All the cool kids are apparently using
##&[]
for
Unevaluated @ Sequence[]
but I have no idea what either means.
Please explain what these things are so I can be a cool kid!
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityAll the cool kids are apparently using
##&[]
for
Unevaluated @ Sequence[]
but I have no idea what either means.
Please explain what these things are so I can be a cool kid!
Try this:
Map[If[#==1,Unevaluated@Sequence[],#]&,{1,2,3}]
Note the output. The 1
is gone. That's because Unevaluated@Sequence[]
puts the empty sequence there, that is, "nothing".
##&[]
is a shorthand that can be used in most places for same - ##
is the sequence of arguments, &
makes it a function to apply to something, []
is that something - an empty argument list, so the result is... a sequence that is empty.
If
or Which
when I wanted "nothing".
$\endgroup$
Unevaluated[]
to Unevaluated@Sequence[]
though I can see why the latter might be considered clearer.
$\endgroup$
Apr 2, 2015 at 21:19
Map[If[# == 1, Unevaluated@Sequence[], #] &, {1, 2, 3}]; If[# == 1, Unevaluated@Sequence[], #] & /@ {1, 2, 3}; If[# == 1, ## &[], #] & /@ {1, 2, 3};
so use the last one above. It is not only shorter than all the others, but also makes you look much smarter as well.
$\endgroup$
If[# == 1, ## &[], #] & /@ {1, 2, 3};
— I mean, obviously!
$\endgroup$
If[# == 1, Sequence @@ {}, #] & /@ {1, 2, 3}
which gives {2, 3}
also. but from now on, I will use ##&[]
to be more cool.
$\endgroup$
I believe it is important to get a fundamental understanding of what Pure Functions are that goes beyond the understanding using of a syntax. Hereafter an non-exhaustif summary of a few key understandings:
1) Pure Functions have they roots in Lambda calculus that forms the basis of functional programming paradigm implemented in Mathematica.
2) In Mathematica a Pure Function is simply an expression with the head Function that is applied to arguments.
3) Syntactially # represent a slot for arguments, whereas ## represent a sequence of arguments
4) Syntactially & represents an operator for declaring an expression as a Pure Function
5) Pure Functions have no names and therefore do not create any global defintion in Mathematica (in Lambda calculus also called anonymos functions)
6) Pure Function can be used within other expressions.
Example to point 2)
Head[# &]
(* Function *)
Applying a Pure Function to an argument
Sqrt @ # &[4]
(*2*)
this is equivalent to writing
Function[x,Sqrt @ x][4]
(*2*)
Example to point 3) difference between supplying the first argument or a sequence of arguments
Plus@# &[1, 2, 3]
(*1*)
Plus@## &[1, 2, 3]
(*6*)
PS:easy or not? even penguins would understand this..hi,hi
Unevaluted simply holds evaluation of an expression within an argument. Rasher's example demonstrates this well.
Regarding your comment, the difference between ##&[] and Unevaluated @ Sequence[] in the example from Rasher is that
a) ##&[] is short notation for Function[SlotSequence[1]][], which is evaluated to Sequence[], which then is spliced into the result {2,3}.
whereas
b) the kernel evaluates Unevaluated @ Sequence[] to Sequence[] after the function If[] has been evaluated, which is then spliced into the final result {2,3}.
Therefore due to the sequence of the evaluation process ##&[] is Unevaluated@Sequene[] and not Sequence[].
Using Trace and FullForm are powerful "tools" if you would like to go "playing in the league of cool kids". They reveal how short notation is re-written and give insight into the evaluation process.
I would recommend to compare output of following in order to get better insight:
Trace[If[# == 1, ## &[], #] & /@ {1, 2, 3}] // FullForm
Trace[If[# == 1, Unevaluated @ Sequence[], #] & /@ {1, 2,3}] // FullForm
Unevaluated
: ## &[1, 2 + 2, 3]
is Sequence[1, 4, 3]
, so 2+2
got evaluated, right? If so, how is ## &[]
Unevaluated@Sequence[]
and not Sequence[]
?
$\endgroup$
##&[]
. It is concise (and I think clear enough after one understands it), butFunction
invocation is not the fastest operation in Mathematica. In most cases (except where the subtle differences actually matter), I would preferUnevaluated@Sequence[]
for explicitness and avoiding an unnecessary function call. Simon Woods's suggestion ofUnevaluated[]
could be the best compromise. $\endgroup$