It's often convenient to imagine a process as a tree-shaped (or graph-shaped) assembly line. Inputs flow in through the leaves and are transformed, filtered or reduced where branches join. This well represents lazy-functional programming. Say one wants the words from a line-delimited file, excluding acronyms, then converted to lower case and stored in a set for quick lookup. Compare syntaxes...
words = set()
for line in file('words'):
line = line.strip()
if line and not line.isupper():
words.add(line.lower())
Variables describe edges in a graph, connecting parts of code, but without being obvious to the eye. Names are boring to create and are often misspelled.
set(imap(str.lower, ifilterfalse(lambda w: w.isupper(), ifilter(None, imap(str.strip, file('words'))))))
set(line.strip().lower() for line in file('words') if line.strip() and not line.isupper())
This wastes time on a second strip() call.
set(line.lower() for line in ifilter(None, imap(str.strip, file('words'))) if not line.isupper())
This eliminates the second strip() call but has a confusing mix of syntaxes. The data flow repeatedly changes direction.
Prefix syntax - that of Lisp, Python, C, etc. - is backwards: the functions called later must precede those called earlier. One has to say what comes last first, like saying: "Eat a sandwich; make a sandwich; buy groceries." The words are spelled left to right but the sentence is right to left.
Consider this Python syntax hack to write lazy-functional code like an assembly line.
file('words') | pmethod('strip') | pfilter | pnfilter(methodcaller('isupper')) | pmethod('lower') | pset
This isn't shorter, but allows sequences of operations to be written naturally from left to right, without nested and distant parenthesis.
pmethod() eases mapping using a method of the objects to be mapped, making this version more general because it works if the strings are a mix of str and unicode instances. methodcaller() similarly eases filtering.
Presumably, this would be better in Lisp, using its read macros, but this abuse of __ror__ hasn't caused problems yet.
Related: ASPN Cookbook Python recipe, Dataflow programming.
Does anyone know of a practical language that takes this idea seriously?
©2004-2008 Patrick Roberts | Burlington, Ontario, Canada