In article <3131171314435...@naggum.no>, Erik Naggum <e...@naggum.no> writes:
> * mike...@mikemac.com (Mike McDonald) >| So the (hyper) spec uses "constant object" for immutable things. >| defconstant doesn't signify that the object is constant, only that using >| the binding of the symbol has to be equivilent to using the literal form.
> and? what part of "literal" don't you get?
> #:Erik
The part where you're adding the immutable to it. At least in the hyper spec's glossary, which you quoted, it does NOT say literal objects are immutable. A literal object is that one, unique object. It says nothing about the status of its contents. In their example of '("two"), it's the cons cell that is the literal object being refered to, not the string "two" or the NIL on the end. Granted, in this example, you'd confuse most people by replaca-ing the list, but I don't see anything in this definition that it says you can't.
In every case where I've seen (defconstant *foo* (make-array ...)) used, what was intended that *foo* would always point to the same array, not that the array's contents would always be the same. But heck, with MCL's interpretation that it can be a different array in every compiled file, DEFCONSTANT doesn't mean anything useable.
mike...@mikemac.com (Mike McDonald) writes: > The part where you're adding the immutable to it. At least in the hyper > spec's glossary, which you quoted, it does NOT say literal objects are > immutable. A literal object is that one, unique object. It says nothing about > the status of its contents. In their example of '("two"), it's the cons cell > that is the literal object being refered to, not the string "two" or the NIL > on the end. Granted, in this example, you'd confuse most people by replaca-ing > the list, but I don't see anything in this definition that it says you can't.
I think that a quoted list like that *is* immutable in fact. I had a whole issue recently to do with students getting confused about this and I and others did some reading of the spec and that's my current opinion on its reading (conveniantly, because that's what I though anyway ...). It is certainly a sensible restriction that it *should* be immutable because it allows lots of nice optimisations and forbids various hideous programming styles (altering quoted structure appearing in the text of code).
I am surprised that the value of something defined with DEFCONSTANT is immutable, though that seems to be a plausible reading of the spec (and I can kind of see why it should be like that, because of all the issues with compileload/runtime sameness. I think it's a misfeature though, because allowing the values to be mutable is just so useful. I'd really like someone who understands all the issues better to explain this to me actually -- how hard would it be to make DEFCONSTANT do (what I think is) the right thing?
David B. Lamkins wrote: > Combining this with the final sentence (two conses never the same) of the > "same" glossary entry quoted above, I think I see how your example's > behavior is allowed: If I create a program containing the form > (defconstant *foo* '(())) > then I have failed to ensure that the initial value is the same at compile > time and load time. If the implementation evaluates the defconstant form at > both compile and load time, it will cons two different initial values.
> So, now for the $2^16 question: Have I interpreted this correctly?
Sorry, no.
The glitch in your analysis is that the constant list in your form is not constructed by evaluation. It is constructed once, by the reader. (That's what QUOTE means: Don't evaluate the subform. :-)
Now, the problem of capturing multiple non-eq versions of a constant arises only when the constant is captured in separately-compiled files. Lacking any persistent database in which to store constants, _if_ the file compiler choses to dereference a constant variable at compile time, there is no way for it to preserve equivalence. That is why the ACL compiler only dereferences constants like numbers and symbols.
The best CL idiom to deal with these things is to use LOAD-TIME-VALUE. Assuming that evaluating a global variable is slightly more expensive than retrieving a constant, the reference would be something like:
(read stream nil (load-time-value +eof+))
Now, what you'd really like is something like the following (untested, for reasons that will become clear):
Unfortunately, this possibility is specifically excluded by the ANS. It is illegal to define a global symbol macro on a symbol declared as a global variable. Perhaps this restriction was a mistake.
A smart compiler could still provide this service for you behind your back. It's something we might consider...
In article <36F7C5E0.B61ED...@elwood.com>, "Howard R. Stearns" <how...@elwood.com> writes:
> I stand corrected. As atonement, let me collect the relevent texts in > one place, demonstrating that the spec does suggest DEFCONSTANT > immutability, but that there is room for improvement. (A cynic might > think that I'm wryly admitting I'm wrong just to show that I really > believe the spec is wrong. A cynic might be right.)
> --- > There is some question as to whether the values produced by references > to DEFCONSTANT are to be treated as literal objects, and are therefore > immutable.
Where does it say that literal objects are immutable?
> Two sections indicate that they are to be immutable:
> 3.2.2.3 Semantic Constraints:
> All conforming programs must obey the following constraints: ... > Constant variables defined in the compilation environment must have > a similar value at run time. A reference to a constant variable in > source code is equivalent to a reference to a literal object that is > the value of the constant variable.
> "constant object" glossary entry
> an object that is constrained (e.g., by its context in a program or > by the source from which it was obtained) to be immutable. "A > literal object that has been processed by compile-file is a constant > object."
> Unfortunately, DEFCONSTANT has no direct references to either of these > entries. In fact, nothing related to DEFCONSTANT seems to reference > this "constant object" entry, which itself doesn't even say anything > about actually applying to DEFCONSTANT.
Because DEFCONSTANT doesn't deal with "constant objects"!
> Furthermore, some sections suggest suggest though ommision that the > value of a constant variable is not a constant object or constant > literal, and these sections should probably be ammended:
No it shouldn't! A constant variable is about how an object is bound to a variable, no more!
> DEFCONSTANT dictionary entry:
> The entry explains in detail the constraints on changing the values of > the constant variable produced by defconstant, when the value might be > computed, and discusses how the variable may not be bound. However, > it never says anything about the value being treated as a literal > object, or about references to internal structures of these values.
Because DEFCONSTANT is only concerned with the binding of the variable!
> Certain variables, called constant variables, are reserved as > "named constants." The consequences are undefined if an attempt is > made to assign a value to, or create a binding for a constant > variable, except that a `compatible' redefinition of a constant > variable using defconstant is permitted; see the macro defconstant.
> Note that nothing is said about immutability, nor is there any > reference to constant objects or literal objects.
> "constant variable" glossary entry:
> a variable, the value of which can never change; that is, a > keyword[1] or a named constant. ``The symbols t, nil, :direction, and > most-positive-fixnum are constant variables.''
> Nothing is said about immutability. One could argue either that a > value of a variable never changing means that the binding can't > change, or alterantively that the internal structure of the value > cannot be mutated. (There is also no reference to section > 3.1.2.1.1.3, which is a shame.)
> "named constant" glossary entry:
> a variable that is defined by Common Lisp, by the implementation, or > by user code (see the macro defconstant) to always yield the same > value when evaluated. "The value of a named constant may not be > changed by assignment or by binding."
> Again, nothing about immutability or treating the value as a literal > object. (Again, no reference to 3.1.2.1.1.3.)
Right! Because once again, constant variable and named constant are talking about the BINDING of a variable, not the object that is being bound.
> "literal" glossary entry:
> (of an object) referenced directly in a program rather than being > computed by the program; that is, appearing as data in a quote form, > or, if the object is a self-evaluating object, appearing as unquoted > data.
> This definition does not include references to a value defined by > DEFCONSTANT.
Nor does it say a literal is immutable!
> Ultimately, one wonders what is "the right thing." Certainly, one > want to allow compilers to treat the value of a constant variable as > some kind of compile-time literal so that partial evaluation can be > performed at compile time for forms involving references. It comes > down to a quesion of whether DEFCONSTANT constrains both > implementations to make sure that the value was similar at all times, > or just at certain times such as compile and load.
I've always avoided using DEFCONSTANT because you never were sure about what value some piece of code had squirreled away. Using DEFCONSTANT leads to (eql *foo* (some-function-that-always-returns-*foo*)) being able to return NIL too easily.
> In other words, we allow the compiler to freeze in the definitions at > compile time, while still allowing a function binding to change when > referenced in a different context. In the case of function bindings, > we're still talking about bindings, not internal structure. (It's > another can of worms as to whether there should be a way to turn of > the constantness of a defconstant BINDING.) The question here is > whether, in the case of DEFCONSTANT, we can allow internal structure > changes to be picked up at run time.
Since DEFCONSTANT, DEFVAR, and DEFPARAMETER are only dealing with bindings, why would anyone infer that they impose any constraints on modifying the insides of the bound objects? I always believed that if the spec didn't explicitly say something was immutable, then assumption was that it was mutable, especially if functions are provided to do the mutation. Heck, no place in the hyperspec does it say that MAKE-ARRAY returns a mutable array in the first place. Would it be "reasonable" then to allow implementations to only return immutable arrays?
> In any case, I think it's clear by now > that any code that relies on an implementation allowing mutations of > value of defconstant will be non-portable, at minimum.
I think any implementation that doesn't is broken.
>> The part where you're adding the immutable to it. At least in the hyper >> spec's glossary, which you quoted, it does NOT say literal objects are >> immutable. A literal object is that one, unique object. It says nothing about >> the status of its contents. In their example of '("two"), it's the cons cell >> that is the literal object being refered to, not the string "two" or the NIL >> on the end. Granted, in this example, you'd confuse most people by replaca-ing >> the list, but I don't see anything in this definition that it says you can't.
> I think that a quoted list like that *is* immutable in fact.
Could be (and probably shoould be although I've never seen an immutable cons cell before). But that's a separate issue from what a "literal" is.
> I am surprised that the value of something defined with DEFCONSTANT is > immutable, though that seems to be a plausible reading of the spec
Well you should be surprised since no one has been able to show that the spec says that.
> (and I can kind of see why it should be like that, because of all the > issues with compileload/runtime sameness.
That's a different issue. What it means is that if in one file I have
(defconstant *foo* (make-array 10))
(defun baz () (print (eql *foo* (bar))))
and in another file I have
(defun bar () *foo*)
then what gets printed out when BAZ is called can be either T or NIL. (Because the *foo* in BAR may have gotten the value from a different environment. Now, if you had used DEFVAR instead, it'd always print the expected T. Kind of counter intuitive that DEFVAR's are EQ but DEFCONSTANTs aren't necessarily.)
> how hard would it be to make > DEFCONSTANT do (what I think is) the right thing?
> --tim
I contend the spec already says it does work that way.
[Lots of interesting material dug up by Howard not included due to space considerations.]
As I see it, there are two issues coming up here. One is DEFCONSTANT immutability, and the other is DEFCONSTANT identity. Not having to preserve DEFCONSTANT across all the code that is written in an environment can have a nice efficiency benefit. However, I too find the notion that a constant may not be EQL across source files I write hard to deal with.
I find it useful to rethink the notion of environments and think of the role of DEFCONSTANT in those terms. Granted, this may not be realistic, but it makes a nice thought experiment for me.
Having environments as first class objects, implemented to behave in a manner analogous to packages, would be nice. In other words, I would like to be able to say (in-environment "FOO") at the start of my source file. I would like to be able to define an environment like a package, and be able to define inheritence across environments. Most importantly, I would like to be able to write my code knowing that this environment is going to be available when the code runs or compiles. I know that packages are supposed to provide much of this separation of data, but AFAIK they don't do much besides handling name conflicts. I am not proposing turning packges in to modules. Rather, I would like to see more of a commitment as to what data they will contain, and how that data will relate to the code that is executed within the scope of the package.
Incidentally, there is at least one existing system (Matlab) that provides similar "environments". Matlab has a global environment. The user interacts with the user environment which is distinct from the global environment, and any code that is loaded inherits from the user environemnt. Any references to the global environment have to be explicitly declared. I am fairly certain that it is possible to specify environments other than the global in which to look up forms and variables.
Let me add that I haven't thought this through all that much, and I am throwing it out as a possible topic of discussion, not a concrete proposal.
In my opinion, a Defconstant value should be immutable, so it can be placed in a read-only area, and thus can be shareable by multiple lisp images. What gain is there to allow mutability over a Defvar?
Is their some particular problem with having a DefGlobal which declares a variable global?
> I stand corrected. As atonement, let me collect the relevent texts in > one place, demonstrating that the spec does suggest DEFCONSTANT > immutability, but that there is room for improvement. (A cynic might > think that I'm wryly admitting I'm wrong just to show that I really > believe the spec is wrong. A cynic might be right.)
> --- > There is some question as to whether the values produced by references > to DEFCONSTANT are to be treated as literal objects, and are therefore > immutable.
> Two sections indicate that they are to be immutable:
> 3.2.2.3 Semantic Constraints:
> All conforming programs must obey the following constraints: ... > Constant variables defined in the compilation environment must have > a similar value at run time. A reference to a constant variable in > source code is equivalent to a reference to a literal object that is > the value of the constant variable.
> "constant object" glossary entry
> an object that is constrained (e.g., by its context in a program or > by the source from which it was obtained) to be immutable. "A > literal object that has been processed by compile-file is a constant > object."
> Unfortunately, DEFCONSTANT has no direct references to either of these > entries. In fact, nothing related to DEFCONSTANT seems to reference > this "constant object" entry, which itself doesn't even say anything > about actually applying to DEFCONSTANT.
> Furthermore, some sections suggest suggest though ommision that the > value of a constant variable is not a constant object or constant > literal, and these sections should probably be ammended:
> DEFCONSTANT dictionary entry:
> The entry explains in detail the constraints on changing the values of > the constant variable produced by defconstant, when the value might be > computed, and discusses how the variable may not be bound. However, > it never says anything about the value being treated as a literal > object, or about references to internal structures of these values.
> 3.1.2.1.1.3 Constant Variables:
> Certain variables, called constant variables, are reserved as > "named constants." The consequences are undefined if an attempt is > made to assign a value to, or create a binding for a constant > variable, except that a `compatible' redefinition of a constant > variable using defconstant is permitted; see the macro defconstant.
> Note that nothing is said about immutability, nor is there any > reference to constant objects or literal objects.
> "constant variable" glossary entry:
> a variable, the value of which can never change; that is, a > keyword[1] or a named constant. ``The symbols t, nil, :direction, and > most-positive-fixnum are constant variables.''
> Nothing is said about immutability. One could argue either that a > value of a variable never changing means that the binding can't > change, or alterantively that the internal structure of the value > cannot be mutated. (There is also no reference to section > 3.1.2.1.1.3, which is a shame.)
> "named constant" glossary entry:
> a variable that is defined by Common Lisp, by the implementation, or > by user code (see the macro defconstant) to always yield the same > value when evaluated. "The value of a named constant may not be > changed by assignment or by binding."
> Again, nothing about immutability or treating the value as a literal > object. (Again, no reference to 3.1.2.1.1.3.)
> 3.2.1 Compiler Terminology:
> The term literal object refers to a quoted object or a > self-evaluating object or an object that is a substructure of such > an object. A constant variable is not itself a literal object.
> Because this specifically refers to constant variables, but only in > the negative, this could easily be read as indicating that "the value > of a reference to a constant variable is not itself a literal object." > Apparently, the intention is instead to indicate that the conceptual > object called a constant variable (not its value) is not a literal > object. However, it is unusual for the spec to refer to the concept > of a variable as an object.
> "literal" glossary entry:
> (of an object) referenced directly in a program rather than being > computed by the program; that is, appearing as data in a quote form, > or, if the object is a self-evaluating object, appearing as unquoted > data.
> This definition does not include references to a value defined by > DEFCONSTANT.
> There is one other source of confusion. Sunil Mishra gives the > example that some implementations might treat the values of > DEFCONSTANT as compile-file literals, with references in different > files being "similar", but not identical. This can lead to confusion. > The "workaround" is to use DEFPARAMETER instead, which leads to the > embarrassing situation that a user might tend to think of the value of > a DEFPARAMETER as more "constant" (really more EQ) across files than > the value of a DEFCONSTANT. This confusion is furthered, as David > Lamkins points out, by generally understanding "similar" to mean EQL. > However, David also points out that the situation only comes up > through "programmer error" because it violates the original citation > from 3.2.2.3, above. (Any misinterpretatin of Sunil's and David's > statements is my fault, not theirs.)
> Ultimately, one wonders what is "the right thing." Certainly, one > want to allow compilers to treat the value of a constant variable as > some kind of compile-time literal so that partial evaluation can be > performed at compile time for forms involving references. It comes > down to a quesion of whether DEFCONSTANT constrains both > implementations to make sure that the value was similar at all times, > or just at certain times such as compile and load.
> For example, CL already has the issue of what happens when compile > time and run time definitions differ. Consider an expression like: > (FOO BAR)
> If FOO is an an inlinable reference to the function -, and bar is a > constant variable with value 1, then the compiler is justified in > treating the entire expression as the literal value -1. This is true > even if the user latter arranges for FOO to have a different function > definition when the above code is actually run. In fact, a different > reference to (FOO BAR) in a context in which FOO may not be inlined, > must actually call the run time definition of FOO, and might produce a > different result.
> In other words, we allow the compiler to freeze in the definitions at > compile time, while still allowing a function binding to change when > referenced in a different context. In the case of function bindings, > we're still talking about bindings, not internal structure. (It's > another can of worms as to whether there should be a way to turn of > the constantness of a defconstant BINDING.) The question here is > whether, in the case of DEFCONSTANT, we can allow internal structure > changes to be picked up at run time.
> My own inclination is that we have other mechanisms for disallowing > changes to internal structure -- namely quoting and load-time-value -- > which could be used in conjunction with the value-form argument to > DEFCONSTANT if desired. Thus, why force defconstant to be a bigger > hammer than it needs to be.
> In any case, I think it's clear by now > that any code that relies on an implementation allowing mutations of > value of defconstant will be non-portable, at minimum.
In article <36F804EA.269...@intellimarket.com>, Kelly Murray <k...@IntelliMarket.Com> writes:
> In my opinion, a Defconstant value should be immutable, > so it can be placed in a read-only area, and thus can > be shareable by multiple lisp images. > What gain is there to allow mutability over a Defvar?
Well, the theory was that a DEFCONSTANT would name a single object and that that binding couldn't be changed. With a DEFVAR, one set and bind the variable, which you can't do with a DEFCONSTANT. But given that you can get non EQ values from the "constant", DEFCONSTANT seems pretty useless to me. One of the most common uses of DEFCONSTANT (which is in error) was to do something like what the original poster tried to do. Namely
(defconstant +EOF-VALUE+ (gensym))
for which there's a chance that it won't do what is intended. DEFVAR and DEFPARAMETER work but don't convey the idea that the binding should be constant.
> Is their some particular problem with having a DefGlobal > which declares a variable global?
> -Kelly Murray
Kind of depends on what the properties of this proposed DEFGLOBAL are.
> then what gets printed out when BAZ is called can be either T or NIL. > (Because the *foo* in BAR may have gotten the value from a different > environment. Now, if you had used DEFVAR instead, it'd always print the > expected T. Kind of counter intuitive that DEFVAR's are EQ but DEFCONSTANTs > aren't necessarily.)
Can you demonstrate that this is legal behaviour? (Not that some implementation has it.)
> > Yes, but DEFPARAMETER is no different from DEFVAR with respect to being > > fast or slow in lookup of the variable's value, so DEFPARAMETER was of > > no interest to me for the purpose of this particular (self-imposed) > > exercise.
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov (You may want to cc your posting to me if I _have_ to see it.) LEGEMANVALEMFVTVTVM (Ancient Roman programmers' adage.)
-----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
In article <8mGJ2.13203$A6.7619...@news1.teleport.com>, "David B. Lamkins" <dlamk...@teleport.com> wrote: (...)
> "same adj. [...] 2. (...) > Backing up a bit, I notice the phrase "users must ensure ... and that it > always evaluates to the same value."
> Combining this with the final sentence (two conses never the same) of the > "same" glossary entry quoted above, I think I see how your example's > behavior is allowed: If I create a program containing the form > (defconstant *foo* '(())) > then I have failed to ensure that the initial value is the same at compile > time and load time. If the implementation evaluates the defconstant form at > both compile and load time, it will cons two different initial values.
> So, now for the $2^16 question: Have I interpreted this correctly?
The word we need here is `similar.'
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov (You may want to cc your posting to me if I _have_ to see it.) LEGEMANVALEMFVTVTVM (Ancient Roman programmers' adage.)
-----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
> In my opinion, a Defconstant value should be immutable, > so it can be placed in a read-only area, and thus can > be shareable by multiple lisp images. > What gain is there to allow mutability over a Defvar?
> Is their some particular problem with having a DefGlobal > which declares a variable global?
> -Kelly Murray
Well, another in my series of half-baked new compiler ideas is that compilation-units/environments and declarations are the proper way to specify modularity of bindings -- orthogonal to issues of compile-file literals.
For example, consider that bindings (either function or variable, or perhaps even other named bindings such as types/classes) can have declarations indicating to the compiler:
- that the value of the binding, if known, can be used by the compiler for partial evaluation/inlining - that the binding can or cannot be considered by the compiler to be bound at run time, effecting whether or not boundp/fboundp checks are needed. - that the value of a binding can be locked in a "load" time - the compiler can't inline it, but it it can at least arrange to grab its value at load time (as though through a (load-time-value ...) and then always use a fast reference to that. (This is more or less a "top-level" lexical variable with the file scope.) etc.
Each of these declarations can apply to lexical and global variable, but of course, the valid values for some of these are more limited for lexical variables (e.g., a lexical variable cannot ever be unbound). Thus, in general, the declarations can be introduced over a lexical scope in the usual way, and global scopes can be effected by compilation-unit.
If some set of declarations, or programmer action such as quoting, indicates that a literal can be used at some level (file, module, local scope, etc.) then so be it.
Defxxx are each understood in terms of these declarations.
Although the idea is to provide both coarse and fine-grained control over compiler optimizations, I find this model easier to understand than the specific top level defxxx thingies, and I'm essentially trying to build concensus for whatever the least restrictive definition of defconstant can be, so that I can figure out how to implement it in terms of declarations and environments.
(No, I don't have a specific proposal or any documentation on what these declarations would cover, nor am I even sure that I understand the consequences in my own head...)
mike...@mikemac.com wrote: > In article <3131135071149...@naggum.no>, > Erik Naggum <e...@naggum.no> writes: > > * ANSI X3.226-1994 > >| 3.2.2.3 Semantic Constraints > >| (...) > >| Constant variables defined in the compilation environment must have a > >| similar value at run time. A reference to a constant variable in source > >| code is equivalent to a reference to a literal object that is the value > >| of the constant variable.
> > * mike...@mikemac.com (Mike McDonald) > >| It says the object, not the contents of the object.
> > I think you need to look up `literal object':
> > literal adj. (of an object) referenced directly in a program rather than > > being computed by the program; that is, appearing as data in a quote form, > > or, if the object is a self-evaluating object, appearing as unquoted data. > > ``In the form (cons "one" '("two")), the expressions "one", ("two"), and > > "two" are literal objects.''
> > such objects are immutable:
> > constant object n. an object that is constrained (e.g., by its context in a > > program or by the source from which it was obtained) to be immutable. ``A > > literal object that has been processed by compile-file is a constant object.''
> > #:Erik
> So the (hyper) spec uses "constant object" for immutable things. defconstant > doesn't signify that the object is constant, only that using the binding of the > symbol has to be equivilent to using the literal form.
Consider then the following example:
(defconstant c '(some value) "example")
(let ((local-var '(some value))) ... ;with local-var appearing in a for-evaluation position here
And we have a reference to C somewhere in the program which is equivalent to a reference to '(SOME VALUE).
Now, what is `a reference to a literal object that is the value of the constant variable'? Is it (1) like the reference to LOCAL-VAR in the LET, or is it (2) like '(SOME VALUE) appearing literally in a for-evaluation position, or is there a third possibility?
If (1), then `is equivalent' in the excerpt from 3.2.2.3 is strange, because the binding of LOCAL-VAR is not constant. You deny (2). So what is the third possibility?
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov (You may want to cc your posting to me if I _have_ to see it.) LEGEMANVALEMFVTVTVM (Ancient Roman programmers' adage.)
-----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
>> then what gets printed out when BAZ is called can be either T or NIL. >> (Because the *foo* in BAR may have gotten the value from a different >> environment. Now, if you had used DEFVAR instead, it'd always print the >> expected T. Kind of counter intuitive that DEFVAR's are EQ but DEFCONSTANTs >> aren't necessarily.)
> Can you demonstrate that this is legal behaviour? (Not that some > implementation has it.)
> --tim
I think it goes something like this:
compile and load file 1 compile and load file 2 ; BAR has the same value for *FOO* compile and load file 1 ; BAZ has a new value for *FOO*!
> In article <36F804EA.269...@intellimarket.com>, > Kelly Murray <k...@IntelliMarket.Com> writes: > > In my opinion, a Defconstant value should be immutable, > > so it can be placed in a read-only area, and thus can > > be shareable by multiple lisp images. > > What gain is there to allow mutability over a Defvar?
> Well, the theory was that a DEFCONSTANT would name a single object and that > that binding couldn't be changed. With a DEFVAR, one set and bind the > variable, which you can't do with a DEFCONSTANT. But given that you can get > non EQ values from the "constant", DEFCONSTANT seems pretty useless to me. > One of the most common uses of DEFCONSTANT (which is in error) was to do > something like what the original poster tried to do. Namely
> (defconstant +EOF-VALUE+ (gensym))
The most common and very useful purpose of defconstant is to declare numeric constants, so the compiler can optimize numerican expressions.
If one can also use it to specify large read-only structures, so much the better, as there isn't a way to really specify this property except consing up a quoted expression at compile time using a macro, as I did in the "reverse-bits" example a while back.
> for which there's a chance that it won't do what is intended. DEFVAR and > DEFPARAMETER work but don't convey the idea that the binding should be > constant.
> > Is their some particular problem with having a DefGlobal > > which declares a variable global?
> > -Kelly Murray
> Kind of depends on what the properties of this proposed DEFGLOBAL are.
Declaring a variable global to avoid a special-bindings lookup, which I thoughts was the point of the thread giving the Subject: of "fast" global variables.
Some get concerned that what is needed is really a "top level lexical" variable for which no symbol is really needed, i.e. you can't get the value via #'symbol-value, and this spills over into defconstant, which has license to elimnate the variable lookup.
> Where does it say that literal objects are immutable?
Let's try Section 3.7 for a change.
3.7.1 Modification of Literal Objects
The consequences are undefined if literal objects are destructively modified.
(...)
> Nor does it say a literal is immutable!
Nor does it exhaust what the spec has to say about literals.
(...)
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov (You may want to cc your posting to me if I _have_ to see it.) LEGEMANVALEMFVTVTVM (Ancient Roman programmers' adage.)
-----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
> At least in the hyper > spec's glossary, which you quoted, it does NOT say literal objects are > immutable.
(...)
Once again, see Section 3.7.1.
> In every case where I've seen (defconstant *foo* (make-array ...)) used, > what was intended that *foo* would always point to the same array, not that > the array's contents would always be the same. But heck, with MCL's > interpretation that it can be a different array in every compiled file, > DEFCONSTANT doesn't mean anything useable.
May every case have been CLtL 1st ed. usage? <opening the book> Sorry, no, even in the 1st ed. text in the 2nd ed. (p. 87), `(...) the compiler chooses to replace references to the name of the constant by the value of the constant in code to be compiled (...),' I shouldn't be guessing.
And what's MCL done to you? Does it not obey the standard? Does it introduce copies of constants that are not similar?
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov (You may want to cc your posting to me if I _have_ to see it.) LEGEMANVALEMFVTVTVM (Ancient Roman programmers' adage.)
-----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
"David B. Lamkins" <dlamk...@teleport.com> writes:
> Combining this with the final sentence (two conses never the same) of the > "same" glossary entry quoted above, I think I see how your example's > behavior is allowed: If I create a program containing the form > (defconstant *foo* '(())) > then I have failed to ensure that the initial value is the same at compile > time and load time. If the implementation evaluates the defconstant form at > both compile and load time, it will cons two different initial values.
> So, now for the $2^16 question: Have I interpreted this correctly?
(That's guaranteed not to be big bucks, though, isn't it? :-)
I think most of your interpretation is correct except I don't think it says enough things to support Sunil's conclusion, even though I think Sunil's right. I think the facts you need to cite are not just that it works as you say and htat you didn't provide protect yourself but also that you were forbidden to for conses. (Can't write a make-load-form on them.) It seems to me that if you'd done (defconstant +foo+ ;I don't like *'s around constants. (get-canonical-copy '(()))) where you'd grabbed the copy out of a registry you wouldn't be accepting just any old item in either case, but a trusted copy with some sense of identity, and you'd have the same questions you had before. And you'd still lose because if someone saved this set, it wouldn't get written out in a way that called get-canonical-copy again because there is no association between the object's identity and the manner of its creation or lookup.
HOWEVER, with user-defined classes that's not so. You *could* have MAKE-LOAD-FORMS such that even if the compiler wrote out the constant in two different places it would have enough info to repatriate the constant with all the other copies and with the things the copy was supposed to deal with. But that's just the definition of similarity... that you write a make-load-form method to make the thing be similar.
So it's really an argument of practicality and externalizable objects that leads you to where you want to be.
mike...@mikemac.com (Mike McDonald) writes: > The part where you're adding the immutable to it. At least in the hyper > spec's glossary, which you quoted, it does NOT say literal objects are > immutable.
That's because, as I understand it, literal objects are not immutable. But literal objects seen by the file compiler are.
In particular, I think: (let ((x (list nil))) (compile nil `(lambda () ',x))) returns a function that yields a modifiable literal. It is the process of externalization, not the process of semantic processing per se, that renders an object immutable. As I recall, anyway.
There is an ordering problem here in the design of the language. We reached this conclusion after much debate because we didn't yet have LOAD-TIME-VALUE. We later added LOAD-TIME-VALUE because this matter was so confusing and contentious but we didn't go back and clean up the mess in EVAL. Now that there's LOAD-TIME-VALUE there is no essential reason that all quoted things couldn't be immutable. But in the pre LOAD-TIME-VALUE days there was an important efficiency reason why it was important that code be able to return a "literal" that was still "mutable" even if such code had to be itself created at loadtime in "impure space" (or whatever they call data on non-read-only pages these days.
> A literal object is that one, unique object. It says nothing about > the status of its contents. In their example of '("two"), it's the > cons cell that is the literal object being refered to, not the > string "two" or the NIL on the end. Granted, in this example, you'd > confuse most people by replaca-ing the list, but I don't see > anything in this definition that it says you can't.
Yes, I agree with this analysis philosophically, though the record is a bit muddled and both you and Erik are probably slightly confused because the language itself is slightly confused on this point. "Sorry about that."
> In every case where I've seen (defconstant *foo* (make-array ...)) used, > what was intended that *foo* would always point to the same array, not that > the array's contents would always be the same. But heck, with MCL's > interpretation that it can be a different array in every compiled file, > DEFCONSTANT doesn't mean anything useable.
Right. Externalization is a mess. As I recall, an example place where it matters is in CLOS-like dispatching where you want to AREF out of a table that can have known address at load time but that still wants to be mutable to accomodate redefinition. If you require that it live in a special variable, you have to do what the pdp10 called a MOVE instruction (an instruction that takes an argument of a memory location and does a memory read from that location); to access a quoted constant, you can get away with a MOVEI (immediate move, where you don't have to do a memory access because you know the "from" value and can represent it in the code vector instead of in the heap). So, in principle, (AREF (LOAD-TIME-VALUE ...) I) is possible to make faster than (AREF +SOME-CONSTANT+ I) because the former can (in principle) be made a MOVEI, while it's hard to tell how the second could be any better than a MOVE indirect through +SOME-CONSTANT+'s value cell (unless you put the value cell in the code vector itself and there was never more than one such code vector, but that's pretty odd). I don't know modern instruction sets well enough to know what the instruction options are, so my apologies for picking such an old one. Of course, an actual CLOS implementation is probably system-provided and doesn't have to fuss about this, but if you wanted to duplicate things CLOS does yourself with no loss of efficiency, you'd want something this powerful to avoid losing a memory cycle on some architectures.
In article <36F7C5E0.B61ED...@elwood.com>, "Howard R. Stearns" <how...@elwood.com> wrote: (...)
> Two sections indicate that they are to be immutable:
> 3.2.2.3 Semantic Constraints: (...) > "constant object" glossary entry (...) > Unfortunately, DEFCONSTANT has no direct references to either of these > entries.
But perhaps an indirect reference would do?
(A) About the middle of the `Macro DEFCONSTANT' section we have
If a defconstant form appears as a top level form, the compiler must recognize that name names a constant variable.
(B) In `See also' there is a reference to 3.2 and if it is followed, and then 3.2.2 followed, we come to 3.2.2.3 which talks about constant variables.
To me, this is quite satisfactory.
> Furthermore, some sections suggest suggest though ommision that the > value of a constant variable is not a constant object or constant > literal, and these sections should probably be ammended:
> DEFCONSTANT dictionary entry:
> The entry explains in detail the constraints on changing the values of > the constant variable produced by defconstant, when the value might be > computed, and discusses how the variable may not be bound. However, > it never says anything about the value being treated as a literal > object, or about references to internal structures of these values.
Maybe it would have been nice if it was explicit, or the reference to the other part of the spec more explicit, but there is a reference.
> 3.1.2.1.1.3 Constant Variables: (...) > Note that nothing is said about immutability, nor is there any > reference to constant objects or literal objects.
The reference is elsewhere.
(...) ;I guess I can safely skip these
> 3.2.1 Compiler Terminology:
> The term literal object refers to a quoted object or a > self-evaluating object or an object that is a substructure of such > an object. A constant variable is not itself a literal object.
> Because this specifically refers to constant variables, but only in > the negative, this could easily be read as indicating that "the value > of a reference to a constant variable is not itself a literal object."
Well, it is true that every formulation can easily be understood in the wrong way.
> Apparently, the intention is instead to indicate that the conceptual > object called a constant variable (not its value) is not a literal > object. However, it is unusual for the spec to refer to the concept > of a variable as an object.
I don't think that we have a reference of this kind here. I interpret
A constant variable is not itself a literal object.
as
An entity which is a constant variable is not an entity which is a literal object.
though this is nit-picking (if that's the word).
> "literal" glossary entry: (...) > This definition does not include references to a value defined by > DEFCONSTANT.
It shouldn't because a constant variable is not a literal object; a _reference_ to it is equivalent to a _reference_ to a literal object.
After all, when one sees ``PI,'' one doesn't literally---immediately--- see that the value is a number somewhere between 3 and 4.
(This is one thing that Pascal helped me to learn. With
const three=3;
both THREE and 3 are constants but only the latter is literal.)
> There is one other source of confusion. Sunil Mishra gives the > example that some implementations might treat the values of > DEFCONSTANT as compile-file literals, with references in different > files being "similar", but not identical. This can lead to confusion.
I don't claim that `similar' is easy to understand, but it is defined comprehensively. Can anyone say specifically what is wrong with this concept?
(...)
> Ultimately, one wonders what is "the right thing." Certainly, one > want to allow compilers to treat the value of a constant variable as > some kind of compile-time literal so that partial evaluation can be > performed at compile time for forms involving references. It comes > down to a quesion of whether DEFCONSTANT constrains both > implementations to make sure that the value was similar at all times, > or just at certain times such as compile and load.
(...)
I.e., what should DEFCONSTANT be?
When it comes to the notion of defining constants, there are (at least) two different possibilities:
(1) constant binding to an immutable object. Offered by DEFCONSTANT as it is now in ANSI Common Lisp. The good thing about arbitrary forms like calls to MAKE-ARRAY, and not just literal objects, being allowed as init values is that sometimes one wants to construct an immutable value at compile time, not at program writing time. The other obvious advantage is that the compiler can optimise for speed and against space by `literalising' the value into the code.
(2) constant binding to a mutable object. Nothing in ANSI Common Lisp provides just that. (This could be used to provide a variable accessible in O(1) at the expense of not being bindable (my idee fixe again). I have an idea how this could be implemented reasonably efficiently and I'll post it RSN.) It would probably be a good thing to have this in the language as many people seem to want it. (Not my implementation but the notion of (2).)
Not that explaining Lisp in terms of C is a good idea (send flames to me by e-mail so I could post a summary to the group), but C provides the following bases for analogy:
const int const *cicp; /*like DEFCONSTANT */ int const *icp; /*always the same cell, */ /* but maybe a different value--- */ /* apparently wanted */ const int *cip; /*that would be a variable that must */ /* always be bound to literal objects */ /* ---anybody ever wanted one? */ int const *icp; /*like an unbindable variable, my */ /* fixation */
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov (You may want to cc your posting to me if I _have_ to see it.) LEGEMANVALEMFVTVTVM (Ancient Roman programmers' adage.)
-----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
In article <36F7E87F.F4BC4...@franz.com>, "Steven M. Haflich" <s...@franz.com> wrote: (...)
> illegal to define a global symbol macro on a symbol declared as a global > variable. Perhaps this restriction was a mistake.
(...)
I don't think so.
Imagine a book which says, perhaps in an obscure footnote, let e be <some value which is not exp 0>, and then uses e^x throughout.
Vassil Nikolov <vniko...@poboxes.com> www.poboxes.com/vnikolov (You may want to cc your posting to me if I _have_ to see it.) LEGEMANVALEMFVTVTVM (Ancient Roman programmers' adage.)
-----------== Posted via Deja News, The Discussion Network ==---------- http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
> In article <36F7C5E0.B61ED...@elwood.com>, > "Howard R. Stearns" <how...@elwood.com> wrote: > (...) >> Two sections indicate that they are to be immutable:
>> 3.2.2.3 Semantic Constraints: > (...) >> "constant object" glossary entry > (...) >> Unfortunately, DEFCONSTANT has no direct references to either of these >> entries.
> But perhaps an indirect reference would do?
> (A) About the middle of the `Macro DEFCONSTANT' section we have
> If a defconstant form appears as a top level form, the compiler must > recognize that name names a constant variable.
> (B) In `See also' there is a reference to 3.2 and if it is followed, > and then 3.2.2 followed, we come to 3.2.2.3 which talks about constant > variables.
> To me, this is quite satisfactory.
In this particular case, I believe the definition of a "constant variable" that pertains is "a named constant", whose definition is:
named constant n. a variable that is defined by Common Lisp, by the implementation, or by user code (see the macro defconstant) to always yield the same value when evaluated. ``The value of a named constant may not be changed by assignment or by binding.''
To me, the important part of this is "to yield the same value when evaluated".
But I'll concede that the spec is confused and inconsistant enough that just about any interpretation is possible, rendering DEFCONSTANT pretty close to useless. The fact that in one place, similar is used instead of same means that you can't use EQ/EQL when testing against the constant, which breaks most of the code that I've seen use DEFCONSTANT.
Now I have to go back a figure out what to do about my CLIM implementation. Its spec requires some CLOS instances to be the value of a constant variable, typically to be used in generic functions using the eql specifier. But since EQL doesn't work on "similar", I don't know what to do about them. How does one test for similarity?
> In my opinion, a Defconstant value should be immutable, > so it can be placed in a read-only area, and thus can > be shareable by multiple lisp images. > What gain is there to allow mutability over a Defvar?
See my post earlier this evening for an explanation. There is a purpose. It doesn't mean you have that purpose. But some people do, or did--at least until LOAD-TIME-VALUE came along. LOAD-TIME-VALUE with a NIL second argument is a very critical need.
> Is their some particular problem with having a DefGlobal > which declares a variable global?
Political.
There was an issue (PROCLAIM-LEXICAL) which failed and hence was not recorded in the HyperSpec (mainly because I worried someone would get confused into thinking it had passed; I suppose I could have found a way to make it clear it hadn't).
In discussion of PROCLAIM-LEXICAL, which proposed global lexicals, it became clear that people were of conflicted minds about whether a global lexical and a global special should have the same value cell, and so it wasn't clear how many kinds of global were needed.
Jonathan Rees wrote up the issue nicely and in a way that accomodated the Scheme community's needs. Then it got amended horribly in meetings to the point where neither the Scheme community could use it nor did anyone in the CL community want it, but it was not unacceptable to people (who were ready to vote yes on it because they had defeated the ill consequences of others' needs, and they (wrongly) still assumed it had some value to those others). In the end, we almost voted in something no one wanted but everyone was willing to tolerate, but I recall polling the room and asking if anyone was still really *wanting* it and no one said yes. Various people had wanted something, but it wasn't it. And no one wanted to start over. So we did nothing.
The issue writeup might be at parcftp.xerox.com somewhere in pub/cl If not, and if someone really cares, they can ask me and I'll dredge up the issue and put it somewhere.
Mike McDonald wrote: > (defconstant +EOF-VALUE+ (gensym))
Incidentally, I usually avoid this for reasons other than those discussed. The purpose of having a unique value is to assure you never see it as a result of READ. But if you have it in this variable, then #.+EOF-VALUE+ will give a bogus eof result when doing READ, and so you defeat the purpose. I prefer to make a new EOF value lexically in the scope of whatever routine I'm using just to make sure no program gets to the eof value. Seems obscure, but I worry about such things.
Btw, to avoid consing, the unique value I almost always use is the stream itself, which is invariably not found in the stream. As long as it's not bound to a special (like *standard-input*) it's not available to the stream. Sometimes I do (let ((eof stream)) ...) so that I can still use a variable named EOF instead of the STREAM variable. Feels kind of weird either way. But it's very practical.
Vassil Nikolov <vniko...@poboxes.com> writes: > Not that explaining Lisp in terms of C is a good idea (send flames > to me by e-mail so I could post a summary to the group), but C > provides the following bases for analogy:
Nothing like keeping an open mind :-)
> const int const *cicp; /*like DEFCONSTANT */ > int const *icp; /*always the same cell, */ > /* but maybe a different value--- */ > /* apparently wanted */ > const int *cip; /*that would be a variable that must */ > /* always be bound to literal objects */ > /* ---anybody ever wanted one? */ > int const *icp; /*like an unbindable variable, my */ > /* fixation */
I'm confused by your second and fourth forms. They look the same to me. Am I missing something?