1 | initial version |
The lambda construct is used to invoke a function, where the name of the function is given, then forgotten / not needed any more. A parallel situation occurs with variables, for instance in the following generation of ten random numbers:
import random
print [ random.choice( [0..1000] ) for extractionCounter in [1..10] ]
(I've got this time [933, 708, 641, 729, 455, 854, 673, 581, 955, 472].) Now, some economical spirit argues, that we do not need the extractionCounter as it is or as a k or an other name of a variable. And eclipse marks the corresponding line with the hint (!) "unused variable". Then we can simply use instead:
import random
print [ random.choice( [0..1000] ) for _ in [1..10] ]
and a mathematician will complain usually for writing a list by using the "white noise letter" _ and consider this line as an ugly trick. But programmers love this.
An other paradigm would be to define a variable, use it in the next line, and never again. For instance:
p = 2
q = p^32
F = GF(q)
Usually, we will need in the sequel p, q . But if we do not need them, it is better to use directly F = GF( 2^32 ) . Both versions are interpreted, but there are coding guidelines, and styles. One proverb in python is "explicit is better than implicit", so F = GF( 2^32 ) is best in this sense.
Now there are similar issues, where we need a function (instead of a variable), but for a short usage. And the function is a minor appearance in our theater with quick interpreters of a clean language. In that case, the underscore is not welcome. We use the lambda construction. Instead of
def myFunction( y ):
if condition(y):
return doSomethingWith( y )
return 0
followed by a single use of the function myFunction, we want direct solution. We need such an example of a singel usage. Note that the single usage may have to "unnatural" in the context. For instance, instead of
winner = myFunction( y )
we could and should maybe have used
winner = doSomethingElse( y ) if condition(y) else 0
and there is no need for a function. So when would we have such a "more complicated", "unnatural" situation?! Such a possible situation is given by a function, that expects an other function as one of its arguments. (Function have names, and are "regular citizens" in python.) In math we have often to deal with... plotting a function. We take it as an exampe. It we have such a customized function, myPlot( fun, interval ), then we may define myFunction as above and call
myPlot( myFunction, interval )
But as a quick line we may want to use:
myPlot( lambda y: doSomethingElse( y ) if condition(y) else 0 , interval )
An other reason to use the lambda construction is in the case of
def myFunction( a, b, y ):
return doThisAndThat( a, b ) - doSomethingElse( y )
where a, b are parameters. And we want to plot w.r.t y. We simply define the above function to have a clear separation of plot and formulas, then use it simply:
myPlot( lambda y: myFunction( a, b, y ), interval ) # a, b must be interpretable at this point
Very often, one uses lambda functions in sort(ing) operations. For instance:
sage: E = EllipticCurve( [-65, 0] )
sage: integral_points = E.integral_points()
sage: integral_points.sort( lambda P,Q: cmp( abs(P[0]), abs(Q[0]) ) )
sage: integral_points
[(0 : 0 : 1), (-1 : 8 : 1), (-4 : 14 : 1), (9 : 12 : 1), (65 : 520 : 1)]
(I want quickly the points, no time to introduce the sorting function.) An other example is as follows: There is a difference between the following two lines...
sage: plot( lambda x: max( abs(x-1), 1, x**2 ), -2, 2 )
sage: plot( max( abs(x-1), 1, x**2 ), -2, 2 )
And now back to the example in the question. This is really an example where we need the name of the function. So i would personally prefer:
def pi(x):
"""Here is a good point to introduce some ten
lines of comments, doc strings are important.
"""
return pari(x) . primepi()
(Even if there is a single or no usage of pi. Unfortunately, there is a name collision, so we should isolate this pi in its own namespace, a class or a function, for instance.)