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, 31 Jul 2009 14:56:01 +0200 Organization: Anevia SAS Message-ID: <7c8wi5nh9a.fsf@pbourguignon.anevia.com> References: <87d47pkb52.fsf@galatea.local> <787f39a2-b016-4d10-9b28-12bb0bca17da@e27g2000yqm.googlegroups.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1249047664 19117 80.91.229.12 (31 Jul 2009 13:41:04 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 31 Jul 2009 13:41:04 +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 15:40:57 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 1MWsLx-0007xh-Dw for geh-help-gnu-emacs@m.gmane.org; Fri, 31 Jul 2009 15:40:57 +0200 Original-Received: from localhost ([127.0.0.1]:50041 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MWsLw-0002RL-N2 for geh-help-gnu-emacs@m.gmane.org; Fri, 31 Jul 2009 09:40:56 -0400 Original-Path: news.stanford.edu!headwall.stanford.edu!news.glorb.com!news2.glorb.com!newsfeed20.multikabel.net!multikabel.net!newsfeed10.multikabel.net!feeder.news-service.com!proxad.net!cleanfeed3-b.proxad.net!nnrp5-2.free.fr!not-for-mail Original-Newsgroups: gnu.emacs.help 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.101 (Gnus v5.10.10) Emacs/22.2 (gnu/linux) Cancel-Lock: sha1:Y2QzMGZiZWE0YjU3YTczZTE4ZWY5ODJjNTU1NmE5MTdiOTM5ZTIxMw== Original-Lines: 115 Original-NNTP-Posting-Date: 31 Jul 2009 14:56:01 MEST Original-NNTP-Posting-Host: 88.170.236.224 Original-X-Trace: 1249044961 news-4.free.fr 729 88.170.236.224:52658 Original-X-Complaints-To: abuse@proxad.net Original-Xref: news.stanford.edu gnu.emacs.help:171382 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:66567 Archived-At: weber writes: > I did wanted to generate code at run-time, similar to the way like > defstruct generates helper functions. "Times" are a little complicated matter in lisp. There is a read-time, a macro-expansion time, a compilation-time, a load-time and a run-time. In emacs lisp, things are a little simplier, since there's no customizable reader macros, there's no way to have user code executing at read-time. Nonetheless, there are means to have code evaluated during each of four other times. The problem is that more than "times" they are "phases", and they can occur intermixed one with the other. When at run-time, (eg in the scratch buffer you run the eval-last-expression (C-x C-e) command to evaluate the form you just typed), this form is first read; during this read-time, a lisp object is built according the syntax of the characters that are "read". Then the read object (which must be a form), is evaluated; during this run-time, it may be noted that we must interpret a macro. We will call corresponding macro-function, and we get the body of the macro executed during this macro expansion time. The macro may build a new function and call byte-compile to include a compiled function in the returned form, so we will have a compilation-time, which further may include macro-expansion times, etc. At compilation-time it is possible to set things up to be evaluated at load-time, only when you use load on the .elc file (see the load-time-value macro in (require 'cl)). If you compile the file (byte-compile-file), then you go to the compilation-time, it reads the source (read-time), then macroexpands the macros (macro-expansion time), then generate the byte code. You will later load it (load-time), and then you may execute it (run-time). If your program generate *at run-time* new functions, it may compile them (compilation-time, macro-expansion-time), and then execute them (back at run-time). etc... defstruct is a macro. You may use it in different circumstances, let's consider the three following cases: - You directly evaluate (defstruct point x y). - You put (defstruct point x y) in a source file, and then evaluate (byte-compile-file "point.el"), - You put it in a function, such as: (defun example () (defstruct point x y)) and you evaluate this form (which defines the function example), or you have this function in a file, and you byte-compile-file it. Then you load the file and you call the function (example). Let's consider the second case. The compiler will read the defstruct form, will notice that the symbol defstruct is defined as a macro, and the will call the corresponding macro-function. Now at macroexpansion time, defstruct can work, and generate the accessor functions needed from the arguments (a list of fields). Notice that the macro generates the functions at macro-expansion time, not at run-time. It returns a progn form containing defun forms amongst others. The compiler then compile that form, including the function definitions, and generate the byte-code of these functions in a file, along with the byte-code needed to _define_ these functions, that is, to associate the compiled function byte code to the symbol that name the function. Later you will load this byte-code file, and will have the function definition loaded in your emacs lisp image. No run-time has occured, yet your functions are already defined. In the third case, when compiling the defun form, the compiler will macroexpand the defstruct form, and will generate the body of the example function, which contain only the instructions needed to _define_ these function, that is, to associate the compiled function byte code to the symbol that name the function. Then you call (example), and at run-time, the accessors of the structure (which have been generated at macro-expansion time during compilation of the function example), will be _defined_, that is associated to the symbol that name the accessor function. Still, no code has been generated at run-time. In the first case, you might have the impression that defstruct generate code at run-time but as the above explications, and particularly the third case, may lead you to understand, when evaluating the defstruct form, there's a macroexpansion time during which the functions are generated, and then what is executed at run-time, is only the binding of these functions to their name (when executing the defun forms). Even without a compilation time, when interpreting code, the function generation done by macros is not exactly done at run-time. The reason why it is not the case, and why it is not needed to generate the code at run-time, is that all the information needed to generate these defstruct accessor functions is known before run-time: none of the arguments of the defstruct macro are evaluated (at run-time). They're taken literally, and known at compilation-time. The macro just returns the accessor function definition, it doesn't need to return forms that would evaluate the arguments (at run-time) and generate the functions (at run-time), since it has all the information to do it itself at macro-expansion time. Therefore since your sentence is contradictory, I still don't know when you want to generate your functions... -- __Pascal Bourguignon__