I may be missing the point of this question, but I think it is important to note that ;
is the short form of CompoundExpression
, and it is not primarily for suppressing output.
You can see how ;
is interpreted using one of the methods I described here:
HoldForm @ FullForm[a; b; c]
HoldForm @ FullForm[a; b;]
CompoundExpression[a, b, c]
CompoundExpression[a, b, Null]
Note that when a final expression is omitted Null
is inserted, just like this behavior with ,
:
{1, 2,}
{1, 2, Null}
The suppression of output is not a behavior of CompoundExpression
but rather Null
, which when returned as output (alone) is not printed. For example 2 Null/2
evaluates to Null
, therefore when given as input no output is printed.
There is little point in sprinkling ;
around your code without need, unless perhaps as a visual reminder that the evaluated form of a given expression is not directly used by the surrounding head. One exception is when writing code that will eventually be made into a function or Module
as line breaks are not valid separators in this case, therefore even functions that already return Null
such as SetDelayed
should be terminated with a ;
, e.g.:
foo[bar_Integer] := bar^2;
foo[bar_Real] := bar/2;
This avoids the error seen with:
Module[{foo},
foo[bar_Integer] := bar^2
foo[bar_Real] := bar/2
]
What ;
is really for
The actual function of CompoundExpression
is described in the documentation:
expr1;expr2; ...
evaluates the expri in turn, giving the last one as the result.
CompoundExpression
, while more succinct and canonical than other methods, is not the only way to accomplish this. For example you could use
Last[{expr1, expr2, ...}]
in the same manner, e.g.:
a = 5; b = a^2; Binomial[b, a]
Last[{a = 5, b = a^2, Binomial[b, a]}]
53130
53130
And suppression of output:
x = Range@500;
Last[{x = Range@500,}] (* no output printed *)
You can also return a specific expression using Slot
in a simple Function
:
#2 &[a = 5, b = a^2, Binomial[b, a]]
25
This is specifically appropriate when you need to perform some action after generating an expression, such as closing a stream:
str = StringToStream["abcdefg 123456"];
# &[Read[str, Word], Close @ str]
"abcdefg"
I would be remiss not to mention that these alternative methods are not actually equivalent to CompoundExpression
because even though they only return one expression (possibly Null
) they still accumulate all of them in memory. Compare these, each pair of lines run in a fresh Kernel:
Range@1*^7; Range@1*^7; Range@1*^7; Range@1*^7;
MaxMemoryUsed[]
94923152
Last[{Range@1*^7, Range@1*^7, Range@1*^7, Range@1*^7,}]
MaxMemoryUsed[]
174925336
To get the memory performance of ;
one would need something more complex, such as:
SetAttributes[ce, HoldAll]
ce[x__] := Fold[#2 &, , Hold @ x]
ce[Range@1*^7, Range@1*^7, Range@1*^7, Range@1*^7,]
MaxMemoryUsed[]
93506816
Additional reading:
Null
come from" and the "surprise multiplications" problems... $\endgroup$If[x < 1, y = 1 z = 3 , y = 4 ]
without a;
betweeny=1
andz=3
. Even if you have thez=3
in a new line in the notebook. One still needs a;
$\endgroup$