From: Kaz Kylheku
Subject: Re: constructing a lambda
Date: 
Message-ID: <1138620220.596195.289860@o13g2000cwo.googlegroups.com>
Stefan Ram wrote:
> I tried to solve the word puzzle by Frank Buss, took my first
>   steps into Common Lisp, and immediatly encountered a problen:
>
> ( defun alpha () "alpha" )

Note: it's customary to omit whitespace between the parentheses and
what they enclose.

> ( defun beta ( x )( concatenate 'string x "beta" ))
>
> ( defun bind( source sink )
>   ( lambda()( funcall sink( funcall source ))))

Note that this LAMBDA here is incorporated into the BIND function.

What you are asking below is to construct the source code for the
lambda at run time. This is a drastic change to the semantics of the
program.

> ( print ( bind #'alpha #'beta ))
>
>   It prints:
>
> #<FUNCTION :LAMBDA NIL (FUNCALL SINK (FUNCALL SOURCE))>
>
>   What I'd like to see is:
>
> #<FUNCTION :LAMBDA NIL "alphabeta")>
>
>   I.e., the function »bind« should evaluate
>
> ( funcall sink( funcall source ))
>
>   to construct the lambda-body.

You now need run-time eval:

(defun bind (source sink)
  (eval `(lambda () ,(funcall sink (funcall source))))

The backquote syntax is a shorthand notation for list construction.
It's the same as writing

  (list 'lambda nil (funcall sink (funcall source)))

The backquote contains evaluation-suppressed material like a regular
quote, except that expressions introduced by a leading comma are
evaluated to produce a value.

Instead of EVAL you could use COMPILE to actually dynamically compile
the LAMBDA source code.

But you should also think about whether it's wortwhile: does the
problem you are trying to solve need a dynamic evaluator or compiler?

Is the problem the fact that the SOURCE and SINK functions are called
each time the closure is invoked? That can be solved without using
dynamic evaluation, like this:

  (defun bind (source sink)
    (let ((cached-result (funcall sink (funcall source))))
      (lambda () cached-result)))

You see? The BIND function chains together SOURCE and SINK, stores the
result in a lexical variable and that variable binding is captured by
the closure that is returned. Whenever that closure is funcalled, it
returns that captured variable, CACHED-RESULT, which just holds the
string "alphabeta".