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!
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!
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".
– orome
Apr 02 '15 at 20:35
Unevaluated[] to Unevaluated@Sequence[] though I can see why the latter might be considered clearer.
– Simon Woods
Apr 02 '15 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.
– Nasser
Apr 02 '15 at 21:48
If[# == 1, ## &[], #] & /@ {1, 2, 3}; — I mean, obviously!
– orome
Apr 02 '15 at 21:52
If[# == 1, Sequence @@ {}, #] & /@ {1, 2, 3} which gives {2, 3} also. but from now on, I will use ##&[] to be more cool.
– Nasser
Apr 03 '15 at 01:24
Unevaluated@Sequence[], but I hesitate to say that it's equivalent. There may be counterexamples.
– Simon Woods
Apr 03 '15 at 15:43
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[]?
– orome
Apr 03 '15 at 01:18
Unevaluated,SequenceandEvaluateare a bit special and are not handled in the usual way during the evaluation procedure. – Szabolcs Apr 03 '15 at 01:43##&[]. It is concise (and I think clear enough after one understands it), butFunctioninvocation 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. – Oleksandr R. Apr 03 '15 at 14:37Unevaluated[]in this answer. Performance was briefly discussed with Leonid in the original dialog (on Stack Exchange) about this. To address your concern I shall add benchmarking to my answer. – Mr.Wizard Apr 08 '15 at 16:50## &[]tests as slightly faster thanUnevaluated[]in both 7.0 and 10.0. Please see the update to answer 3705. – Mr.Wizard Apr 08 '15 at 17:34Unevaluated[]would perform exactly the same asUnevaluated@Sequence[]! The vanishing function is also not as slow as I had anticipated; its 10-20% penalty overUnevaluated@Sequence[]is quite tolerable for most applications. – Oleksandr R. Apr 08 '15 at 18:39