# Is this a bug in Total?

The output from the last of these lines doesn't make sense to me

Total[{}, {1}]
Total[{}, {1, 2}]
Total[{{1}, {1, 1}}, {2}]
Total[{}, {2}]


0
0
{1, 2}
0

The 3 first correctly sums at the given levels, but the last sums at level 1 unexpectedly. Is this a bug?

My alternative to get the correct output:

total = Fold[Apply[Plus, #, {#2}] &, #, Range @@ MinMax[#2 - 1]] &
total[{}, {1}]
total[{}, {1, 2}]
total[{{1}, {1, 1}}, {2}]
total[{}, {2}]


The thing is {} doesn't contain anything with Depth 2, so there are no entries to sum, so I would expect the structure to be preserved at the levels below level 2. That's what happen at part 1 when running Total[{{}, {{2}}}, {3}] since part 1 is {} which has depth less than 3, there is nothing to sum (not even an empty set) so it's left with its structure in the output {{}, {2}}.

How can you expect 0 from Total[{}, {2}], but not expect {0, {2}} from Total[{{}, {{2}}}, {3}]?

• So you don't think Total[{}, {5}] is doing the right thing either? Feb 4 at 15:09
• Up to the documentation, "Total[list,{n}] totals elements at level n". Don't hesitate to ask for further explanation in need. Feb 4 at 15:14
• The second (or any) level of an empty List is an empty List, i.e., Level[{}, {2}] == {}. And the Total of an empty List is 0. Consequently, Total[{}, {2}] == 0 Feb 4 at 15:17
• Rephrasing OP's doubt: “Since $\mathtt{Depth@\{\}}$ gives $2$, should operations on level $\geqslant2$ of $\{\}$ be illegal”? Feb 4 at 15:51
• @BobHanlon Added an example in the OP, where you also have Level[{{}}, {3}] == {}, but Total[{{}}, {3}] doesn't contain 0 because it's against the structure of the input. Feb 4 at 16:03

FWIW, for the question what to expect, this seems equivalent for the use-case Total[expr, {k}] the OP asks about:

ClearAll[myTot];
myTot[expr_, 0 | {0}] := expr;
myTot[{}, _] := 0; (* the controversial rule *)
myTot[expr_, {k_Integer}] := With[{
res = Check[
Apply[Plus, expr, {k - 1}], (* main equivalence *)
$$Failed, {Thread::tdlen}]}, res /; res =!=$$Failed
];
myTot[expr_, _Integer | {_Integer, _Integer}] := "Unimplemented";


Examples:

expr = {{1, 4}, {{}, {}}, {10, 20}};
k = 1;
Total[expr, {k}]
myTot[expr, {k}]

(*
{{}, {}}
{{}, {}}
*)

expr = {{1}, {10, 20}};
k = 1;
Total[expr, {k}]
myTot[expr, {k}]
k = 2;
Total[expr, {k}]
myTot[expr, {k}]


Total::tllen : Lists of unequal length in {{1},{10,20}} cannot be added. >>

(*  Total[{{1}, {10, 20}}, {1}]  *)


Thread::tdlen : Objects of unequal length in {1}+{10,20} cannot be combined. >>

(*  myTot[{{1}, {10, 20}}, {1}]  *)

(*
{1, 30}
{1, 30}
*)

expr = {{}};
k = 1;
Total[expr, {k}]
myTot[expr, {k}]
k = 2;
Total[expr, {k}]
myTot[expr, {k}]
k = 5;
Total[expr, {k}]
myTot[expr, {k}]

(*
{}
{}

{0}
{0}

{{}}
{{}}
*)