Now, when we have seen the Classic Functions we could begin to form a big picture of what we have.

There functions should be used to visualize how data is processed - how one list structure is being traversed (walked) and a new, fresh one is being created, as in case of the map function.

In the real-world Lisp systems, such as CMUCL or SBCL or various Scheme implementations the definitions of there classic functions would look differently - more cluttered and stuffed. This is because they include some performance optimizations, and usually were written in an imperative style, to avoid the usage of recursion, because it isn't efficient without a proper support for Tail-Call optimization.

Nevertheless, keep in mind these naive and beautiful, recursive versions, so you could literally see whats going on inside. Keep your own procedures compact and as simple and possible (but not simpler) and you will able to memorize and visualize them the same way.

It is reasonable to complete some Scheme course, based on HtDP or SCIP books, to learn lots of small procedures, in order to not reinvent the wheel, and appreciate more elegance and beauty. Usually, people who write without reading the classic books end up producing so-called spaghetti code, so common in J* world.

Because we have simple and consistent rules and uniform list structure, made out of pairs, which represent the data and the code, we could hold and visualize a much bigger chunks of a program in our mind.

When we need some complicated data-structure, such as a tree, or a graph, or a table we can make it out of pairs. This requires some discipline, and little more effort, but it pays back by having our programs more uniform, less bloated without unnecessary artificial complications.

The Lisp language itself consist of a very few special forms - a specialized syntactic constructs for performing certain tasks, such as creating a procedure or a binding, and one, uniform, general evaluation rule for all Lisp expressions.

The rule says how every expression is evaluated - first to evaluate all the sub-expressions - formal parameters, then apply the procedure to the values of its arguments (parameters). Eval-Apply rule.

Each special form has its own evaluations rule, this is why it is called special form. All other expressions evaluated with the Geneal Rule. This gives uniformity, consistency and unambiguity to the language.

The most amazing fact is that we could define not just new data-structures, but also new special forms. For this we have to use the same underlying list structure, feature of language called macros - the way to create new expressions, including new procedures, when program is executing.

This allows us to extend Lisp with new syntactic sugar and data structures which reflect our problem domain, producing so-called Domain-Specific Language, or DSLs. Those languages are embedded in Lisp - they rely on the same common underlying list structure.

What could be done with such set of features? Well, some great people have managed to embed the whole Programming Paradigm (OOP) in Lisp using nothing, but hight-order procedures, macros and structures. This is called Common Lisp Object System, or CLOS.

This have been done not just once, this have been done for almost every major Common Lisp implementation (CLOS is standardized) and for each major Scheme implementation, which has its own Object Systems, inspired by CLOS.

There insights require time to be internalized and hours and hours of reading sources and of practice before they could be actually realized. After that, I'm not kidding, you would posses almost unimaginable power of clarity of thought and knowledge.

The last level, to become a Magician, is to know how to implement Lisp efficiently.

Last modified 8 years ago Last modified on Jan 9, 2013, 8:04:49 PM
Note: See TracWiki for help on using the wiki.