Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between flet vs let+funcall

These are two related questions actually.

  1. What is the difference between flet and let for binding functions.
  2. Are the examples A and B below equivalent?

A)

(flet ((myfun (x) (+ x 3)))
  (myfun 3))

B)

(let ((myfun (lambda (x) (+ x 3))))
  (funcall myfun 3))

NB:

(let ((myfun (lambda (x) (+ x 3))))
  (myfun 3))

will throw an error "myfun" undefined operator.

like image 823
marleynoe Avatar asked Mar 14 '23 15:03

marleynoe


1 Answers

Let's start from your second question:

  1. Are the examples A and B below equivalent?

As the answer of @sds discusses in detail, both are semantically equivalent, even if A is compiled more efficiently by most Common Lisp compilers (and this can be easily understood because B requires an additional call to the high level function funcall).

Now, for your first question:

  1. What is the difference between flet and let for binding functions.

One difference is that, since Common Lisp is a Lisp-2 language (see for instance this question), the example A binds the name of function myfun to a functional object, while the second one bind a normal lexical variable to the same functional object.

The consequence is that, from a practical point of view, a part from efficiency, there are differences both in syntax (a more convenient way for calling the functional object, like your example shows), and in semantics (for instance, the function defines a named-block, so that one can write something like: (flet ((myfun (x) (when (< x 0) (return-from myfun 0)) (+ x 3))) (myfun -4)), not possible with a let).

But maybe the most important point is that flet is only a part of the twin special operators flet, labels to define local functions (together with macrolet to define local macros, see the specification). And with the labels operator you can define recursive local functions, which is not possible with let.

like image 152
Renzo Avatar answered Mar 18 '23 23:03

Renzo