Re: (eval-when?)
- From: Peter Seibel <peter@xxxxxxxxxxxxxxx>
- Date: Tue, 02 Aug 2005 14:48:44 GMT
Artem Baguinski <artm@xxxxx> writes:
> Dear Lispniks
>
> I am a bit confused about compile/load/execute time evaluation.
>
> Say, I have a package and i have some constants defined there with
> (defconstant ...)
>
> If now I issue M-x slime-compile-and-load-file command I get warnings
> about the constants being redefined (and even am thrown in a
> debugger).
>
> I gather it's because when I compiled the file the defconstant forms
> where already evealuated and when the lisp loads the file it has to
> evaluate them again. but I don't understand why it happens like
> that. I thought compiling file just creates the compiled version of my
> .lisp file?
That's true. But slime-compile-and-load-file, not suprisingly also
loads the file.
> on the other hand, i also used a loop to generate some of the
> constants and give them values, something like:
>
> (do ((n 0 (+ 1 n))
> (note-list '((B# C) (C# Db) (D)
> (D# Eb) (E Fb) (E# F)
> (F# Gb) (G) (G# Ab)
> (A) (A# Bb) (B Cb)) (rest note-list)))
> ((null note-list) nil)
> (mapc #'(lambda (alias)
> (eval `(defconstant ,alias ,n)))
> (car note-list)))
>
> and other code depends on the generated constants:
>
> (defconstant +standard-tuning+
> (list E B G D A E)
So this is asking for undefined behavior since if you evaluate this
form twice the (list ...) form will evaluate to two different,
i.e. non EQL, values. I'd probably use DEFPARAMETER for this.
> Now I can't compile the file because on compile time the constants E
> B G ... aren't generated yet. I feel like I have to use eval-when
> form but i don't really understand the rules. Also my constant
> generation uses eval form and I keep hearing that it's something to
> avoid.
>
> Where can I read an explanation about these different "situation"
> (compile time, load time, execute) and how to use eval-when? Something
> more newbie friendly then HyperSpec (which works for me in most cases,
> but not always).
I like to think the explanation in the section EVAL-WHEN in
<http://www.gigamonkeys.com/book/the-special-operators.html>
is pretty understandable. But I don't think EVAL-WHEN is really the
solution to this particular problem.
> Or feel free to say: all that you're doing is wrong and you have to do
> it like this (or like that).
Okay. I'd do it something like this:
(defmacro define-notes ((start) &body names)
`(progn
,@(loop for names in names
for i from start nconc
(loop for n in names collect `(defconstant ,n ,i)))))
(define-notes (0)
(B# C) (C# Db) (D) (D# Eb) (E Fb) (E# F) (F# Gb) (G) (G# Ab) (A) (A# Bb) (B Cb))
You may still get warnings about redefining constants if you eval the
DEFINE-NOTES form and then later compile and load the whole file. But
if you do you can ignore them since the values of your constants are
in fact the same (i.e. EQL). Certainly you should not end up in the
debugger.
-Peter
--
Peter Seibel * peter@xxxxxxxxxxxxxxx
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/
.
- Follow-Ups:
- Re: (eval-when?)
- From: Artem Baguinski
- Re: (eval-when?)
- References:
- (eval-when?)
- From: Artem Baguinski
- (eval-when?)
- Prev by Date: Re: (eval-when?)
- Next by Date: Re: (eval-when?)
- Previous by thread: Re: (eval-when?)
- Next by thread: Re: (eval-when?)
- Index(es):
Relevant Pages
|
|