Will Stuyvesant wrote:
. def delay(exp): return lambda: exp

If you look at the definition of "delay" in SICP, you'll notice that it's defined as "syntax sugar", in other words, a macro. Since Python does not have macros, you'll have to just use "lambda", because by defining "delay" as a function, you're forcing the expression "exp" to evaluate immediately. In other words, theres a crucial difference between::


  delay(sys.stdout.write('evaluated\n'))

and::

  lambda: sys.stdout.write('evaluated\n')

If you type in those two snippets, you'll see what I mean.

Coincidentally, I attempted a similar experiment just a couple of days ago, and here's what I came up with::

   # Stream.py - Stream class inspired by SICP

    class Stream(object):
        pass

    class EndOfStream(Exception):
        pass

    class Item(Stream):
        def __init__(self, current, nextf):
            self.current = current
            self.nextf = nextf

        next = property(lambda self: self.nextf())

        def fold(self, f, init):
            return f(self.current, self.next.fold(f, init))

        def __getitem__(self, n):
            if n == 0:
                return self.current
            else:
                return self.next[n - 1]

        def __str__(self):
            return '<Stream.Item: %s, ...>' % self.current
        __repr__ = __str__

    class End(Stream):
        def fold(self, f, init):
            return init

        def __getitem__(self, n):
            raise EndOfStream()

        def _fail(self):
            raise EndOfStream()

        current = property(_fail)
        next = property(_fail)

        def __str__(self):
            return '<Stream.End>'
        __repr__ = __str__

Here's how it works::

    Python 2.4 (#1, Dec  4 2004, 20:10:33)
    [GCC 3.3.3 (cygwin special)] on cygwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import Stream
    >>> s = Stream.Item(1, lambda: Stream.Item(2, lambda: Stream.End()))
    >>> s
    <Stream.Item: 1, ...>
    >>> s.current
    1
    >>> s.next
    <Stream.Item: 2, ...>
    >>> s.next.current
    2
    >>> s.next.next
    <Stream.End>
    >>> s.next.next.next
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "Stream.py", line 37, in _fail
        raise EndOfStream()
    Stream.EndOfStream
    >>> def evens(n=0):
    ...     return Stream.Item(n, lambda: evens(n + 2))
    ...
    >>> s = evens()
    >>> s.current
    0
    >>> s.next.current
    2
    >>> s.next.next.current
    4

I don't know if this is useful or not, but it was an interesting exercise nonetheless.

Dave
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to