From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: weber Newsgroups: gmane.emacs.help Subject: Re: defun vs lambda Date: Fri, 31 Jul 2009 04:41:43 -0700 (PDT) Organization: http://groups.google.com Message-ID: <787f39a2-b016-4d10-9b28-12bb0bca17da@e27g2000yqm.googlegroups.com> References: <87d47pkb52.fsf@galatea.local> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1249044091 7810 80.91.229.12 (31 Jul 2009 12:41:31 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 31 Jul 2009 12:41:31 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Fri Jul 31 14:41:24 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 1MWrQK-0005KE-0X for geh-help-gnu-emacs@m.gmane.org; Fri, 31 Jul 2009 14:41:24 +0200 Original-Received: from localhost ([127.0.0.1]:37545 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MWrQJ-00014h-DT for geh-help-gnu-emacs@m.gmane.org; Fri, 31 Jul 2009 08:41:23 -0400 Original-Path: news.stanford.edu!newsfeed.stanford.edu!postnews.google.com!e27g2000yqm.googlegroups.com!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 205 Original-NNTP-Posting-Host: 201.22.212.181 Original-X-Trace: posting.google.com 1249040503 1081 127.0.0.1 (31 Jul 2009 11:41:43 GMT) Original-X-Complaints-To: groups-abuse@google.com Original-NNTP-Posting-Date: Fri, 31 Jul 2009 11:41:43 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: e27g2000yqm.googlegroups.com; posting-host=201.22.212.181; posting-account=7GrjgQoAAAD6slWURausdJnhFDkmQYC8 User-Agent: G2/1.0 X-HTTP-Via: 1.1 stargate.datacom:3128 (squid/2.6.STABLE5) X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1 (.NET CLR 3.5.30729), gzip(gfe), gzip(gfe) Original-Xref: news.stanford.edu gnu.emacs.help:171380 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:66566 Archived-At: On Jul 24, 6:46=A0pm, p...@informatimago.com (Pascal J. Bourguignon) wrote: > 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": > =A0 =A0 - symbols naming functions, > =A0 =A0 - lambda expressions representing anonymous functions, > =A0 =A0 - byte code (compiled-functions), > =A0 =A0 - primitives ("subr" functions), > =A0 =A0 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 =A0 =A0 =A0 =A0 =A0 =A0(quote =A0 =A0 =A0 =A0 (l= ambda (x y) (+ x y)))) > =A0 =A0 =A0 (anonymous-function =A0 =A0 =A0 =A0 =A0 (function =A0 =A0 =A0= (lambda (x y) (+ x y)))) > =A0 =A0 =A0 (compiled-anonymous-function =A0(byte-compile '(lambda (x y) = (+ x y)))) > =A0 =A0 =A0 (function-name =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(quote =A0 =A0p= lus)) > =A0 =A0 =A0 (named-function =A0 =A0 =A0 =A0 =A0 =A0 =A0 (function plus)) > =A0 =A0 =A0 (compiled-named-function =A0 =A0 =A0(function compiled-plus)) > =A0 =A0 =A0 (interpreted-function =A0 =A0 =A0 =A0 (symbol-function 'plus)= ) > =A0 =A0 =A0 (compiled-function =A0 =A0 =A0 =A0 =A0 =A0(symbol-function 'c= ompiled-plus)) > =A0 =A0 =A0 (primitive-function =A0 =A0 =A0 =A0 =A0 (symbol-function '+))= ) > =A0 =A0(dolist (name =A0'(lambda-expression anonymous-function > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compiled-anonymous-function funct= ion-name named-function > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compiled-named-function interpret= ed-function > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 compiled-function primitive-funct= ion)) > =A0 =A0 =A0(insert (format "%s\n\t--> %S\n\t=3D=3D: %S\n\t=3D=3D> %S\n\n" > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0name (symbol-value name) (type= -of (symbol-value name)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(funcall (symbol-value name) 3= 2 10))))) > > lambda-expression > =A0 =A0 =A0 =A0 --> (lambda (x y) (+ x y)) > =A0 =A0 =A0 =A0 =3D=3D: cons > =A0 =A0 =A0 =A0 =3D=3D> 42 > > anonymous-function > =A0 =A0 =A0 =A0 --> (lambda (x y) (+ x y)) > =A0 =A0 =A0 =A0 =3D=3D: cons > =A0 =A0 =A0 =A0 =3D=3D> 42 > > compiled-anonymous-function > =A0 =A0 =A0 =A0 --> #[(x y) " =A0 \\\207" [x y] 2] > =A0 =A0 =A0 =A0 =3D=3D: compiled-function > =A0 =A0 =A0 =A0 =3D=3D> 42 > > function-name > =A0 =A0 =A0 =A0 --> plus > =A0 =A0 =A0 =A0 =3D=3D: symbol > =A0 =A0 =A0 =A0 =3D=3D> 42 > > named-function > =A0 =A0 =A0 =A0 --> plus > =A0 =A0 =A0 =A0 =3D=3D: symbol > =A0 =A0 =A0 =A0 =3D=3D> 42 > > compiled-named-function > =A0 =A0 =A0 =A0 --> compiled-plus > =A0 =A0 =A0 =A0 =3D=3D: symbol > =A0 =A0 =A0 =A0 =3D=3D> 42 > > interpreted-function > =A0 =A0 =A0 =A0 --> (lambda (x y) (+ x y)) > =A0 =A0 =A0 =A0 =3D=3D: cons > =A0 =A0 =A0 =A0 =3D=3D> 42 > > compiled-function > =A0 =A0 =A0 =A0 --> #[(x y) " =A0 \\\207" [x y] 2] > =A0 =A0 =A0 =A0 =3D=3D: compiled-function > =A0 =A0 =A0 =A0 =3D=3D> 42 > > primitive-function > =A0 =A0 =A0 =A0 --> # > =A0 =A0 =A0 =A0 =3D=3D: subr > =A0 =A0 =A0 =A0 =3D=3D> 42 > > nil > > The difference between quote and function, in emacs lisp, can be > detected only when you compile the code that use them. =A0function let > the compiler know that its argument is actually code, so it will > compile it. =A0quote 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: > > =A0 =A0(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. =A0So when you (funcall f), you will call > the function named by g. =A0But you still have to write (funcall f). > > You can of course name the function f, and so be able to directly call > it: > > =A0 =A0 (defun f () 2) > =A0 =A0 (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). =A0This > 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: > > =A0 =A0 (setf f 42) > =A0 =A0 (defun f () 2) > =A0 =A0 f --> 42 > > but instead, a function slot is changed: the symbol is "fbound". > > =A0 =A0 (unintern 'f) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; clean up > =A0 =A0 (list (boundp 'f) (fboundp 'f)) =A0 ; --> (nil nil) > =A0 =A0 (setf f 42) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; --> 42 > =A0 =A0 (list (boundp 'f) (fboundp 'f)) =A0 ; --> (t nil) > =A0 =A0 (defun f () 2) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; --> f > =A0 =A0 (list (boundp 'f) (fboundp 'f)) =A0 ; --> (t t) > > In the case of emacs lisp, which proposes only special variables, when > the symbol is bound, you can =A0find the binding of a variable =A0in the > value slot of the symbol: > > =A0 =A0 (symbol-value 'f) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; --> 42 > > Similarly, when the symbol is fbound, you can find the function > binding of the function int he function slot of the symbol: > > =A0 =A0 (symbol-function 'f) =A0 =A0 =A0 =A0 =A0 =A0 =A0; --> (lambda nil= 2) > > These operators are accessors, so you could modify the function slot > as well as the value slot: > > =A0 =A0(setf (symbol-value 'f) 42) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; = <=3D> (setf f 42) > =A0 =A0(setf (symbol-function 'f) (lambda () 2)) =A0 =A0 ; <=3D> (defun f= () 2) > > So in a way, you could write that: > > =A0 =A0(setf (symbol-function 'f) (lambda () 2)) > > and then be able to call the function f directly: > > =A0 =A0(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-tim= e. > > =A0 (setf (symbol-function 'f) (compute-some-lambda-expression)) > =A0 (f) ; --> ? > =A0 (byte-compile 'f) > =A0 (f) ; --> ? faster. > > or just: > > =A0 (setf (symbol-function 'f) (byte-compile (compute-some-lambda-express= ion))) > =A0 (f) ; --> ? faster. > > but you didn't mention generating code at run-time, so I guess I > overextended myself. =A0Sorry. > > -- > __Pascal Bourguignon__ Thanks Anselm. Pascal, I did wanted to generate code at run-time, similar to the way like defstruct generates helper functions. Thanks for the great explanation! Cheers, weber