Group Abstract Group Abstract

Message Boards Message Boards

0
|
10.8K Views
|
11 Replies
|
12 Total Likes
View groups...
Share
Share this post:

[?] Different ways to define a function?

Posted 7 years ago
POSTED BY: Edward Davis
11 Replies
POSTED BY: EDITORIAL BOARD

So this post is for you then: see subchapter "5.2.3 Attributes of Pure Functions" of Maeder's book PIM 3e. Whenever I believe that I understood something, maybe a concept explained in the WLDC/tutorial or so, and feel a bit more confident about the topic, and i then look at any subchapter of that book, I am back at the humblest of myself. Love the book tho, has great side note explanations commenting his code!!

POSTED BY: Raspi Rascal
Anonymous User
Anonymous User
Posted 7 years ago

I will read it. Thanks.

POSTED BY: Anonymous User

One can set attributes on pure functions no problem. Never mind since the op seems gone.

POSTED BY: Raspi Rascal
Anonymous User
Anonymous User
Posted 7 years ago

I appreciate the info.

POSTED BY: Anonymous User
Anonymous User
Anonymous User
Posted 7 years ago

think of this

#1*#2&

as just an abbreviation for this:

Function[{x,y},x*y]

Like all abbreviations it looks odd at first, but once you get used to it, you may appreciate its conciseness.

Pure functions are Wolfram's implementation of Church's concept of lambda function:

https://en.wikipedia.org/wiki/Lambda_calculus

Between Church and Wolfram, McCarthy included lambda functions in LISP.

I don't know if it is possible to set attributes on Mathematica's pure functions or do pattern matching on their arguments, as you can with Mathematica's regular functions.

POSTED BY: Anonymous User

The important point that one learns while studying this ubiquitous construct is that there are instances where a pure function must be used and that there are even instances where only one form of the pure function, typically the Function[ ] form, can be used. Those instances are rare .. but not as rare as a beginner would not encounter them. When i saw such examples, that was a very enlightening experience! I learned that, in most cases, one can use f[x], Function[ ], or #& with the same effect (result), and you can let your mood decide. But then there are those rare or few cases where no room for choice or decision is left.

i have no examples at hand. i am just saying. and sooner or later the student will encounter such cases too. watch out for them good luck!

POSTED BY: Raspi Rascal

It's often convenient to use a pure function when you start with a function f of two arguments and want to fix one of the arguments so as to evaluate f for several values of the other argument, and then you would combine the pure function with a Map (or, often, the /@ special input form for Map).

For example:

 cubeRootsUnity = Exp[(2 Range[3] \[Pi] I)/3];
 Graphics[{
   Red, PointSize[Large],
   Point /@ ReIm[cubeRootsUnity],
   Blue, Thick, Arrowheads[Medium],
   Arrow[{{0, 0}, #}] & /@ ReIm[cubeRootsUnity]
   }, Axes -> True, PlotRange -> 1.25]

Plot of cube roots of unity

To be utterly precise here, the expressionf[arg1, arg2] is Arrow[{arg1,arg2}], and the fixed first argument is {0, 0}.

It would be tedious (especially if you considered, say, 8th roots of unity instead of cube roots), to repeat the Arrow expression for each individual root.

(Note that Arrow[{{0, 0},#}]& is not Listable.)

POSTED BY: Murray Eisenberg

In the simplest situations the two paradigms are interchangeable. The & way (cryptic slang for Function) may be a little faster for purely numerical functions, because it skips the pattern matching, but I don't really know. The p[x_]= way is much more customisable with all the pattern-matching capabilities. With the & way you don't need to give the function a name, you simply insert the function code into your expressions.

A general-purpose beginner shouldn't be bothered with the &, I think.

POSTED BY: Gianluca Gorni

The major use (that I see at least) for anonymous functions using the & notation is to introduce functions within expressions instead of declaring them on their own. For example, maybe you have a list of numbers and want to turn it into a list where each number is replaced with the result of some predicate (like >4). You could do this by using an anonymous functions like this:

In[1]:= # > 4 & /@ {1, 2, 3, 4, 5, 6}

Out[1]= {False, False, False, False, True, True}

This idiom is common for things like mapping a function over a list, or defining a predicate used by other functions like Select:

In[2]:= Select[{1, 2, 3, 4, 5, 6}, # > 4 &]

Out[2]= {5, 6}

In both of these cases the function being defined just has one parameter, and is equivalent to this function using the other notation that you mentioned:

In[3]:= f[x_] := x > 4

In[4]:= Select[{1, 2, 3, 4, 5, 6}, f]

Out[4]= {5, 6}

The advantage of defining a named function like that is that you can use it over and over without restating the body of the function. Anonymous functions are useful when the function serves some transient purpose where you don't want to declare it as a named thing.

This idiom is common in functional languages: the concept of introducing anonymous (or pure) functions is used all over the place in languages that support what are usually called lambdas. If you look around at, say, OCaml or Haskell or F#, you'll see the term lambda used in a very similar manner as pure functions in Mathematica.

I don't believe it's correct to think of the & symbol as "anding" the body of the function with its arguments. The symbol is there more or less to tell the system where the declaration of the function ends. For example, I can say this:

In[1]:= (#^2 & /@ #) &[{1, 2, 3, 4}]

Out[1]= {1, 4, 9, 16}

In that case there are two anonymous functions being defined in different places: the innermost one defines the function being mapped over some list that squares the elements. That is then wrapped up inside another function where the argument is the list to map over. So, the position of the & really is more of a delimiter indicating where the functions are defined. It's a little easier to see this when you look at things in TreeForm:

(#^2 & /@ #) & // TreeForm

Tree Form

I doubt there is a performance difference, but that would require some more knowledge of the internals of how the interpreter handles functions.

POSTED BY: Matthew Sottile
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard