|There's more than one way to do things|
Using functional abstraction in Perlby spurperl (Priest)
|on Jul 01, 2005 at 11:09 UTC||Need Help??|
Today, I want to talk about "functional abstraction" - a way to program that I'm most fond of, and that comes naturally in Lisp.
What I mean by functional abstraction is hiding away the implementation details of some data structure, using a set of functions. Consider, for example, the following:
(This is taken from Peter Norvig's PAIP)
I want to use "bindings", that is, key -> value pairs where the key represents a variable and the value represents what this variable is "binded" to. Say I choose the idiomatic Lisp representation of an "association list", which is just a list of key, value pairs (essentially ((key . value) (key2 . value2)).
A Lisp programmer would immediately bang the following functions to abstract the "bindings" concept:
Now, this may not seem like much, but think about how convenient this approach makes the later programming using bindings. Lisp gurus usually say that "if you want to program X in Lisp, you first create a programming language suitable for things like X and then implement X on top of it", and the code example I showed is an important foundation of this approach (in reality, macros are usually heavily employed for the more hairy tasks).
The current "bindings" implementation is a list of pairs, but the "user" (the higher abstraction level) should know nothing about it. Underneath, the implementation can be changed to hashes, vectors, binary trees, whatever.
The important thing is the definition of a new "data type" - bindings, that can be used on the upper abstraction level just like another type, using all the auxiliary functions provided with it.
In Perl, complex data structures are even more common. Since the introduction of references, many hackers use hashes of arrays of hashes, etc, we even have names for them: AoAoH, HoH, etc.
Choosing to implement "bindings" as a hash table of key -> value pairs, this could be abstracted in Perl as follows:
But somehow, I see too much "plain" code around. Code that accesses these data structures directly, assuming their implementation is fixed. I'd wish to see more "functional abstraction" in Perl - new "types" created above all those AoAoHs, with appropriate functions/constants to use them.
In my opinion, such code will be much more understandable, easier to debug and more fun to write. Programming bottom up is fun - at each level you have more power, and since each level is only an abstraction above a lower level, the debugging task is neatly broken into easy-to-handle layers/chunks.
P.S. Naturally, such a thing can be also done with OOP, but many people would prefer not to do it. Lisp gurus often say that Lisp + functional programming techniques "supercede" OOP (although Lisp has a powerful OO library - CLOS).