|
From: Hoehle, Joerg-C. <Joe...@t-...> - 2005-06-13 15:20:47
|
Dan Cohen wonders: >Is there some reason these do not execute only once? 1. the current behaviour is explicitly covered by the CLHS. "If the same list (load-time-value form) is evaluated or compiled more than once, it is implementation-dependent whether form is evaluated only once or is evaluated more than once." However, "Implementations that implicitly compile (or partially compile) expressions processed by eval might evaluate form only once, at the time this compilation is performed." CLISP is not such an implementation, so it's behaviour is not covered. 2. Yes, indeed, why not?! Then I'd have a better feeling about recommending load-time-value for FFI stuff in CLISP, since it's valuable for compiled code and would not be stupid in interpreted code. OTOH, caching it seems reminescent of DMD, aka. long deprecated displace macros (they modified the source code's s-exp list representation). I'm actually unsure about how to realize a caching load-time-value in the interpreter. I don't know whether a per-load/compilation-unit weak-key EQ hash-table would be TRT. Support for interpreted mode is important in CLISP for as long as using interpreted code is the recommended way to debug code (or to get useful information inside the debugger). Regards, Jorg Hohle |
|
From: <don...@is...> - 2005-06-14 20:51:53
|
> If you want to avoid stupidly slow behaviour in the evaluator, i.e. > guarantee that a form is executed only once, you can use the MEMOIZED > macro, found in defs1.lisp. Is there any reason not to use this in the standard versions of defmacro and l-t-v ? If anyone really wants the uncached versions then they could be supplied via ext:...-uncached > A portable version of this MEMOIZED macro is available in > http://www.cliki.net/memoize-form I see that version is not quite suitable for the use proposed above. But it looks easy enough to fix. |
|
From: Bruno H. <br...@cl...> - 2005-06-15 12:13:59
|
Don Cohen wrote:
> > If you want to avoid stupidly slow behaviour in the evaluator, i.e.
> > guarantee that a form is executed only once, you can use the MEMOIZED
> > macro, found in defs1.lisp.
>
> Is there any reason not to use this in the standard versions of
> defmacro and l-t-v ?
> If anyone really wants the uncached versions then they could be
> supplied via ext:...-uncached
About LOAD-TIME-VALUE: There are two reasons for keeping clisp's behaviour,
i.e. in the interpreter, reevaluate each time:
1) In the interpreter, the developer wants changes to other functions to
be activated immediately, without re-entering forms. Example:
;; Let's compute the volume of a ball with radius x.
(defun my-func (x) (* 4/3 pi (* x x)))
(defun my-func-normalized (x)
(/ (my-func x) (load-time-value (my-func 0.01))))
(my-func-normalized 1.0) => 10000
;; Oops, I made a mistake.
(defun my-func (x) (* 4/3 pi (* x x x)))
;; Try it again.
(my-func-normalized 1.0) => 1000000 ;; Good! - in CLISP
(my-func-normalized 1.0) => 10000 ;; Unexpected! - in SBCL
The point here is that the developer made a mistake in my-func,
so he corrects it, and expects things to work. He did not make
a mistake in my-func-normalized, so he does not want to reenter
this form.
This is where "early compile" can be encumbering.
2) MEMOIZED does extra consing; it's useless to do extra consing to
implement a behaviour of which ANSI CL says that you cannot count upon.
About DEFMACRO, it's not clear what you mean.
Bruno
|
|
From: <don...@is...> - 2005-06-15 18:18:14
|
Bruno Haible writes: > About LOAD-TIME-VALUE: There are two reasons for keeping clisp's behaviour, > i.e. in the interpreter, reevaluate each time: > > 1) In the interpreter, the developer wants changes to other functions to > be activated immediately, without re-entering forms. Example: I agree that there's some value in this form of "immediate gratification", but it's not as if the current behavior is perfect in that respect, or as if perfection is only a few tweaks away. For instance, if you find yourself in an error break, say + complaining that nil is not a number and you see that your error was that (+ (cdr x) 2) should have been (+ (car x) 2) and then redefine your function, you can't just back up to the + and redo. (Actually, in the days of structure editing that might have worked!) Even if you could, you would have to understand all the same issues when you started to compile. To me it makes more sense to try to make the interpreted behavior similar to the compiled behavior. This seems especially important when it's so much easier to debug the interpreted code, but you really want the compiled code to work! Note that it's pretty easy to find cases where the interpreted code will now do what the programmer wants while the compiled code does not. (This is much more likely to happen to a beginner, but then the ideal of trying to make every change take immediate effect seems mainly for his benefit.) > 2) MEMOIZED does extra consing; it's useless to do extra consing to > implement a behaviour of which ANSI CL says that you cannot count upon. Alternatively, one might argue that it's useless to do extra evaluation (including lots of consing in many cases) that the spec says you can't count upon. The performance tradeoff seems clearly in favor of memoizing. The interpreted code already uses a whole bunch of conses and the addition of one more to store the result and a boolean is small fixed overhead compared to (almost always) much higher cost on (almost always) many different occasions. > About DEFMACRO, it's not clear what you mean. It's completely analogous. > (loop for i below 3 collect (load-time-value (print 2))) 2 2 2 (2 2 2) > (defmacro foo () (print 2)) > (loop for i below 3 collect (foo)) 2 2 2 (2 2 2) In both of these cases I'd like the print to happen only once, as would be the case if the code were compiled. |
|
From: Hoehle, Joerg-C. <Joe...@t-...> - 2005-06-15 13:27:16
|
Bruno Haible wrote: >guarantee that a form is executed only once, you can use the MEMOIZED >macro, found in defs1.lisp. Nice. CVS now exports it from EXT, because that's what IMHO should = happen to nice utilities in CLISP. I don't plan however to use it with FFI code, since the plan was not = not make compiled code slower by going through an extra test. BTW, how do people here feel about adding more documentation strings to = stuff from EXT? M-x slime-apropos shows a lot of symbols, but a really = small number of them have docstrings. When they do, I quite appreciate = it. Regards, J=C3=B6rg H=C3=B6hle. |
|
From: Sam S. <sd...@gn...> - 2005-06-15 13:44:07
|
> * Hoehle, Joerg-Cyril <Wbr...@g-...> [2005-06-15 15:26:59 +0200]: > > Nice. CVS now exports it from EXT, because that's what IMHO should > happen to nice utilities in CLISP. please document it in impext.xml:"macros3" (Additional Fancy Macros). > BTW, how do people here feel about adding more documentation strings > to stuff from EXT? please do add doc strings whenever you feel like it. you can also append a pointer to impnotes to the docstring. -- Sam Steingold (http://www.podval.org/~sds) running w2k <http://www.dhimmi.com/> <http://www.camera.org> <http://www.mideasttruth.com/> <http://www.memri.org/> cogito cogito ergo cogito sum |
|
From: Bruno H. <br...@cl...> - 2005-06-15 14:50:34
|
J=C3=B6rg wrote: > BTW, how do people here feel about adding more documentation strings to > stuff from EXT? M-x slime-apropos shows a lot of symbols, but a really > small number of them have docstrings. When they do, I quite appreciate it. I think that doc strings with just 1 to 3 lines of text are an obsolete concept. It doesn't convey enough information. Better use URLs into the ANSI CL doc or into clisp's impnotes.html. So that SLIME can then mark them clickable. Bruno |
|
From: Bruno H. <br...@cl...> - 2005-06-13 18:05:52
|
J=C3=B6rg wrote: > Dan Cohen wonders: > >Is there some reason these do not execute only once? > 2. Yes, indeed, why not?! > Then I'd have a better feeling about recommending load-time-value for FFI > stuff in CLISP, since it's valuable for compiled code and would not be > stupid in interpreted code. If you want to avoid stupidly slow behaviour in the evaluator, i.e. guarantee that a form is executed only once, you can use the MEMOIZED macro, found in defs1.lisp. Bruno |
|
From: Bruno H. <br...@cl...> - 2005-06-13 18:35:56
|
A portable version of this MEMOIZED macro is available in http://www.cliki.net/memoize-form Bruno |