Dear monks,

I'm carrying on with my quest (as told here and here) to understand what makes Lisp so attractive and how we can use/implement these features/paradigms in Perl.

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:

(defconstant no-bindings '((t . t))) (defun get-binding (var bindings) "Find a (var . value) pair in a binding list" (assoc var bindings)) (defun binding-val (bindings) "Get the value part of a single binding" (cdr binding)) (defun lookup (var bindings) "Get the value part (for var) for a binding list" (binding-val (get-binding var bindings)) (defun extend-bidings "Add a (var . value) pair to a binding list" (cons (cons var val) (if (eq bindings no-bindings) nil bindings)))
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:

sub no_bindings { return not keys %{$_[0]}; } sub is_variable { return substr($_[0], 0, 1) eq '?'; } sub get_binding { my ($var, $bind) = @_; defined($bind->{$var}) ? [$var, $bind->{$var}] : undef; } sub binding_val { defined($_[0]) ? $_[0]->{1} : undef; } sub lookup { my ($var, $bind) = @_; return $bind->{$var}; } sub extend_bindings { my ($var, $val, $bind) = @_; $bind->{$var} = $val; return $bind; }

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).


In reply to Using functional abstraction in Perl by spurperl

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.