Ted Leung on the air: Open Source, Java, Python, and ...
I agree with something that Dave Winer has said in the past, which is that some of the best blogs are the ones where you can watch people flesh their ideas out and learn along with them.
PJE is continuing his explorations with predicate dispatching, and you can follow the evolution of his thoughts:
On Wednesday:
Generic functions aren't always a substitute for adaptation and interfaces, however. Technically, a generic function can do anything that you can do by adapting to an interface and calling a method, but sometimes interface+adaptation is a better "metaphor" for what's going on, or a more convenient or expressive way to do things, especially for documentation. (For example, the interface I left behind in the new implementation was purely for documentation purposes.)
By Friday:
I'm beginning to think that predicate-dispatch generic functions capture something really fundamental about computation, or that at least they're much more fundamental than interfaces or adaptation. As useful as interfaces and adaptation are, they're actually pretty cumbersome compared to generic functions.
Now, this second insight is exactly the point of the predicate dispatch work, that it unifies single dispatch, multiple dispatch, ML style pattern matching, predicate classes and more. It's also important because there is a way to implement this efficiently.
I think that there's also something else going on, which is a rewiring of what it means for a thing to be an object. Much has been made of the virtues of encapsulation in object-oriented programming, and a typical reaction to Lisp style generic functions (or Python's single dispatching object system) is that there isn't any encapsulation, and that having everything work as functions is not really object-oriented. But maybe it's the case that being "object oriented" is not the primary goal. If reduction of unnecessary code and the ability to extend the system are what's most important, then generic functions (even without predicate dispatching) are a very powerful tool. Interfaces and adaptation (which becomes necessary by virtue of the existence of interfaces) are concepts from a very object-centric view of the world. If you remove that view, then the landscape looks very different.
I've been toying with developing a language called Inertia that unifies predicate dispatching into blocks. For example, with predicates there is no need for a special syntax for list comprehension:
1..10 map: n [n % 2 == 0] -> n * n
read: from 1 to 10 map n where n is-even, to n squared. A block is defined as:
arg [predicate] -> body
so you can use them for pattern matching:
stream each: char
[char is-digit] -> read-number
[char is-alpha] -> read-ident
I find list comprehension in other languages ugly because it introduces a whole new syntax. I know they borrow from lambda calculus, but still.
Python:
[n * n for n in range(1,11) if n % 2 == 0]
Haskell:
[n * n | n <- [1..10], n mod 2 == 0]
Just thought I'd share my thoughts,
Mike
Posted by Mike Austin at Mon Aug 8 17:55:57 2005
To insert a URI, just type it -- no need to write an anchor tag.
Allowable html tags are:
<a href>
, <em>
, <i>
, <b>
, <blockquote>
, <br/>
, <p>
, <code>
, <pre>
, <cite>
, <sub>
and <sup>
.You can also use some Wiki style:
URI => [uri title]
<em> => _emphasized text_
<b> => *bold text*
Ordered list => consecutive lines starting spaces and an asterisk