From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: pjb@informatimago.com (Pascal J. Bourguignon) Newsgroups: gmane.emacs.help Subject: Re: defun vs lambda Date: Fri, 24 Jul 2009 23:46:01 +0200 Organization: Informatimago Message-ID: <87d47pkb52.fsf@galatea.local> References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1248475246 24213 80.91.229.12 (24 Jul 2009 22:40:46 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 24 Jul 2009 22:40:46 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sat Jul 25 00:40:39 2009 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MUTRN-0006CZ-TS for geh-help-gnu-emacs@m.gmane.org; Sat, 25 Jul 2009 00:40:39 +0200 Original-Received: from localhost ([127.0.0.1]:58330 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MUTRM-0005TU-Vw for geh-help-gnu-emacs@m.gmane.org; Fri, 24 Jul 2009 18:40:37 -0400 Original-Path: news.stanford.edu!newsfeed.stanford.edu!news.tele.dk!news.tele.dk!small.news.tele.dk!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 184 Original-X-Trace: individual.net mzVh4tBF8KQpCTrbYRqDfgd+l+4SBz5dMEF3TRFuVdVGJS+FDM Cancel-Lock: sha1:NjEwNWQ4MzU2ZDUxMzI0NWM0YzMzZGI4YjY2NzZmNjJiZmYzZDEyNg== sha1:uvcRvjSLi2jiFFazDifr1JMx7z0= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en X-Disabled: X-No-Archive: no User-Agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/22.3 (darwin) Original-Xref: news.stanford.edu gnu.emacs.help:171191 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:66378 Archived-At: weber writes: > Hi, > > I know I can return a function from another function, like this: > > (setq f (lambda () 2)) > > but I have to call it like (funcall f). Is there anyway that I could > do: > > (setf f (defun () 2) and then be able to call (f) ? Notice that funcall accepts various kinds of "functions": - symbols naming functions, - lambda expressions representing anonymous functions, - byte code (compiled-functions), - primitives ("subr" functions), and possibly others (such as macros). (defun plus (x y) (+ x y)) (defun compiled-plus (x y) (+ x y)) (byte-compile 'compiled-plus) (let ((lambda-expression (quote (lambda (x y) (+ x y)))) (anonymous-function (function (lambda (x y) (+ x y)))) (compiled-anonymous-function (byte-compile '(lambda (x y) (+ x y)))) (function-name (quote plus)) (named-function (function plus)) (compiled-named-function (function compiled-plus)) (interpreted-function (symbol-function 'plus)) (compiled-function (symbol-function 'compiled-plus)) (primitive-function (symbol-function '+))) (dolist (name '(lambda-expression anonymous-function compiled-anonymous-function function-name named-function compiled-named-function interpreted-function compiled-function primitive-function)) (insert (format "%s\n\t--> %S\n\t==: %S\n\t==> %S\n\n" name (symbol-value name) (type-of (symbol-value name)) (funcall (symbol-value name) 32 10))))) lambda-expression --> (lambda (x y) (+ x y)) ==: cons ==> 42 anonymous-function --> (lambda (x y) (+ x y)) ==: cons ==> 42 compiled-anonymous-function --> #[(x y) " \\\207" [x y] 2] ==: compiled-function ==> 42 function-name --> plus ==: symbol ==> 42 named-function --> plus ==: symbol ==> 42 compiled-named-function --> compiled-plus ==: symbol ==> 42 interpreted-function --> (lambda (x y) (+ x y)) ==: cons ==> 42 compiled-function --> #[(x y) " \\\207" [x y] 2] ==: compiled-function ==> 42 primitive-function --> # ==: subr ==> 42 nil The difference between quote and function, in emacs lisp, can be detected only when you compile the code that use them. function let the compiler know that its argument is actually code, so it will compile it. quote let the compiler know that its argument is actually data, so it won't compile it: the lambda expression returned by quote will always be considered as data (and happily interpreted by emacs lisp). > (setf f (defun () 2) and then be able to call (f) ? This defun form is invalid. You must give a function name: (setf f (defun g () 2)) defun returns the name of the function, that is the symbol g, and f will be bound to that symbol. So when you (funcall f), you will call the function named by g. But you still have to write (funcall f). You can of course name the function f, and so be able to directly call it: (defun f () 2) (f) --> 2 Now to answer your formal question, there is no way to call the function bound to a variable without using funcall (or apply). This is because emacs lisp is what is called, a "Lisp-2". Have a look at: http://www.nhplace.com/kent/Papers/Technical-Issues.html When we define a function with defun, what happens, is that the value binding of the name of the function is not changed: (setf f 42) (defun f () 2) f --> 42 but instead, a function slot is changed: the symbol is "fbound". (unintern 'f) ; clean up (list (boundp 'f) (fboundp 'f)) ; --> (nil nil) (setf f 42) ; --> 42 (list (boundp 'f) (fboundp 'f)) ; --> (t nil) (defun f () 2) ; --> f (list (boundp 'f) (fboundp 'f)) ; --> (t t) In the case of emacs lisp, which proposes only special variables, when the symbol is bound, you can find the binding of a variable in the value slot of the symbol: (symbol-value 'f) ; --> 42 Similarly, when the symbol is fbound, you can find the function binding of the function int he function slot of the symbol: (symbol-function 'f) ; --> (lambda nil 2) These operators are accessors, so you could modify the function slot as well as the value slot: (setf (symbol-value 'f) 42) ; <=> (setf f 42) (setf (symbol-function 'f) (lambda () 2)) ; <=> (defun f () 2) So in a way, you could write that: (setf (symbol-function 'f) (lambda () 2)) and then be able to call the function f directly: (f) ; --> 2 But it's simplier to write (defun f () 2). Unless of course you have to generate the body of the function at run-time. (setf (symbol-function 'f) (compute-some-lambda-expression)) (f) ; --> ? (byte-compile 'f) (f) ; --> ? faster. or just: (setf (symbol-function 'f) (byte-compile (compute-some-lambda-expression))) (f) ; --> ? faster. but you didn't mention generating code at run-time, so I guess I overextended myself. Sorry. -- __Pascal Bourguignon__