python hack of the day -- "listable" functions

Stefan Franke spamfranke at bigfoot.de
Sun May 16 17:38:42 EDT 1999


On Fri, 14 May 1999 20:08:41 GMT, wtanksle at dolphin.openprojects.net (William
Tanksley) wrote:

>On Thu, 13 May 1999 22:50:34 GMT, Stefan Franke wrote:
>>I think function application with $ does follow the rewrite rule
>
>>    f(x, y, $[z1, z2, ..., zn], a) ->
>>   $[f(x, y, z1, a), f(x, y, z2, a), ..., f(x, y, zn, a)]
>
>Okay, then let x and y be lists.  What is the result of
>
>f($x,$y)?  Is it something like x cross y, or does it have as many
>elements as the shortest of x or y (or the longest)?

The rewrite rule - which BTW should have been

    f(x, y, $[z1, z2, ..., zn], a, ...) ->
   $[f(x, y, z1, a, ...), f(x, y, z2, a, ...), ..., f(x, y, zn, a, ...)]

does not imply the semantics I inteded. We need to define an order of evaluation
not only because of side effects, but because  type and value of the result
depend of in case of multiple $ed arguments.

That's why I tried to illutrate it with that hypothetical redefined 'apply',
which basically says:

"Before every function call to f search the arguments from left to right. 

If there's no argument of a dollar type call the function.

If you find a dollar argument, X [ =$[x1, x2, ...,] or (x1, x2, ...) ] the
result of the call is a dollared(!) sequence of the same type than the arg.

The elements of the resulting sequence are the result of applying f from left to
right  to a number of arguments tuples that can be obtained by replacing X by
each element x1, x2, ... in the original parameter list [works even for keyword
arguments]. Any application of f is a recursive call to the new application
machinery."

The result of f($x, $y) then is (with x=[x1, x2, ..., xn] and y= [y1, y2, ...,
ym]):

f($[x1, x2, ..., xn], $y) ->

$[f(x1, $y), f(x2, $y), ..., f(xn, $y), ] ->

$[$[f(x1, y1), f(x1, y2), ..., f(x1, ym)], 
  $[f(x2, y1), f(x2, y2), ..., f(x2, ym)], 
...,
  $[f(xn, y1), f(xn, y2), ..., f(xn, ym)] ]

Note that the nesting is a direct implication of the evaluation ordner.

>It wouldn't be "apply", really.  But carry on...
No, just an illustration.

>
>Now, consider this.
>
>x = o.verb(a,b,c)
>
>You've created a language feature where the action of the verb depends not
>on the single object it's attached to, but on EACH of the parts of speech
>in its parameter list.
>
>After that change, Python wouldn't be object oriented.  It'd be grammar
>oriented.
Not really. Even if Python had static typing, no extension to the method
dispatch/overloading machinery would be necessary. 
The expansion of dollared arguments is done before any function call. Usually,
no function gets a parameter of a dollared type. This could be only the case if
you have a dollared sequence inside a dollared argument. (Dunno if it's clever
to allow this. The operations on the $ type are yet to be defined.)

Especially because this works for methods as well, and due to the dynamic typing
of Python, there lies a lot of expressive power inside that construct. When
writing OO programs, I often find myself writing expressions like

    map (lambda x, arg=arg: x.method(arg), seq)

In our style this could be written as

  $seq.method(arg)

Especially the scope transition of arg is not longer necessary, which even seems
more Pythonic to me than map/lambda. BTW, are there similar constructs for
filter and fold(reduce)-like operations in APL/J/K?

>They're worth it.  May I suggest J?  APL is very nice, but hard to learn
>because you have to learn a new way of typing (if you wind up using it
>regularly the expressiveness makes it all worthwhile, I'm told).  J is
>similar, but entirely ASCII.  K is different, and although it's a
>facinating approach it's a bit more of a hybrid with conventional
>languages, so it's easy to be sloppy and work the way you've always worked 
>(a bad thing when you're learning a new language because it's different).
>
Thanks for your suggestions.

>J also adds some concepts officially which APL only implies, such as a
>formal concept of parts of speech (noun, verb, adverb, adjective, gerund,
>and so on) or a formal definition for certain formerly meaningless
>combinations of functions (called "forks" and "hooks").
Interesting. Could you give me some pointers (preferably WWW)?

Stefan





More information about the Python-list mailing list