>>>>> "Gavin" == Gavin Sinclair <gsinclair / soyabean.com.au> writes:

    >> Yes. Python supports lexical closures. The only gotcha is that you
    >> can't 'assign' the names of free variables to point to new objects,
    >> i.e. it has to be the same object, though it can be mutated. So you
    >> can use e.g. length 1 array to contain the other object.

    Gavin> That's an unfortunate limitation.  Just like Java.  Given that
    Gavin> limitation, does it really count as a lexical closure?  (I'm out of my
    Gavin> expert range there.)

Yes, why not? The scoping of objects is the same, and using list
indexing is not that bad a workaround when you need to rebind an
object. Another way would be to do

var = Box(0)

....
def f():
    ...
    var.set(var.get() + 1)
    
If list indexing seems weird to you.

BTW, your database examples could have been written using this
pattern, to the extent rebinding inter-transaction objects is
necessary.



    >> def get_char_counter():
    >> chars = [0]
    >> 
    >> def filepusher(f):
    >> chars[0] += len(open(f).read())
    >> return chars[0]
    >> 
    >> return filepusher
    >> 
    >> acc = get_char_counter()
    >> 
    >> print acc("/bootsect.dos")
    >> print acc("/bootsect.dos")

    >> -------------------
    >> 
    >> Prints out:
    >> 
    >> -------------------
    >> 201
    >> 402
    >> -------------------

    Gavin> I've seen an example like that before.  I don't understand why the
    Gavin> return value changes.  You are asking for a character count of an
    Gavin> unchanging file.

Actually, I created a closure, an accumulator if you wish, that
remembers the count in chars[0]. New invocations just add to that
number, and return the number accumulated so far.


    Gavin> I imagine it's hard to see the value of code blocks as an
    Gavin> "added feature".  We're only human, after all.  They are
    Gavin> only useful if the pervade the language.  That way, when
    Gavin> you're new to the language, you see them being used in very
    Gavin> useful ways.  That familiarises you with the concept, and
    Gavin> then you go: "hang on, does that mean I can do ____ myself?
    Gavin> Wow, what a cool feature!"  That's my experience, anyway.

The dynamic doesn't seem to be such in Python. Iterators, generators
and list comprehensions were adopted quite quickly, and interesting
uses spring around all the time. If a feature is added, it will be
assimilated quickly.

    Gavin> the discussion into a new dimension.  And some design patterns (e.g.
    Gavin> delegate, singleton) are directly implementable in Ruby.  E.g.:

    Gavin> class DataManager
    Gavin> include Singleton
    Gavin> # ...
    Gavin> end

This particular case, Singleton, is trivial, once you have modules
(just use a module global variable).

    Gavin> It's pretty common knowledge in our communities that Python used to
    Gavin> lack certain useful features and this situation was improved after
    Gavin> 2.0 or 2.1 or thereabouts (e.g. inheriting built-in classes,
    Gavin> OO-vs-function-call interfaces).  I'm sure it would be acknowledged
    Gavin> that Ruby was a factor in some of the changes.  Well, I'm also pretty

Well, at least the Ruby bragging rights might have annoyed Python core
developers enough to push the implementation of some of the features
;-).

Ruby still has the advantage of being much less used in production
than Python, so it can be more experimental and break more
stuff. Enjoy it while lasts :). Python 3.0 is going to be the release
that breaks things for us, but it might be many years away...

And lest truth be forgotten, Ruby and Python both absolutely kick ass
compared to the statically typed dinosaurs we have to work on in most
of the "day jobs".

BTW, while I stil have time, I can't help but wonder why so many
Rubyists seem to have turned away from Python because they have to
type __init__ instead of initialize. That's pretty much the only place
you need underscores, apart from 

if __name__ == "__main__":
   main()

idiom. You really don't need to implement __call__, __iter__ and
friends every day. Talk about throwing baby out with the bathwater...

-- 
Ville Vainio   http://tinyurl.com/2prnb