lambda closure question

jfj jfj at freemail.gr
Sun Feb 20 22:58:11 EST 2005


Carl Banks wrote:
> 
> Say you want to calculate a list of points of an iterated fractal.
> Here's the idea: you have a set of linear transformations.  You take
> the origin (0,0) as the first point, and then apply each transformation
> in turn to get a new point.  You recursively apply each transformation
> at each additional point, up to a certain depth.

I like these kind of things. Ahhh, the best use out of one's computer.

> 
> What's the best way to write such a function?  Using a nested function,
> it's easy as pie.  (Details may be a little wrong....)
> 
> . def ifs(transformations, maxdepth):
> .     def add_point(x,y,angle,depth):
> .         ifspoints.append((x,y,angle))
> .         if depth < maxdepth:
> .             for t in transformations:
> .                 nx = x + t.x*cos(angle) - t.y*sin(angle)
> .                 ny = y + t.x*sin(angle) * t.y*cos(angle)
> .                 nangle = angle + t.angle
> .                 add_point(nx,ny,nangle,depth+1)
> .     ifspoints = []
> .     add_point(0.0, 0.0, 0.0, 0)
> .     return ifspoints
> 
> If you didn't have the nested function, you'd have to pass not only
> depth, but also maxdepth, transformations, and ifspoints around.
> 

I see. Some people complained that you have to use "self." all the
time in methods:)  If that was lifted the above would be done with
a class then?


The costly extra feature is this:
###############
  def foo():
     def f():
        print x
     x=1
     f()
     x=2
     f()
     return f
foo()()
#############
which prints '1 2 2'

The fractal code runs a little _slower_ because of this ability.
Although the specific program does not take advantage of it!

> If you had something a little more complex than this, with more than
> one nested function and more complex pieces of data you'd need to pass
> around, the savings you get from not having to pass a data structure
> around and referncing all that data though the structure can be quite a
> lot.

Generally, I believe OOP is a superset of nested functions (as a
feature).  Nested functions make sense to me as primary python
def statements which ``create new code objects with arbitary constants''

When I see :
###########
def foo(x):
      def bar():
          print x
      return bar
###############
and the call:
  xx = foo(1)

I imagine that python runs:
  def bar():
     print 1
  xx=bar

But alas, it doesn't:(
Nooooooooo. It carries around a silly cell object for the
rest of its lifetime.  see xx.func_closure.
At least, I think this is what happens...


jfj



More information about the Python-list mailing list