[PEAK] Another way to spell generic function predicates
Phillip J. Eby
pje at telecommunity.com
Sat Jan 1 23:21:11 EST 2005
While working on some refactoring to support an expanded API, it occurred
to me that we could do something like:
"""Test whether container is empty"""
and then use it in generic function tests, i.e.:
@someGeneric.when("isEmpty(foo) and not isEmpty(bar)")
The idea here is that the 'predicate' decorator replaces the decorated
function's body with the supplied expression, but also marks the function
as being a predicate function, along with how to compute the
predicate. Thus, the 'someGeneric.when()' would automatically be inlined
to the equivalent of:
@someGeneric.when("len(foo)==0 and not len(bar)==0")
I think this is a better idea than the simple "macro" I was suggesting the
other day, as it makes the parameterization explicit, allows multiple
arguments, and doesn't introduce new namespaces to keep track of; it works
just like calling a function would, only faster because the conditions get
"inlined" -- and are therefore indexed and computed at most once per
The second piece is the ordered classifier thing. I'm thinking that could
be done by simply combining @predicate decorators with a Classifier
@predicate("isEmpty(rolls) or frame>10")
"""Nothing left to score"""
"""Frame was a strike"""
"""Frame was a spare"""
"""Frame was open"""
The idea here is that the predicates are arranged in priority order, and a
given predicate is translated as the negation of the previous predicates,
and-ed with the specified predicate. So, for example, even though 'strike'
above is 'rolls==10', the *actual* strike predicate is 'not
(isEmpty(rolls) or frame>10) and rolls==10'. And so on through the
items, so that the default case occurs only if no other predicate
matched. For the scoring example, one could use the above classifer in
"""Return score for bowling game, given list of a player's rolls"""
return sum(rolls[:3]) + score(rolls[1:],frame+1)
return sum(rolls[:3]) + score(rolls[2:],frame+1)
return sum(rolls[:2]) + score(rolls[2:],frame+1)
That is, predicate functions in a Classifier subclass are treated as static
methods, and they could be inlined and optimized just like ordinary
What do you think? This seems to me like a more straighforward way to
spell "macros" and ordered classifications without introducing weird new
rules and keyword arguments and namespaces.
More information about the PEAK