From: Alex Mizrahi
Subject: defconstant in SBCL
Date: 
Message-ID: <48078eba$0$90265$14726298@news.sunsite.dk>
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 

From: Thomas A. Russ
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <ymiwsmwcgps.fsf@blackcat.isi.edu>
"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
From: Barry Margolin
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <barmar-23B8C1.18413517042008@newsgroups.comcast.net>
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 ***
From: Alex Mizrahi
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <480854ce$0$90262$14726298@news.sunsite.dk>
 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. 
From: Barry Margolin
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <barmar-0A8ABD.08350718042008@newsgroups.comcast.net>
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 ***
From: Thomas A. Russ
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <ymi8wzbc7om.fsf@blackcat.isi.edu>
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
From: John Thingstad
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <op.t9s5apltut4oq5@pandora.alfanett.no>
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
From: Pascal J. Bourguignon
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <7c4p9zxny2.fsf@pbourguignon.anevia.com>
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__
From: Alex Mizrahi
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <4808b11d$0$90275$14726298@news.sunsite.dk>
 ??>> 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? 
From: Barry Margolin
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <barmar-8FB021.01243221042008@newsgroups.comcast.net>
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 ***
From: Alex Mizrahi
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <4815dd43$0$90271$14726298@news.sunsite.dk>
 ??>> "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. 
From: Tim Bradshaw
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <3b36429f-1f7e-41e2-ab88-50946efb7319@t12g2000prg.googlegroups.com>
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
From: Pascal J. Bourguignon
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <7cy777ux7b.fsf@pbourguignon.anevia.com>
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__
From: Tim Bradshaw
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <a30b7bc8-2b3b-4b9e-94a9-74dfc503b802@a9g2000prl.googlegroups.com>
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.
From: Russell McManus
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <874p9vnrl3.fsf@thelonious.cl-user.org>
···@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
From: Kent M Pitman
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <uy776iusr.fsf@nhplace.com>
···@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.
From: Pascal J. Bourguignon
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <7cwsmvy0qg.fsf@pbourguignon.anevia.com>
"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__
From: Alex Mizrahi
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <48086e07$0$90263$14726298@news.sunsite.dk>
 ??>> 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 
From: Pascal J. Bourguignon
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <7cskxjxx67.fsf@pbourguignon.anevia.com>
"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__
From: Thomas A. Russ
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <ymi4p9zc7fj.fsf@blackcat.isi.edu>
···@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
From: Kent M Pitman
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <uk5iupspe.fsf@nhplace.com>
···@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.
From: Pascal Bourguignon
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <871w52swek.fsf@hubble.informatimago.com>
···@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.
From: Frode Vatvedt Fjeld
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <2hfxtjlelx.fsf@vserver.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.

-- 
Frode Vatvedt Fjeld
From: John Thingstad
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <op.t9szs9zout4oq5@pandora.alfanett.no>
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
From: Tim Bradshaw
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <a68be816-9d28-472a-b6d0-81d668be5611@8g2000hse.googlegroups.com>
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+)
From: Alex Mizrahi
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <480865d6$0$90267$14726298@news.sunsite.dk>
 ??>> 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 
From: Thomas A. Russ
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <ymiej8z6q8z.fsf@blackcat.isi.edu>
"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
From: Alex Mizrahi
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <4815db79$0$90262$14726298@news.sunsite.dk>
 ??>> 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.
From: ··············@gmail.com
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <ae914cf7-7fd4-42cb-902c-2d7fb09eba31@m73g2000hsh.googlegroups.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

if you want a practical answer, then look at define-constant in
alexandria, or (def (constant :test 'string=) +foo+ "bar) in cl-def

- attila
From: Pascal J. Bourguignon
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <7clk3bzj9h.fsf@pbourguignon.anevia.com>
"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__
From: John Thingstad
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <op.t9sy5zshut4oq5@pandora.alfanett.no>
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
From: Alex Mizrahi
Subject: Re: defconstant in SBCL
Date: 
Message-ID: <48087f8f$0$90274$14726298@news.sunsite.dk>
 ??>> "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..