Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
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":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-18 18:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found