FLET LABELS

Both FLET and LABELS define local functions and evaluate forms contained in the FLET/LABELS context, where the local functions are defined. They accept any number of arguments, but first must be list of the function definitions. Note that no evaluation is done in the defining forms. Remaining arguments are evaled as in PROGN.

>(flet ((foo (a b) (+ a b))
        (bar (a b) (* a b)))
    (foo 1 (bar 2 3))) 
7

In this exaple we defined two local functions FOO and BAR.

The function definitions are the same as in DEFUN, so also work with &OPTIONAL and &REST parameters.

Difference between FLET and LABELS

The difference between FLET and LABELS is that the body forms of FLET do not have access to the other locally defined functions. The body forms of LABELS can contain calls to the local functions, so LABELS can even define recursive function.

FLET might be usefull if we want to locally shadow a globally defined function, but call the global function from within its body.

>(defun foo (a) (+ a 13))       ; global FOO
FOO
>(flet ((foo (a) (+ (foo a) 1)) ; local FOO makes small correction to global  
    (foo 1))                    ; calling the corrected FOO
15

In most cases, LABELS is more versatile.

In both cases the local function have the outer context as their lexical context, not the FLET/LABELS form itself. But the symbols representing them are bound in the FLET/LABELS context.

The difference is implemented in LabLISP by some special idea of defining the FLET functions as static. When called, static functions do not have access to the dynamic calling environment, only to the lexical and then global contexts. This also means that FLET function cannot be contained in shadowing environment.

LABELS functions will find the other (or self) local functions defined in the dynamic/calling environment.

Weird behavior might be generated by nesting LABELS forms with same function names. Since the outer form serves as lexical environment, the symbols from the body of the local function are looked up first in the lexical closure, before accessing the dynamic context.