Re: & without #
- To: mathgroup at smc.vnet.net
- Subject: [mg73078] Re: [mg73042] & without #
- From: Sseziwa Mukasa <mukasa at jeol.com>
- Date: Thu, 1 Feb 2007 03:43:27 -0500 (EST)
- References: <200701310440.XAA13604@smc.vnet.net>
On Jan 30, 2007, at 11:40 PM, Kristen W Carlson wrote: > Hi, > >> From Built-in Functions/Cases, here is this (undocumented?) usage >> of & > without #: > > L=Array[Random[Integer,10]&,20] > > {4,5,9,6,8,5,4,0,9,4,5,2,10,6,3,7,4,2,2,8} > > Here is what happens without the &: > > L=Array[Random[Integer,10],20] > > {3[1],3[2],3[3],3[4],3[5],3[6],3[7],3[8],3[9],3[10],3[11],3[12],3 > [13],3[ > 14],3[15],3[16],3[17],3[18],3[19],3[20]} > > Can someone who understands this please explain as completely as you > can, including how & and # work > together, given the behavior of & alone. And is this documented > anywhere? The results are a natural consequence of the behavior of Array and & as described. The behavior of # is not related. First of all Array uses the second argument to form a sequence of arguments for Array's first argument. That's what you see in your second example, the expression first argument[second argument] is formed for Range[second argument to Array]. You can get the same effect with 3/@Range[20] or Random[Integer,10]/@Range[20] if you prefer. Note that Array evaluates all of its arguments, as does Map, so in the first case Random[Integer,10] was evaluated resulting in 3, then the expressions 3[1]...3[20] were formed. Use Trace in the future to see what is evaluated and how expressions are built. Now to the behavior of &, it creates a pure (or anonymous in some terminology) function which holds its arguments unevaluated. Expressions of the form body&[argument] cause the evaluator to bind free variables in body with the values in argument (I can't think of any simple way of saying that) and then evaluate the resulting expression. # can be used to refer to an argument to a pure function by position # is really shorthand for #1 which is the first argument, #2 refers to the second etc. In your particular example the pure function takes no arguments (no # is referred to in its body) so it simply evaluates the expression Random[Integer,10]&[1...20] which results in the evaluation of Random[Integer,10] with the expected results. Because & held its arguments when it was passed to Array the evaluation happens after Array has generated the 20 expressions so you get 20 random numbers. Again, use Trace to see how the expressions get built. The utility of combining Array with a pure function of no arguments is you can control how often the function is evaluated with the second argument to Array even though the function does not depend on Array's second argument. I personally would write Table[Random [Integer,10],{20}] to achieve the same result but that's just a matter of taste. > In general it means a constant function. For example 3& will return 3 > with any argument. But the are at least two "special" functions, > which will work like "variable constants" when used in this way. One > of them is Random[]& (and various variants of it). Another is Unique > [symbol]&, which on every evaluation will produce a unique name based > on "symbol". There's nothing special about the behavior of Random or Unique, what's special is when they get evaluated. You have to use Trace to figure out when your expressions are being evaluated, and for functions whose value depends on the number of times they've been evaluated, like Random or Unique you will get different results depending on whether they are evaluated once, as in your second case, or multiple times. Hope this helped, Ssezi