list of polynomial functions

Tim Chase python.list at tim.thechases.com
Thu Jun 15 19:04:04 EDT 2006

```> Just to be a bit more explicit:
> In code like:
>      def make_polys(n):
>          """Make a list of polynomial functions up to order n."""
>          p = lambda x: 1
>          polys = [p]
>          for i in range(n):
>              polys.append(lambda x: polys[i](x)*x)
>          i=3
>
> The lambda-defined functions will be called after the for loop is done,

::boggle::

My understanding is that the lambda-defined functions are not
called until the actual application thereof, with the

mypolys = make_polys(8)
mypolys[5](2) #the lambda call happens here, no?

</F>'s original statement read like a koan...there was more in it
than I was getting out of it.  There seem to be several concepts
I've not yet wrapped my head around.  My understanding (likely
wrong) was that "lambda" was sort of like defining a function
inline, along the lines of

def f(x):
return x+5

being somewhat equiv to

k = lambda x: x+5

you could then do

>>> f(20)
25
>>> j = f
>>> j(20)
25
>>> k(20)
25
>>> j = k
>>> j(20)
25

There does seem to be some subtle difference, as

>>> f
<function f at 0xb7d87e9c>
>>> k
<function <lambda> at 0xb7d8c0d4>

"k" clearly knows it's a <lambda> just as "f" knows its an "f"
(whether asked for by the aliased name or not).

So at some point, the Python interpreter is compiling this
function/lambda, and expanding matters with or without some sort
of scope.  The OP's example seems to pull both "polys" and "i"
from the local scope.  However, Python must only be tokenizing
and making references to future-ly available stuff, as, without
"spam", "blah", "tapioca", or "spatula" defined in my
environment, I can do arbitrary things like

q = lambda x: spam[spatula](x) + blah / tapioca

and Python swallows the whole lot as syntactically kosher, even
though none of these items exist.  It seems to only evaluate them
at the point that "q" is called.

[lightbulb begins to go on...sorta]

However, in the OP's example, slightly modified, it seems that
polys, even when it doesn't exist in the calling scope, it
doesn't matter.

>>> def mp(n):
...     p = lambda x: 1
...     polys = [p]
...     for i in range(n):
...             polys.append(lambda x: polys[i](x)*x)
...     return polys
...
>>> f = mp(5)
>>> polys
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'polys' is not defined
>>> for p in f: print p(3)
...
1
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 5, in <lambda>
:
:
:

I'm curious why the very first attempt to call p(3) doesn't bomb
out with the NameError that "polys" wasn't defined before it even
got to the point of attempting to call it.

> Hope this makes it a bit clearer.

like chocolate. :-/

Thanks for trying though...

-tkc (who is certainly *not* a LISP programmer, as evidenced here...)

```