Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!decwrl!ads.com!rar From: rar (Bob Riemenschneider) Newsgroups: comp.emacs Subject: `let' question Message-ID: <9010100137.AA24957@saturn.ads.com> Date: 10 Oct 90 01:37:27 GMT Lines: 81 In-Reply-To: reingold@emr.cs.uiuc.edu's message of 9 Oct 90 21:13:26 GMT => From: reingold@emr.cs.uiuc.edu (Ed Reingold) => Newsgroups: gnu.emacs => => Does the let mechanism in GNU Emacs Lisp allow a function to be redefined => in the same way a variable can be? I want to do something like this: => => (defun silly () => (forward-char 1)) => => (defun ridiculous () => (backward-char 1)) => => (defun idiotic () => (let (('silly 'ridiculous)) => (silly)));; I want this to be a call to move backward one character Short answer: No, because let handles changes to the value cell, but not the function cell. (Take a look at specbind and let in src/eval.c.) Longer answer: You can define a macro to do what you want. Basically, you'd like (defun idiotic () (rename-function-let ((silly ridiculous)) (silly))) to expand to something like (defun idiotic () (let ((tmp (make-symbol "tmp"))) (fset tmp (symbol-function 'silly)) (fset 'silly (symbol-function 'ridiculous)) (set tmp (silly)) (fset 'silly (symbol-function tmp)) (symbol-value tmp))) or, if you're feeling really silly, (defun idiotic () (let ((silly (make-symbol "silly"))) (fset silly (symbol-function 'silly)) (fset 'silly (symbol-function 'ridiculous)) (set silly (silly)) (fset 'silly (symbol-function silly)) (symbol-value silly))) More generally, you really want a defun-like syntax, with renaming as a special case. Thus, you'd define idiotic as follows (defun idiotic () (flet ((silly () (ridiculous))) (silly))) where (defun fname (fbinding) (car fbinding)) (defun fvars (fbinding) (car (cdr fbinding))) (defun fbody (fbinding) (car (cdr (cdr fbinding)))) (defmacro flet (fbindings body) (list 'let '((tmp (make-symbol "tmp"))) (list 'fset 'tmp (list 'symbol-function (list 'quote (car (car fbindings))))) (list 'fset (list 'quote (fname (car fbindings))) (list 'quote (list 'lambda (fvars (car fbindings)) (fbody (car fbindings))))) (list 'set 'tmp body) (list 'fset (list 'quote (fname (car fbindings))) '(symbol-function tmp)) '(symbol-value tmp))) (The generalization to flet-ing multiple symbols is left as an exercise.) -- rar