Why are Common Lisp functions visible outside an enclosing let?

Viewed 126

In Scheme, the function f below is not visible outside its enclosing let:

(let ()
  (define (f x)
    (+ x 1)))

(f 2)  ; Error.

However, in Common Lisp, the function f is visible outside its enclosing let:

(let ()
  (defun f (x)
    (+ x 1)))

(f 2)  ; Returns: 3

What is going on in the Common Lisp code above? How can f be visible outside the let?

2 Answers

In Scheme the define operator can be used both for top level definitions and for internal definitions. For internal definitions these should appear at the beginning of a body and it will have an effect like a letrec* form. See chapter 5.3 in R7RS.

In Common Lisp defun always defines a global function. To define local lexical functions Common Lisp has two other operators: flet and labels. labels is used for recursive functions.

From common lisp hyperspec:

Evaluating defun causes function-name to be a global name for the function specified by the lambda expression

 (lambda lambda-list
   [[declaration* | documentation]]
   (block block-name form*))

processed in the lexical environment in which defun was executed.

http://www.lispworks.com/documentation/HyperSpec/Body/m_defun.htm#defun

If you want a local definitions use flet or labels.

In the case of scheme, define is local to the <body> in which it is defined.

Related