Confessions of a Python fanboy

Masklinn masklinn at masklinn.net
Fri Jul 31 04:08:33 EDT 2009


On 30 Jul 2009, at 23:57 , Luis Zarrabeitia wrote:
> I'd like to ask, what "container.each" is, exactly? It looks like a  
> function
> call (as I've learned a few posts ago), but, what are its arguments?  
> How the
> looping "works"? Does it receive a "code" object that it has to  
> execute?
> Is .each some kind of magic keyword? (This has little to do with  
> python or
> the current thread, so feel free to reply off-list if you want to...)

#each is simply a method that takes a function (called blocks in  
ruby). One could call it a higher-order method I guess.

It's an implementation of the concept of internal iteration: instead  
of collections yielding iterator objects, and programmers using those  
through specially-built iteration constructs (e.g. `for…in`),  
collections control iteration over themselves (the iteration is  
performed "inside" the collection, thus the "internal" part) and the  
programmer provides the operations to perform at each iterative step  
through (usually) a function.

In Python (assuming we had anonymous defs and an each method on  
lists), the following loop:

     for item in some_list:
         do_something(item)
         do_something_else(item)

     some_list.each((def (item):
         do_something(item)
         do_something_else(item)
     ))

There's absolutely nothing magic there, it's simply using anonymous  
functions and method calls (SmallTalk initiated this approach in the  
70s, and actually went much, much further than Ruby as it did away not  
only with `for…in` but also with `if…else` and `while` and a bunch of  
other stuff).

Now as IV pointed out, #each isn't the most interesting usage of  
blocks/anonymous functions (though I do like it, because it gets rid  
of no less than two keywords… even if Ruby reintroduced them as  
syntactic sugar), higher-order functions (functions which act on other  
functions) are (among other things) ways to create new control  
structures without having to extend the core language (so are lisp- 
style macros, by the way).

Of course Python does have higher-order functions (functions are first- 
class objects, so it's possible and frequent to have functions act on  
other functions), but since Python doesn't have anonymous functions  
that usage tends to be a bit too verbose beyond simple cases (also, of  
course, this kind of usages is neither in the "genes" nor in the  
stdlib).

In closing, IV has an example of how blocks make `with` unnecessary in  
Ruby (the functionality can be implemented at the library level rather  
than the language one). Generally, anonymous functions in OO languages  
are a way to inject behavior into third-party methods/objects. Kind-of  
a first-class Visitor support.

-m

PS: there's actually a bit of syntactic magic in Ruby's blocks, and  
it's one of the things I hate in the language, but it's not relevant  
to the role of blocks, and unnecessary to it: SmallTalk has no magical  
syntax).


More information about the Python-list mailing list