here are some things that I couldn't gather from Steele's book:
1) temporarily, let's forget about macrolet. Suppose I have a function in which I'd like to define a local function (with `flet' or with `labels'). And also, suppose that I want that function to be inlined inside the main function. So it looks like this:
(defun test () (declaim (inline f)) ;; #### does the declaim line belong here??? #### (flet ((f (x) (declaim (inline f) ;; #### or does it belong here??? #### (* x x)))) (blah...) (+ (f 2) (f 3))))
so I want to know where the declaration *should* go so that the function is inlined.
2) can someone explain the difference between `labels' and `flet' ? I can't understand it :-(
3) in Allegro CL, after you've verified that your program is really clean and bug-free, you compile it with all the best compiler options. then you get a .fasl file which you can load at an time, and you can run a program that way. But is that the fastest way? is there a way to turn your program into a binary executable that will run even faster?
In article <6id1qg$...@senator-bedfellow.MIT.EDU>, David Bakhash <ca...@mit.edu> wrote:
>here are some things that I couldn't gather from Steele's book:
>1) temporarily, let's forget about macrolet. Suppose I have a function ... >(defun test () > (declaim (inline f)) ;; #### does the declaim line belong here??? ####
^^^^^^^^^^^^^^^^^^^ How about (declare (inline f))
A declare at the beginning of a body effects that body. So to inline into the body of test you'd wish to say it here. Not that Lisp really "has to" do it. The environment can ignore you at its discretion.
However, F hasn't been defined yet..... so this probably isn't a good place to put this declaration...
> (flet ((f (x) > (declaim (inline f) ;; #### or does it belong here??? ####
^^^^^^^^^^^^^^^^^^^
Again DECLARE. DECLAIM/PROCLAIM to effect the global environment (and generally used outside the body of functions et. al. ). DECLARE to effect the body of a function/let/etc. The declaration would only effect the body of F. Not where F is utilized.
The closest body to the place where you wish to inline is that of the FLET. That would be where you would want to put the inline declaration.
As mentioned above... the environment doesn't "have to" inline.
However, .....
>2) can someone explain the difference between `labels' and `flet' ? I > can't understand it :-(
You can't write recursive FLET's. The functions defined by the beginning of an FLET can only be seen in the body of the FLET
(flet ( ... fcn defs .... ) ... flet's body.. )
Whereas the functions defined by the beginning of a LABELS can be seen both in the body and in definitions part...
Examples:
(flet ( (f (x) (g (1+ x )) ) (g (x) (* x 10)) )
(f 10))
Or even
(flet ( (f (x) (cond ((= x 0 ) 'all-done) ( t (f (1- x ))))) ) (f 10 ) )
Will "die" a horrible death. The function F knows nothing of the function g or of itself. Where:
(labels ( (f (x) (g (1+ x )) ) (g (x) (* x 10)) )
(f 10))
works.
In some sense, FLET and LABELS are to functions what LET and LET* are to local variables. It isn't a precise analogy but close.
>3) in Allegro CL, after you've verified that your program is really > clean and bug-free, you compile it with all the best compiler .... > there a way to turn your program into a binary executable that will > run even faster?
Compiling turns your Lisp code into "native binary". Things don't get any faster than that. :-) It is just as "native" as the output of a C/C++ compiler.
You can peek under the hood...
(disassemble #'car ) ;; or one of your compiled functions...
should reveal the associated opcodes for your processor if compiled.
Somewhat related to the above question... You can develop (with the proper tools) as standalone application that doesn't return you to "start up" the lisp environment to run. You can forego the startup overhead of the development environment and it would be faster from start to finish ( for instance, if you developed some filter that read some data, transformed it, and then quit). But besides the development environment start up /close down overhead.... your code would execute no faster.
--
Lyman S. Taylor "There is something unexplainable here, Scully, (ly...@cc.gatech.edu) but it is certainly not unidentifiable." Fox Mulder - X-Files
* David Bakhash | here are some things that I couldn't gather from Steele's book:
you'll doubtless get numerous answers, so I'll try a shot, too...
| 1) temporarily, let's forget about macrolet. Suppose I have a function | in which I'd like to define a local function (with `flet' or with | `labels'). And also, suppose that I want that function to be inlined | inside the main function. So it looks like this:
the first question that occurs to me is "why do you want to inline it?" the second question is "why do you think you have tell the compiler so explicitly?"
| so I want to know where the declaration *should* go so that the function | is inlined.
evaluate (EXPLAIN-COMPILER-SETTINGS), as suggested when you start Allegro and in the User Guide. the optimization setting affecting whether to try and _automatically_ inline function calls is
;; COMPILER:GENERATE-INLINE-CALL-TESTS-SWITCH T
this is actually a variable, whose values is
#<Function SPEED >= SPACE @ #x2683e2>
indicating that if your optimization declarations satisfy this condition, the compiler will try to inline calls. you can learn more about this:
(DECLAIM (:EXPLAIN :CALLS))
will tell you about each call the compiler has to generate code for. (note: it quickly gets verbose.)
| 2) can someone explain the difference between `labels' and `flet' ? I | can't understand it :-(
the scope of an FLET function binding is the _body_ of the FLET form. the scope of a LABELS function binding is the _whole_ LABELS form.
| 3) in Allegro CL, after you've verified that your program is really | clean and bug-free, you compile it with all the best compiler | options. then you get a .fasl file which you can load at an time, | and you can run a program that way. But is that the fastest way? is | there a way to turn your program into a binary executable that will | run even faster?
when finalizing some software for packaging as a product, you build an image that is essentially a stand-alone program just like the Allegro CL image is. you will replace the top-level loop with your own, and will probably not have the editor interface and all that included. building such images can save you a lot of size, but probably not much in speed.
#:Erik -- Support organized crime: use Microsoft products!
Sam Steingold wrote: > >> there a way to turn your program into a binary executable that will > >> run even faster?
> Only if you purchased a full commercial version (the free Linux version > doesn't do that, unfortunately).
Sure it does. Perhaps you are confusing it with Allegro CL for Windows?
Paul (eagerly awaiting ACL 5.0, and hoping they'll release it for Linux as well)
---
;; Here's an example, using this file:
(defun counter (n) (declare (fixnum n)) (let ((x 0)) (declare (fixnum x)) (loop for i from 1 to n do (incf x i)) x))
USER(7): :ld test.lsp ; Loading ./test.lsp USER(8): (time (counter 10000)) ; cpu time (non-gc) 3,080 msec user, 30 msec system ; cpu time (gc) 320 msec user, 20 msec system ; cpu time (total) 3,400 msec user, 50 msec system ; real time 3,760 msec ; space allocation: ; 320,163 cons cells, 1 symbol, 880,168 other bytes 50005000 USER(9): :cf test.lsp ;;; Compiling file test.lsp ; Compiling COUNTER Warning: COUNTER, :OPERATOR was defined in ./test.lsp and is now being defined in test.lsp ;;; Writing fasl file test.fasl Warning: No IN-PACKAGE form seen in test.lsp. (Allegro Presto will be ineffective when loading a file having no IN-PACKAGE form.) ;;; Fasl write complete USER(10): :ld test.fasl ; Fast loading ./test.fasl Warning: COUNTER, :OPERATOR was defined in ./test.lsp and is now being defined in test.lsp USER(11): (time (counter 10000)) ; cpu time (non-gc) 10 msec user, 0 msec system ; cpu time (gc) 0 msec user, 0 msec system ; cpu time (total) 10 msec user, 0 msec system ; real time 4 msec ; space allocation: ; 1 cons cell, 0 symbols, 32 other bytes 50005000 USER(12):
>> there a way to turn your program into a binary executable that will >> run even faster?
> Compiling turns your Lisp code into "native binary". Things don't > get any faster than that. :-) It is just as "native" as the output > of a C/C++ compiler.
Some compilers can do more if they are compiling one or more modules as a whole. I think CMU CL has such a mode. Lucid CL maybe?
In article <hckg1ispfmy....@eto.ericsson.se>, Raymond Wiker <eto...@eto.ericsson.se> wrote:
>Sam Steingold <s...@usa.net> writes: >> 3. I use ... >> (defmacro sqr (xx) .... > Ummm. Doesn't this evaluate xx twice for the case when xx is > not an atom?
The temporary variable will be evaluated twice when this LET is evaluated. But that isn't the original expression (which may have associated side effects, which is evaluated once). Evaluating a variable has no side effects.
--
Lyman S. Taylor "Twinkie Cream; food of the Gods" (ly...@cc.gatech.edu) Jarod, "The Pretender"
>> there a way to turn your program into a binary executable that will >> run even faster?
> Compiling turns your Lisp code into "native binary". Things don't > get any faster than that. :-) It is just as "native" as the output > of a C/C++ compiler.
Some compilers can do more if they are compiling one or more modules as a whole. I think CMU CL has such a mode. Lucid CL maybe?
> The temporary variable will be evaluated twice when this LET is > evaluated. But that isn't the original expression (which may > have associated side effects, which is evaluated once). > Evaluating a variable has no side effects.
Although I've used this trick myself from time to time out of laziness, it's worth noting (just so you know) this is not correct and should not be used in code you export to other people who might not have the same understanding of "typical CL code" as you. In particular, if you personally never use symbol macros, you personally won't be harmed (much) by the atom test.
But it is in principle possible for (atom x) to be true of a symbol-macro x and it is (though I think very bad style) in principle possible for such a symbol-macro to have a side-effect, or at least to create a difference in value. e.g., consider a variable TEMPERATURE which literally reads the outdoor temperature and note that (SQR TEMPERATURE) might actually return a number that is not a perfect square as the temperature changes from 30 to 31 and the result is 930. This could be confusing at least.
>Although I've used this trick myself from time to time out of >laziness,
Personally, I rarely use macros to do inlining. That's what the inlining directives are for. :-)
It would seem that a reasonable compiler would manage not to add too much overhead if the LET was always used. That renders the symbol macro "problem" moot. [ Not that I'd ever seen one before...***]
What's that Knuth quote... :-)
"Premature optimization is the root of all evil ... "
*** Are symbol macros new to ANSI CL?? I can't seem to find anything in CLtL2. Of course it could be in there somewhere... just hard to find. Seems like a weird concept to bind general expressions to a symbol... which makes landmines like the one mentioned here...
--
Lyman S. Taylor "Twinkie Cream; food of the Gods" (ly...@cc.gatech.edu) Jarod, "The Pretender"
In article <6ijjnj$...@pravda.cc.gatech.edu>, Lyman S. Taylor <ly...@cc.gatech.edu> wrote: ...
>*** Are symbol macros new to ANSI CL?? I can't seem to find anything in > CLtL2. Of course it could be in there somewhere...
Ooops, I was looking for DEFINE-SYMBOL-MACRO which seems to postdate CLtL2. Eventually, I found my copy of "On Lisp" which put me onto the right track of SYMBOL-MACROLET. --
Lyman S. Taylor "Twinkie Cream; food of the Gods" (ly...@cc.gatech.edu) Jarod, "The Pretender"
Sam Steingold <s...@usa.net> writes: > >>>> In message <354A628F.98A15...@interaccess.com> > >>>> Sent on Fri, 01 May 1998 19:02:23 -0500 > >>>> Honorable Paul Dietz <di...@interaccess.com> writes > >>>> on the subject of "Re: General Lisp questions...": > >> Sam Steingold wrote:
> >> > >> there a way to turn your program into a binary executable that will > >> > >> run even faster?
> >> > Only if you purchased a full commercial version (the free Linux version > >> > doesn't do that, unfortunately).
> >> Sure it does. Perhaps you are confusing it with Allegro CL for Windows?
> please re-read my message. > I was talking about **stand-alone executables**, **NOT** compilation.
Well it can do this because excl:dumplisp is there and works fine. This results is a stand alone binary executable. If you don't want it to look like lisp to your users then just make sure that your application's top level is started. The gory details of this are described in section 8.3 of the manual.
Have fun,
-Eric "Don't tell the EPA I've dumped lisp in the past." Dahlman
> -- > Sam Steingold, running RedHat5 GNU/Linux (http://www.linux.org) > Micros**t is not the answer. Micros**t is a question, and the answer is Linux, > the choice of the GNU (http://www.gnu.org) generation. > Only a fool has no doubts.