http://www.sbcl.org/manual/Defining-Constants.html
(defconstant +foo+ "bar")
does not work in SBCL:
----
ANSI says that doing defconstant of the same symbol more than once is
undefined unless the new value is eql to the old value. Conforming to this
specification is a nuisance when the "constant" value is only constant under
some weaker test like string= or equal.
...
Many implementations of Common Lisp try to help the programmer around this
annoyance by silently accepting the undefined code and trying to do what the
programmer probably meant.
SBCL instead treats the undefined behavior as an error.
----
i wonder, is it so damn hard to make it more forgiving (i.e. testing via
EQUAL rather than EQL), or SBCL developers find it funny to annoy people
with such bullshit?
or there is some deep philosophy in popping up a message ``do you rreally
want to change constant "bar" to "bar"?''?
p.s. searching in google i've found some workarounds proposed, but they are
so ugly that it is tempting to just write "defvar" and forget about
defconstant.
but i was not able to find reasoning behind this choice
"Alex Mizrahi" <········@users.sourceforge.net> writes:
> (defconstant +foo+ "bar")
>
> does not work in SBCL:
>
> ----
> ANSI says that doing defconstant of the same symbol more than once is
> undefined unless the new value is eql to the old value. Conforming to this
> specification is a nuisance when the "constant" value is only constant under
> some weaker test like string= or equal.
> ----
>
> i wonder, is it so damn hard to make it more forgiving (i.e. testing via
> EQUAL rather than EQL), or SBCL developers find it funny to annoy people
> with such bullshit?
I suppose an argument could be made for downgrading this to a warning.
The problem with testing using something other than EQL is that if the
programmer, thinking that a constant really was a constant, might want
to exploit that fact by using EQL to do his own testing. But if the
object identity changes because of a redefinition, the code would
break. I suspect that that is what the SBCL implementers were worried
about.
> p.s. searching in google i've found some workarounds proposed, but they are
> so ugly that it is tempting to just write "defvar" and forget about
> defconstant.
> but i was not able to find reasoning behind this choice
This really goes to the issue of object identity and the standard
methods for handling constants like strings in compiled code. One
typical implementation technique would be to allocate immutable space
somewhere and then use that address. This will then work fine for EQL
testing unless a new object appears whose address will now be used.
Depending on details of the implementation, it might not be safe and
could cause code to malfunction.
--
Thomas A. Russ, USC/Information Sciences Institute
In article <···············@blackcat.isi.edu>,
···@sevak.isi.edu (Thomas A. Russ) wrote:
> "Alex Mizrahi" <········@users.sourceforge.net> writes:
>
> > (defconstant +foo+ "bar")
> >
> > does not work in SBCL:
> >
> > ----
> > ANSI says that doing defconstant of the same symbol more than once is
> > undefined unless the new value is eql to the old value. Conforming to this
> > specification is a nuisance when the "constant" value is only constant
> > under
> > some weaker test like string= or equal.
> > ----
> >
> > i wonder, is it so damn hard to make it more forgiving (i.e. testing via
> > EQUAL rather than EQL), or SBCL developers find it funny to annoy people
> > with such bullshit?
>
> I suppose an argument could be made for downgrading this to a warning.
> The problem with testing using something other than EQL is that if the
> programmer, thinking that a constant really was a constant, might want
> to exploit that fact by using EQL to do his own testing. But if the
> object identity changes because of a redefinition, the code would
> break. I suspect that that is what the SBCL implementers were worried
> about.
The point that the OP may be missing is that DEFCONSTANT also authorizes
the compiler to open-code references to the constant. So if a function
contains
(if (eql thing +foo+) ...)
this could be compiled with +foo+ replaced with a reference to the
original "bar" string itself. If you re-evaluate the DEFCONSTANT, but
don't recompile this function, the function will still be comparing with
the old "bar" string, rather than the new one.
Or maybe what he really wants is for DEFCONSTANT to be a no-op if the
new value is EQUAL to the existing value, so the redefinition doesn't
actually occur. The notion of "similar as constant" was developed
fairly late in the CL standardization process; perhaps if it had been
around in the days of the original design, they might have used it for
this.
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
BM> The point that the OP may be missing is that DEFCONSTANT also
BM> authorizes the compiler to open-code references to the constant.
defconstant authorizes compiler to open-code references to strings, but
compiler bans programmer from using defconstant with strings.
if this is causing problems, compiler could just disable optimizations if
value of defconstant does not look correct for him, making it work as if it
was defvar.
so it could be doing a bit suboptimal, but there will be less headache
porting code from other implementations.
so, SBCL protects rights of compiler to do aggressive optimizations, but
wants programmer to explicitly allow it to do so.
i find this reasoning a bit strange..
BM> Or maybe what he really wants is for DEFCONSTANT to be a no-op if the
BM> new value is EQUAL to the existing value, so the redefinition doesn't
BM> actually occur.
yep, this seems to be much better solution, as for me -- it is fine
according to the spec, and is extremely unlikely to yield any problems.
another solution would be to "intern" strings and other literals when
reading them from FASL files (and probably normal files too), so they will
be actually EQ to existing ones -- so problem with defconstant wouldn't even
exist.
In article <·························@news.sunsite.dk>,
"Alex Mizrahi" <········@users.sourceforge.net> wrote:
> another solution would be to "intern" strings and other literals when
> reading them from FASL files (and probably normal files too), so they will
> be actually EQ to existing ones -- so problem with defconstant wouldn't even
> exist.
So you would have:
(defconstant +foo+ "abc")
(defconstant +bar+ "abc")
(eql +foo+ +bar+) => T
?
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Barry Margolin <······@alum.mit.edu> writes:
> In article <·························@news.sunsite.dk>,
> "Alex Mizrahi" <········@users.sourceforge.net> wrote:
>
> > another solution would be to "intern" strings and other literals when
> > reading them from FASL files (and probably normal files too), so they will
> > be actually EQ to existing ones -- so problem with defconstant wouldn't even
> > exist.
>
> So you would have:
>
> (defconstant +foo+ "abc")
> (defconstant +bar+ "abc")
> (eql +foo+ +bar+) => T
I would think that under the current standard, either T or NIL would be
conforming answers. The compiler is allowed to, but not required to,
coalesce literal constants. So I could see either answer being allowed
-- which of course means that in portable code one could not rely on the
answer.
--
Thomas A. Russ, USC/Information Sciences Institute
P� Fri, 18 Apr 2008 14:35:07 +0200, skrev Barry Margolin
<······@alum.mit.edu>:
> In article <·························@news.sunsite.dk>,
> "Alex Mizrahi" <········@users.sourceforge.net> wrote:
>
>> another solution would be to "intern" strings and other literals when
>> reading them from FASL files (and probably normal files too), so they
>> will
>> be actually EQ to existing ones -- so problem with defconstant wouldn't
>> even
>> exist.
>
> So you would have:
>
> (defconstant +foo+ "abc")
> (defconstant +bar+ "abc")
> (eql +foo+ +bar+) => T
>
> ?
>
equal sure. eql no
But this is pretty basic Lisp.
--------------
John Thingstad
Barry Margolin <······@alum.mit.edu> writes:
> In article <·························@news.sunsite.dk>,
> "Alex Mizrahi" <········@users.sourceforge.net> wrote:
>
>> another solution would be to "intern" strings and other literals when
>> reading them from FASL files (and probably normal files too), so they will
>> be actually EQ to existing ones -- so problem with defconstant wouldn't even
>> exist.
>
> So you would have:
>
> (defconstant +foo+ "abc")
> (defconstant +bar+ "abc")
> (eql +foo+ +bar+) => T
>
> ?
I see nothing wrong in that.
You can still use defparameter if you want (eql *foo* *bar*) --> NIL
--
__Pascal Bourguignon__
??>> another solution would be to "intern" strings and other literals when
??>> reading them from FASL files (and probably normal files too), so they
??>> will be actually EQ to existing ones -- so problem with defconstant
??>> wouldn't even exist.
BM> So you would have:
BM> (defconstant +foo+ "abc")
BM> (defconstant +bar+ "abc")
BM> (eql +foo+ +bar+) => T
why not? does specification say that each string literal MUST be different
string object?
"dumb" languages like C and Java coalesce equal string literals, for Java
literal string interning is even in standard -- can't Lisp also use same
optimization?
In article <·························@news.sunsite.dk>,
"Alex Mizrahi" <········@users.sourceforge.net> wrote:
> ??>> another solution would be to "intern" strings and other literals when
> ??>> reading them from FASL files (and probably normal files too), so they
> ??>> will be actually EQ to existing ones -- so problem with defconstant
> ??>> wouldn't even exist.
>
> BM> So you would have:
>
> BM> (defconstant +foo+ "abc")
> BM> (defconstant +bar+ "abc")
> BM> (eql +foo+ +bar+) => T
>
> why not? does specification say that each string literal MUST be different
> string object?
The reader is required to create distinct strings. The file compiler is
allowed to coalesce similar constants like this within a single source
file.
> "dumb" languages like C and Java coalesce equal string literals, for Java
> literal string interning is even in standard -- can't Lisp also use same
> optimization?
Do any C implementations actually coalesce across different compilation
units?
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
??>> "dumb" languages like C and Java coalesce equal string literals, for
??>> Java literal string interning is even in standard -- can't Lisp also
??>> use same optimization?
BM> Do any C implementations actually coalesce across different compilation
BM> units?
I think they do, because actual coalescing is performed by a linker rather
than
by a compiler, and linker doesn't have to honour compilation unit
boundaries.
On Apr 18, 3:32 pm, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>
> "dumb" languages like C and Java coalesce equal string literals, for Java
> literal string interning is even in standard -- can't Lisp also use same
> optimization?
The underlying point here, which I think has not been explicitly
brought out is that these languages are in the fortunate situation of
having a small, finite and completely known set of types which can
occur as literals in code: usually numbers and strings. That makes it
pretty easy for the compiler to deal with interning and so on.
Essentially any Lisp type can occur as a literal. This makes life a
whole lot harder for the compiler.
--tim
Tim Bradshaw <··········@tfeb.org> writes:
> On Apr 18, 3:32 pm, "Alex Mizrahi" <········@users.sourceforge.net>
> wrote:
>
>>
>> "dumb" languages like C and Java coalesce equal string literals, for Java
>> literal string interning is even in standard -- can't Lisp also use same
>> optimization?
>
> The underlying point here, which I think has not been explicitly
> brought out is that these languages are in the fortunate situation of
> having a small, finite and completely known set of types which can
> occur as literals in code: usually numbers and strings. That makes it
> pretty easy for the compiler to deal with interning and so on.
>
> Essentially any Lisp type can occur as a literal. This makes life a
> whole lot harder for the compiler.
Well, already it is restricted to about what is printable readably, no?
One cannot file compile (defparameter *f* '#.(lambda (x) (1+ x)))
C/USER[2]> (load"fun-file-comp.lisp")
;; Loading file fun-file-comp.lisp ...
;; Loaded file fun-file-comp.lisp
T
C/USER[3]> (funcall *f* 2)
3
C/USER[4]> (compile-file"fun-file-comp.lisp")
;; Compiling file /home/pjb/spool/pjb/lisp/fun-file-comp.lisp ...
*** - PRINT: Despite *PRINT-READABLY*, #<FUNCTION :LAMBDA (X) (1+ X)> cannot
be printed readably.
The following restarts are available:
ABORT :R1 ABORT
C/Break 1 USER[5]> :q
0 errors, 0 warnings
C/USER[6]> (cat "fun-file-comp.lisp")
(defparameter *f* '#.(lambda (x) (1+ x)))
C/USER[7]>
--
__Pascal Bourguignon__
On Apr 21, 2:58 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
>
> Well, already it is restricted to about what is printable readably, no?
I don't see why it should be, though I may be wrong.
···@informatimago.com (Pascal J. Bourguignon) writes:
>> Essentially any Lisp type can occur as a literal. This makes life a
>> whole lot harder for the compiler.
>
> Well, already it is restricted to about what is printable readably, no?
> One cannot file compile (defparameter *f* '#.(lambda (x) (1+ x)))
I think it is more accurate to say that it is restricted to datatypes
for which a MAKE-LOAD-FORM method is defined.
-russ
···@informatimago.com (Pascal J. Bourguignon) writes:
> Tim Bradshaw <··········@tfeb.org> writes:
...
> > Essentially any Lisp type can occur as a literal. This makes life a
> > whole lot harder for the compiler.
Strictly, it makes life harder for the printer and/or fasdumper. The
compiler is not impeded at all.
> Well, already it is restricted to about what is printable readably, no?
> One cannot file compile (defparameter *f* '#.(lambda (x) (1+ x)))
I'm not sure what the context of this question in this thread (which
I've not been reading) is. But: Not all code has to be file compiled.
The restrictions on file compiling are different than the restrictions
on compiling.
"Alex Mizrahi" <········@users.sourceforge.net> writes:
> another solution would be to "intern" strings and other literals when
> reading them from FASL files (and probably normal files too), so they will
> be actually EQ to existing ones -- so problem with defconstant wouldn't even
> exist.
You would have to distinguish literal strings from normal strings.
"aaa" and "aaa"
vs.
"aaa" and #.(make-string 3 :initial-element #\a)
#(1 2 3) and #(1 2 3)
vs.
#(1 2 3) and #.(vector 1 2 3)
--
__Pascal Bourguignon__
??>> another solution would be to "intern" strings and other literals when
??>> reading them from FASL files (and probably normal files too), so they
??>> will be actually EQ to existing ones -- so problem with defconstant
??>> wouldn't even exist.
PJB> You would have to distinguish literal strings from normal strings.
PJB> "aaa" and "aaa"
PJB> vs.
PJB> "aaa" and #.(make-string 3 :initial-element #\a)
do you mean that if string is made with #.(make-string 3 :initial-element
#\a) it's allowed to be modified in runtime then?
well, even if it's such, i see no problems with this -- implementation could
just have two distinct type-tags: string and literal-string.
literal-string type will not be revealed to user, but it can be serialized
with this distinct type tag and interned on reading.
btw, in Java "All literal strings and string-valued constant expressions are
interned. ". they don't have #., though
"Alex Mizrahi" <········@users.sourceforge.net> writes:
> ??>> another solution would be to "intern" strings and other literals when
> ??>> reading them from FASL files (and probably normal files too), so they
> ??>> will be actually EQ to existing ones -- so problem with defconstant
> ??>> wouldn't even exist.
>
> PJB> You would have to distinguish literal strings from normal strings.
>
> PJB> "aaa" and "aaa"
> PJB> vs.
> PJB> "aaa" and #.(make-string 3 :initial-element #\a)
>
> do you mean that if string is made with #.(make-string 3 :initial-element
> #\a) it's allowed to be modified in runtime then?
Yes.
> well, even if it's such, i see no problems with this -- implementation could
> just have two distinct type-tags: string and literal-string.
> literal-string type will not be revealed to user, but it can be serialized
> with this distinct type tag and interned on reading.
To let reader macros decide on what's literal and what's not, you'd
have to define a CL primitive to designate such literal values.
Please write a CDR ;-)
> btw, in Java "All literal strings and string-valued constant expressions are
> interned. ". they don't have #., though
--
__Pascal Bourguignon__
···@informatimago.com (Pascal J. Bourguignon) writes:
> "Alex Mizrahi" <········@users.sourceforge.net> writes:
>
> > ??>> another solution would be to "intern" strings and other literals when
> > ??>> reading them from FASL files (and probably normal files too), so they
> > ??>> will be actually EQ to existing ones -- so problem with defconstant
> > ??>> wouldn't even exist.
> >
> > PJB> You would have to distinguish literal strings from normal strings.
> >
> > PJB> "aaa" and "aaa"
> > PJB> vs.
> > PJB> "aaa" and #.(make-string 3 :initial-element #\a)
> >
> > do you mean that if string is made with #.(make-string 3 :initial-element
> > #\a) it's allowed to be modified in runtime then?
>
> Yes.
Well, I would be surprised by that. Absent some marking produced by the
reader, I don't see any way that the compiler could distinguish between
"aaa" and #.(make-string 3 :initial-element #\a), since they would both
be strings when the compiler saw them.
I think you have the same issue with '(a b c) and #.(list 'a 'b 'c),
where I don't think you can legitimately modify either list. To have a
string or list that it is safe to mutate, you would need to execute the
MAKE-STRING or LIST function at run time, not read time.
--
Thomas A. Russ, USC/Information Sciences Institute
···@sevak.isi.edu (Thomas A. Russ) writes:
> I think you have the same issue with '(a b c) and #.(list 'a 'b 'c),
> where I don't think you can legitimately modify either list.
Heh. Note that those are not the same situation.
'#.(list 'a 'b 'c)
would be more analogous.
I know you know this. But that's for others reading on. Hopefully it
won't detract from your main point.
> To have a string or list that it is safe to mutate, you would need to
> execute the MAKE-STRING or LIST function at run time
Well, at load time or later. So
(load-time-value (list 'a 'b 'c) nil)
is ok and creates a kind of constant but one whose identity you can rely
on because you know it's created in the load-time environment by code you
wrote, and you know there's no permission given to the implementation to
do coalescing.
> not read time.
Nor any time that is prior to semantic processing, such as compile time,
but which includes read time. For instance, not in a macro expander
either. That is,
(macrolet ((abc () (list 'quote (list 'a 'b 'c))))
(abc))
is also bad.
In other words, it's not about read nor read-time. It's about the
larger time window in which the call READ done by #. occurs.
···@sevak.isi.edu (Thomas A. Russ) writes:
> ···@informatimago.com (Pascal J. Bourguignon) writes:
>
>> "Alex Mizrahi" <········@users.sourceforge.net> writes:
>>
>> > ??>> another solution would be to "intern" strings and other literals when
>> > ??>> reading them from FASL files (and probably normal files too), so they
>> > ??>> will be actually EQ to existing ones -- so problem with defconstant
>> > ??>> wouldn't even exist.
>> >
>> > PJB> You would have to distinguish literal strings from normal strings.
>> >
>> > PJB> "aaa" and "aaa"
>> > PJB> vs.
>> > PJB> "aaa" and #.(make-string 3 :initial-element #\a)
>> >
>> > do you mean that if string is made with #.(make-string 3 :initial-element
>> > #\a) it's allowed to be modified in runtime then?
>>
>> Yes.
>
> Well, I would be surprised by that. Absent some marking produced by the
> reader, I don't see any way that the compiler could distinguish between
> "aaa" and #.(make-string 3 :initial-element #\a), since they would both
> be strings when the compiler saw them.
>
> I think you have the same issue with '(a b c) and #.(list 'a 'b 'c),
> where I don't think you can legitimately modify either list. To have a
> string or list that it is safe to mutate, you would need to execute the
> MAKE-STRING or LIST function at run time, not read time.
To let reader macros decide on what's literal and what's not, you'd
have to define a CL primitive to designate such literal values.
Please write a CDR ;-)
--
__Pascal Bourguignon__ http://www.informatimago.com/
HANDLE WITH EXTREME CARE: This product contains minute electrically
charged particles moving at velocities in excess of five hundred
million miles per hour.
Barry Margolin <······@alum.mit.edu> writes:
> The point that the OP may be missing is that DEFCONSTANT also
> authorizes the compiler to open-code references to the
> constant. [..]
Isn't this somewhat akin to the issue of whether type declarations are
promises made by the programmer (and when broken, invalidates all the
compiler's promises), or assertions that the compiler should enforce?
Personally, I find it most useful to think of defconstant as "it's OK
for the compiler to inline references to this variable, and I
understand I probably need to recompile stuff if I should change
it". I'm similarly annoyed by these defconstant errors as I would have
been if reading "foo::bar" had given errors about "illegal use of
private symbol". It seems to me to go against the general attitude of
Lisp to trust (and aid, i.e. warn) the programmer over the
compiler/run-time.
--
Frode Vatvedt Fjeld
P� Fri, 18 Apr 2008 11:03:06 +0200, skrev Frode Vatvedt Fjeld
<······@cs.uit.no>:
> Barry Margolin <······@alum.mit.edu> writes:
>
>> The point that the OP may be missing is that DEFCONSTANT also
>> authorizes the compiler to open-code references to the
>> constant. [..]
>
> Isn't this somewhat akin to the issue of whether type declarations are
> promises made by the programmer (and when broken, invalidates all the
> compiler's promises), or assertions that the compiler should enforce?
>
> Personally, I find it most useful to think of defconstant as "it's OK
> for the compiler to inline references to this variable, and I
> understand I probably need to recompile stuff if I should change
> it". I'm similarly annoyed by these defconstant errors as I would have
> been if reading "foo::bar" had given errors about "illegal use of
> private symbol". It seems to me to go against the general attitude of
> Lisp to trust (and aid, i.e. warn) the programmer over the
> compiler/run-time.
>
Agreed. They are on the same level as declaim inline. More of a
optimisation than a declaration.
Usually a defparameter is what you what. Only use defconstant if you are
REALLY sure it is forever constant.
For instance it causes problems with the 'case' family of macros where you
need a readline expansion to make it work. (You also need a 'eval-when' in
the declaration.)
--------------
John Thingstad
On Apr 17, 6:53 pm, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
> i wonder, is it so damn hard to make it more forgiving (i.e. testing via
> EQUAL rather than EQL), or SBCL developers find it funny to annoy people
> with such bullshit?
"Making it more forgiving" means "causing programs to give the wrong
answer" such as:
(defconstant +foo+ "bar")
...
(defun spot (x)
...
(eql x +bar+)
...
)
...
(spot +foo+)
??>> i wonder, is it so damn hard to make it more forgiving (i.e. testing
??>> via EQUAL rather than EQL), or SBCL developers find it funny to annoy
??>> people with such bullshit?
TB> "Making it more forgiving" means "causing programs to give the wrong
TB> answer" such as:
no, it means "causing _wrong_ programs to give the wrong anwer" -- as these
programs do not take into account how constant strings works, and are
comparing strings via EQL, which is wrong.
i see couple of options for resolving this problem:
1. just ignore these programs.
2. give a warning on redefinition, so wrong programs writers will know they
are wrong.
3. disable compiler optimizations for such constants, so it will work just
as if it was defvar
4. intern all strings and other literals, whereever possible, so making same
literal strings really EQL
(and also saving some amount of memory at cost of some memory cycles)
5. keep old value when it is EQUAL to new one.
i do not see any significant problems with any of these approaches, so it's
really puzzling me why SBCL implements the most annoying way
"Alex Mizrahi" <········@users.sourceforge.net> writes:
> no, it means "causing _wrong_ programs to give the wrong anwer" -- as these
> programs do not take into account how constant strings works, and are
> comparing strings via EQL, which is wrong.
Not for constant strings. That is the entire point.
> i see couple of options for resolving this problem:
>
> 3. disable compiler optimizations for such constants, so it will work just
> as if it was defvar
Well, the problem with this is that there could be code that is already
compiled using those compiler optimizations. So changing the handling
for future code won't fix the already-compiled code.
Changing a constant (of any type, and even to something not EQUAL) could
be expected to work for any newly compiled code. But you are still left
with the problem of existing code compiled with the old value.
--
Thomas A. Russ, USC/Information Sciences Institute
??>> no, it means "causing _wrong_ programs to give the wrong anwer" -- as
??>> these programs do not take into account how constant strings works,
??>> and are comparing strings via EQL, which is wrong.
TAR> Not for constant strings. That is the entire point.
EQL might not work right both on constant and literal strings, because
constant ones could be inlined as if they were literal, and literal string
are not required to be EQ (some people here even thought that they MUST not
be EQ).
some programmers might think that constants behave like variables, so EQL
should work on them, but they are plainly wrong -- they should read
documentation.
so does it make sense to penaltize (with weird error messages) one
programmer for what _another_ programmer _might_ erroneously think? that is
the entire point.
??>> 3. disable compiler optimizations for such constants, so it will work
??>> just as if it was defvar
TAR> Well, the problem with this is that there could be code that is
TAR> already compiled using those compiler optimizations. So changing the
TAR> handling for future code won't fix the already-compiled code.
here by optimization we mean inlining strings.
if this inlining will be disabled, there will be no problems with any code.
TAR> Changing a constant (of any type, and even to something not EQUAL)
TAR> could be expected to work for any newly compiled code.
_changing_ a constant is completely other question.
i have simple single declaration in a file:
(defconstant +foo+ "bar")
and i want it to work when i do (load (compile-file "foo.lisp")), without
any magic passes.
this is bare minimum of sanity i'm expecting.
> p.s. searching in google i've found some workarounds proposed, but they are
> so ugly that it is tempting to just write "defvar" and forget about
> defconstant.
> but i was not able to find reasoning behind this choice
if you want a practical answer, then look at define-constant in
alexandria, or (def (constant :test 'string=) +foo+ "bar) in cl-def
- attila
"Alex Mizrahi" <········@users.sourceforge.net> writes:
> http://www.sbcl.org/manual/Defining-Constants.html
>
> (defconstant +foo+ "bar")
>
> does not work in SBCL:
>
> ----
> ANSI says that doing defconstant of the same symbol more than once is
> undefined unless the new value is eql to the old value. Conforming to this
> specification is a nuisance when the "constant" value is only constant under
> some weaker test like string= or equal.
> ...
>
>
> Many implementations of Common Lisp try to help the programmer around this
> annoyance by silently accepting the undefined code and trying to do what the
> programmer probably meant.
>
> SBCL instead treats the undefined behavior as an error.
> ----
Yes, that's what "undefined" means. Anything can happen is you try to
run the undefined form.
Perhaps it would be nice to have a (declaim (optimize (portability 3)))
that would signal an error on all the undefined or implementation
dependant stuff. I would use it.
> i wonder, is it so damn hard to make it more forgiving (i.e. testing via
> EQUAL rather than EQL), or SBCL developers find it funny to annoy people
> with such bullshit?
>
> or there is some deep philosophy in popping up a message ``do you rreally
> want to change constant "bar" to "bar"?''?
Barry said why.
> p.s. searching in google i've found some workarounds proposed, but they are
> so ugly that it is tempting to just write "defvar" and forget about
> defconstant.
> but i was not able to find reasoning behind this choice
"Constants aren't, variables won't.", old CS saying...
--
__Pascal Bourguignon__
P� Fri, 18 Apr 2008 09:58:50 +0200, skrev Pascal J. Bourguignon
<···@informatimago.com>:
>
>> p.s. searching in google i've found some workarounds proposed, but they
>> are
>> so ugly that it is tempting to just write "defvar" and forget about
>> defconstant.
>> but i was not able to find reasoning behind this choice
>
> "Constants aren't, variables won't.", old CS saying...
>
There is a sb-ext:muffle-warning which I believe can be used.
Given all the 'style' warnings you might want to look into it.
(I don't agree that defgeneric should be declared for all methods for
instance.)
--------------
John Thingstad
??>> "Constants aren't, variables won't.", old CS saying...
??>>
JT> There is a sb-ext:muffle-warning which I believe can be used.
SBCL signals an error, it is not a warning!
it would be perfectly fine if it was a warning..