io
about
blog
community
docs
downloads

    2006 11 17         List each

    I think it was Quag that originally requested and implemented an "each" method on list, which looks like:

    list(1, 2, 3) each foo bar
    
    and does the same as:
    list(1, 2, 3) foreach(foo bar) // evals expression foo bar on each element
    
    which is handy for CLI use as it avoids having to type the parens.

    Here are some recent implementations that also serve as good Io metaprogramming examples. The first one evals the rest of the expression on each element and returns an object that answers nil to all messages:
    BlackHole := Object clone do(forward := nil; removeAllProtos)
    
    List each := method(
    	self foreach(doMessage(call message attached, call sender))
    	BlackHole
    )
    
    That works, but is a bit inneficient, particularly if the expression is large. The seconds acts like a lazy macro - it transforms the each message in the AST to a foreach the first time its called:
    List each := method(
    	m := call message
    	m setName("foreach") setArguments(list(m attached)) setAttached(nil)
    	self doMessage(m)
    )
    
    This implementation has no overhead after its first call.