Back from the past (Part 2)

Common Lisp

 

Let us start from the topic of closure for this dispatch. We will eventually run into explanation of new macros that we used here and also touch upon the rantings we did in the previous dispatch.

Closure

We hope to have tickled some curiosity with the use of word Closure. This word triggers fear in many programmers what recursion used to do prior to this. An interesting topic has found in-roads to business programming these days with many javascript frameworks. Let us look at how it related to what we were attempting to do earlier in Lisp.

We expand the simplification of the lisp language construct as follows

 

( [some function name] ( [some parameters] ) [some return value] )

 

We produce closure from the above generic language construct where the [some return value] offers another function which has the lexical context of its hosting / home function. To demonstrate let us use name’s structure. i.e. Name has components like first, middle and last, right! Now let us define a function that concatenates these components to form a good looking full name.

 

 (defun full-name (

        (lambda (family-name)

           (lambda (given-name middle-name)

               (string-append given-name middle-name family-name)

           )

       )

   )

 

 

When we map this to the simplified construct we notice the trickery involved. [some function name] correspond to deffun full-name as well as the first lambda. The [some return value] correspond to both first and second lambda. This trickery is because of the nesting of function which preserve the lexical context. The second lambda is nested within the first lambda and is the return value. However, the first lambda is nested as well within the function full-name.

Thus, first lambda becomes equivalent to both [some function name] and [some return value]. The use of these function definitions puts the closure in perspective –

 

   ; let us define a name builder for the Gupta family which stores the family name of Gupta

   (defun gupta-family (

           full-name “Gupta”

       )

   )

 

   ; call the closure with family name and provided given and middle name to get the full name

   ; closure has the context of the family name and prepend and append the given and middle name appropriately

 

   (funcall #’gupta-family “Ramesh” “Chandra”)

 

 

That is all to closure that there can be. Simply put closure is the enclosing of the lexical context which can be used and re-used. In Lisp with very less syntactical symbols (only rounded brackets) cognitively the focus is on the topic thus making it pleasure to read. With careful choice of words the lisp program almost many times do not require any additional voice commentary than the program itself.

From the previous article

Let us bring back the pattern matching lisp function

 

   (defun pattern-matcher (pattern input &optional (bindings no-bindings))

     “Match pattern against input in the context of the bindings”

     (cond ((eq bindings fail-to-match) fail-to-match)

       ((variable-pattern pattern)

         (match-variable pattern input bindings))

       ((eql pattern input) bindings)

       ((segment-pattern-p pattern)

         (segment-matcher pattern input bindings))

       ((single-pattern-p pattern)

         (single-matcher pattern input bindings))

       ((and (consp pattern) (consp input))

         (pattern-matcher (rest pattern) (rest input)

               (pattern-matcher (first pattern) (first input)

                   bindings)))

       (t fail-to-match)))

 

 

Let us now look at some interesting functions and macros of the Lisp.

Interesting functions

In the program above as well in the program we used earlier for pattern-matching there are few functions that are worth narrating.

lambda

This function is used to define unnamed function. A named function starts with the macro defun.

consp

This is from the pattern-matcher code where function determines if the supplied argument is a valid list type object or not. It returns the true constant i.e. t or NIL otherwise.

t (constant)

Equivalent to true in the Lisp language.

rest

This function returns everything from the list other than the first element.

cond

This is a function that evaluates a condition. The actual condition itself is passed as parameter to the function.

A small detour is necessary to put a concept in perspective. In Lisp operations are performed using a simplified syntax like this –

 

(operator argument1 argument2 argument3 … &optional argument-opt)

 

 

operator is function like cond it can be mathematical operator like + and depending on the function the number of arguments run. The keyword &optional is to indicate every argument that follows the &optional is not expected to be present.

This list is by no means exhaustive and it will take perpetuity if we set out to list all such functions. If you notice there are more keywords in the pattern-matcher that listed in the interesting functions. They are user defined functions. Functions like variable-pattern, segment-pattern-p, segment-matcher etc. are functions defined in the ELIZA library the very early NLP implementation in Lisp.

Thus, if you could see the pattern matching reduces to checking for variable / constant token, single element match for the token or then for segment i.e. one or more match for the token.

At times Lisp can communicate so eloquently the notion that explaining the result becomes so much easier and could address the problem that modern day AI suffers ability to explain the result.

If you are spruced up to start using Lisp we do recommend to get started with portacle which is an amazing editor for common-lisp and is built on top of EMACS. It does run on windows and linux.

Until next time happy hacking!