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