A critic of Guido's blog on Python's lambda

Lasse Rasinen lrasinen at iki.fi
Sun May 14 14:30:52 EDT 2006


Ken Tilton <kentilton at gmail.com> writes:

> ps. flaming aside, PyCells really would be amazingly good for Python. And
> so Google. (Now your job is on the line. <g>) k

Here's something I wrote this week, mostly as a mental exercise ;-)
The whole code is available at <http://www.iki.fi/~lrasinen/cells.py>,
I'll include a test example below. Feel free to flame away ;-)

(As for background: I like CL better as a language, but I also like Python
a lot. However, I was employed for 3 years as a developer and maintainer
in a Python data mining application, so I'm more fluent in Python than CL.)

The code is mostly based on Kenny's descriptions of Cells in the following
messages:
<0mp7g.600$4q2.70 at fe12.lga>
<NUP7g.17$G22.12 at fe11.lga>
<xcn8g.11$FO5.5 at fe08.lga>

In addition, I have looked at the CL source code briefly, but I'm not sure
if any concepts have survived to the Python version. Since Python's object
model is sufficiently different, the system is based on rules being
defined per-class (however, if you define a rule by hand in the __init__
function, it'll work also. I think; haven't tested).

I can possibly be persuaded to fix bugs in the code and/or to implement
new features ;-)

Features:
- Tracks changes to input cells dynamically (normal attributes are not tracked)
- Callbacks for changes (see caveats)
- Requires Python 2.4 for the decorator syntax (@stuff)
- Should calculate a cell only once per change (haven't tested ;-)

Caveats:
- The input cell callbacks are not called with the class instance 
  as the first argument, while the rule cell callback are. This
  is mostly due to laziness.
- There is no cycle detection. If you write cyclic dependencies, you lose.
- There is very little error checking.

Example follows:

    def x_callback(oldval, newval):
        print "x changed: %s => %s" % (oldval, newval)
    
    class Test(cellular):
       def __init__(self):
           self.x = InputCell(10, callback=x_callback)
    
       def y_callback(self, oldval, newval):
           print "y changed: %s => %s" %(oldval, newval)
    
       def a_callback(self, oldval, newval):
           print "a changed: %s => %s" %(oldval, newval)
    
       def g_callback(self, oldval, newval):
           print "g changed: %s => %s" %(oldval, newval)
           
       @rule(callback=y_callback)
       def y(self):
           return self.x ** 2
    
       @rule(callback=a_callback)
       def a(self):
           return self.y + self.x
    
       @rule(callback=g_callback)
       def g(self):
           if self.x % 2 == 0:
               return self.y
           else:
               return self.a


$ python cells.py

y changed: __main__.unbound => 100
a changed: __main__.unbound => 110
g changed: __main__.unbound => 100
=============
x changed: 10 => 4
y changed: 100 => 16
a changed: 110 => 20
g changed: 100 => 16
=============
x changed: 4 => 5
y changed: 16 => 25
a changed: 20 => 30
g changed: 16 => 30
-- 
Lasse Rasinen
lrasinen at iki.fi



More information about the Python-list mailing list