let and flet in emacs lisp

前端 未结 4 1038
小鲜肉
小鲜肉 2021-01-30 13:31

I don\'t know if you would call it the canonical formulation, but to bind a local function I am advised by the GNU manual to use \'flet\':

(defun adder-with-flet         


        
相关标签:
4条回答
  • 2021-01-30 13:44

    I did a quick search of the Emacs lisp manual and couldn't find any reference to 'flet, which isn't terribly surprising since that is a part of cl - the common-lisp package.

    let will do a local binding as well, but it won't bind to the "function cell" for that symbol.

    i.e. This works:

    (let ((myf (lambda (x) (list x x))))
      (eval (list myf 3)))
    

    but

    (let ((myf (lambda (x) (list x x))))
      (myf 3))
    

    fails with the error: "Lisp error: (void-function myf)"

    flet on the other hand, does do the binding to the function cell, so this works:

    (flet ((myf (x) (list x x)))
      (myf 3))
    

    Notice the difference being that flet allows you to use the symbol myf directly, whereas the let does not - you have to use some indirection to get the function out of the "value cell" and apply that appropriately.

    In your example, the 'mapcar' did the equivalent to my use of 'eval.

    0 讨论(0)
  • 2021-01-30 13:50

    Unlike Scheme, Emacs Lisp is a 2-lisp, which means that each symbol has two separate bindings: the value binding and the function binding. In a function call (a b c d), the first symbol (a) is looked up using a function binding, the rest (b c d) are looked up using the value binding. Special form let creates a new (local) value binding, flet creates a new function binding.

    Note that whether value or function binding is used for lookup depends on the position in the (a b c d) function call, not on the type of the looked-up value. In particular, a value binding can resolve to function.

    In your first example, you function-bind f (via flet), and then do a function lookup:

    (f ...)
    

    In your second example, you value-bind f to a function (via let), and then use a value lookup:

    (... f ...)
    

    Both work because you use the same kind of binding and lookup in each case.

    http://en.wikipedia.org/wiki/Common_Lisp#Comparison_with_other_Lisps

    0 讨论(0)
  • 2021-01-30 13:51

    You don't have to use flet if you do not want to. You place a function in the function cell of a local symbol defined using let as in the following example:

    (let ((ALocalSymbol))
      (fset 'ALocalSymbol (lambda (x) (* 2 x)))
      (ALocalSymbol 4)
      )
    

    Evaluating this will return 8. Do notice the quote in front of ALocalSymbol in (let ((ALocalSymbol))...). While setq quotes symbols, fset does not.

    flet is a syntactic sugar of sorts. Using a plain-old let to define nil-valued symbols, allows you to choose which "cell" of a symbol to set. You could use setq to set the symbol's value cell or fset to set the function cell.

    Hope this helps,

    Pablo

    0 讨论(0)
  • 2021-01-30 13:59

    @d11wq there is `funcall' for this purpose. The following works:

    (defun adder-with-let (x)
      (let ((f #'(lambda (x) (+ x 3))))
        (funcall f 3)))
    
    (adder-with-let 3) ;=> 6
    
    0 讨论(0)
提交回复
热议问题