39 votes

laisser et flet dans lisp emacs

Je me demande si il y a un emacs lisp vétéran, il

Je ne sais pas si vous appelez ça de la formulation canonique, mais de lier une fonction locale je suis informé par la GNU manuel à l'usage "flet':

(defun adder-with-flet (x)
  (flet ( (f (x) (+ x 3)) )
    (f x))
)

Cependant, par accident, j'ai essayé (après avoir joué dans le Schéma un peu) l'expression suivante, où je lier une lambda expression à une variable à l'aide de 'laisser', et il fonctionne aussi si je passe la fonction de mapcar*:

(defun adder-with-let (x)
  (let ( (f (lambda (x) (+ x 3))) )
    (car (mapcar* f (list x)) ))
)

Et les deux fonctions de travail:

(adder-with-flet 3)   ==> 6
(adder-with-let 3) ==> 6

Je me demandais si quelqu'un savait pourquoi le second fonctionne car je ne trouve aucune documentation où 'laisser' peut être utilisé pour lier les fonctions de symboles?

Merci!

(P. S. j'ai posté ceci sur Aide d'Emacs forums mais n'ai obtenu aucune réponse donc je pensais que je serais frappé jusqu'à une communauté différente - qui est toujours appelé le cross-posting?)

44voto

user58804 Points 371

À la différence de Régime, Emacs Lisp est un 2-lisp, ce qui signifie que chaque symbole a deux liaisons: la valeur de la liaison et de la fonction de liaison. Dans un appel de fonction (a b c d), le premier symbole (a) est recherché à l'aide d'une fonction de liaison, le reste (b c d) sont récupérés à l'aide de la valeur de la liaison. Forme spéciale let crée un nouveau (local) de la valeur de liaison, flet crée une nouvelle fonction de liaison.

Notez que si la valeur ou la fonction de liaison est utilisé pour la recherche dépend de la position dans l' (a b c d) appel de fonction, et non pas sur le type de la valeur recherchée. En particulier, une valeur de liaison peut se résoudre à la fonction.

Dans ton premier exemple, la fonction bind f (via flet), puis une fonction de recherche de:

(f ...)

Dans ton deuxième exemple, vous la valeur de-lier f à une fonction (par let), puis utiliser une valeur de recherche:

(... f ...)

À la fois le travail parce que vous utilisez le même type de liaison et de recherche dans chaque cas.

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

20voto

Trey Jackson Points 49816

J'ai fait une recherche rapide sur Emacs lisp manuel et n'a pas pu trouver aucune référence à l' 'flet, ce qui n'est pas vraiment surprenant puisque c'est une partie de l' cl - le common-lisp paquet.

let va faire une liaison locale aussi bien, mais il ne se lient pas à la fonction de"cellule" pour ce symbole.

Ce qui fonctionne:

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

mais

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

échoue avec l'erreur: "Lisp erreur: (void fonction myf)"

flet d'autre part, ne faire la liaison à la fonction de la cellule, de sorte que cela fonctionne:

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

Notez la différence étant qu' flet vous permet d'utiliser le symbole myf directement, tandis que l' let n'est pas - vous devez utiliser une indirection pour obtenir la fonction de la "valeur de la cellule" et de l'appliquer de façon appropriée.

Dans votre exemple, le 'mapcar' a l'équivalent de mon utilisation de l' 'eval.

8voto

carltonf Points 51

@ d11wq il y a `funcall 'à cet effet. Les oeuvres suivantes:

 (defun adder-with-let (x)
  (let ((f #'(lambda (x) (+ x 3))))
    (funcall f 3)))

(adder-with-let 3) ;=> 6
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X