Re: Is DEFCONSTANT broken?



On Jun 24, 7:51 pm, Scott Burson <FSet....@xxxxxxxxx> wrote:
On Jun 23, 10:32 pm, Duane Rettig <du...@xxxxxxxxx> wrote:





On Jun 23, 9:23 pm, Scott Burson <FSet....@xxxxxxxxx> wrote:

On Jun 23, 6:17 pm, Duane Rettig <du...@xxxxxxxxx> wrote:

On Jun 23, 5:09 pm, Scott Burson <FSet....@xxxxxxxxx> wrote:

On Jun 23, 3:20 pm, Duane Rettig <du...@xxxxxxxxx> wrote:

On Jun 23, 2:40 pm, Scott Burson <FSet....@xxxxxxxxx> wrote:
I have long thought DEFCONSTANT is
not as useful as its inventor(s) probably hoped.

That's because you're thinking of defconstant as providing some sort
of "protection", which it does not.

There's that, but there's also the issue raised on the SBCL page
someone in this thread linked to, which is that it arguably would be
better if it didn't assign a new value on repeated evaluation (i.e. it
should be more like DEFVAR).

Perhaps.  But then your program would be write-only.  What do you do
when you realize that you made a mistake?

Perhaps MAKUNBOUND would do for this.  It's rarely enough used that
one is unlikely to call it without thinking.

But in this "new and improved" CL where defconstant really defines
something that can't be changed, would makunbound then have an effect?

I think it could, but again this is off the cuff.  I don't have a
fully thought out proposal and I probably won't bother to produce one.

Right; when considering language changes, one must never limit the
thought to just the localized change that is desired, but one must
consider all of the consequent changes that would be needed to make
the language consistent. I have no doubts you could come up with a
solution, but you would certainly have to think about such a solution
as part of the change and what other conventions you want your
language to follow.

 For example, I could imagine an
implementation noting cases where the compiler has integrated a
declared constant into a compiled routine, in such a way that it could
e.g. warn you, when loading a fasl file, if the current value of the
declared constant differs from the one the function was compiled
with.  I don't know if the spec should have mandated such helpfulness,
but I think DEFCONSTANT would be more useful if at least the high-end
implementations did stuff like that.

Well, there's nothing to prevent an implementation from doing this,
but I certainly wouldn't - how much memory and code overhead do you
think might be involved in remembering that this value 23 compiled
inline into this function's code came from the particular constant you
compiled long ago?

This seems a very strange question in an era when a terabyte disc
drive costs under $100.

This argument has been given since the beginning of computing, long
before Bill Gates made his famous "nobody will ever need 840K memory"
quip.

???  I proposed that for each compiled function the implementation
would remember all values of constants integrated into the compiled
code.  Even constant-heavy code is going to have what, on average --
two or three of these per routine?  How much space do you think we're
talking about here?

Are we really talking about space here? Or even just code? (yes,
these were the choices I gave, but really, is that all you think about
when you hear the word "overhead")? [And even if you were thinking in
the direction of the terabyte machine, what about running CL on your
iPhone? How much power consumption would you have to deal with with
"just a few more bytes?" Of course, all of this overhead could be
stripped away for such a targeted application, but if the language has
to be stripped down in order to deploy, why use CL at all? Cl would
become so muscular that it would edge itself out of many application
situations it can currently be deployed in.]

But I wasn't talking only about memory space, per se, and I'm glad you
caught the drift of what I really was trying to push you toward:

I'm not saying this is a very important feature, but I think the
reason not to do it is that it's more trouble to implement than it's
worth, not that the fasl file space requirement would be prohibitive.

Yes, _now_ we're talking! It's all about complexity, and it's also
about departing from the basic flavor of Common Lisp:

- Complexity:

The CL style is to allow constants (they're immutable by agreement
between the user and implementor) to be compiled inline into the
code. So what happens when a constant is redefined to a new value?
For the sake of discussion, let's ignore that CL says that the results
are implementation dependent; we'll be talking about the "new improved
CL" where constants can indeed be redefined with defined
consequences. If this is the case, and holding all other factors
steady, consider the code

(defmacro addit (a b c)
`(+ ,a ,b ,c))

And then consider the function foo

(defun foo (x)
(addit +my-lifetime-height+ x +my-lifetime-weight+))

Of course, I've depicted these values as constants, but in reality,
they are unlikely to be constants. In the compiled code, my compiler
transforms this function to a single instruction:

add <secret-value>,parm0,ret

where <secret-value> is none of your business.

Now, how do I set up my compiler to keep track of this value, which
has no direct connection with the two constants I defined, but which
should in fact change if I changed either of these constants?
Obviously, there could be connections made, either to the source code
(which would always have to be saved) or to some mechanism to dislodge
the constant from the code stream (similar to what update-instance-
for... do in CLOS). The problem here is that the whole reason for
compilation is to reduce code complexity, and having these hooks to
break these simplifications goes against the goal of compilation. You
may as well not compile your code at all, in which case you would
almost get what you desire anyway (modulo the implementation's
willingness to change the constant).


- Basic flavor of Common Lisp:

Common Lisp tries to balance between late binding and efficiency. So
whereas a function can be redefined on the fly, and thus the new
definition can be made available for the next call to that function's
name, there are also provisions for freezing function definitions, via
the guarantees made by the Semantic Constraints in 3.2.2.3 (which are,
like constants not changing, only guarantees if the constraints are
obeyed by the user). Thus, a function in a file might be called by
another function in that same file, and the implementation is free to
seal that function's definition within the caller, regardless of
whether the called function has been later redefined. CL thus defines
a pattern that might be described as "late binding, but not too
strict". It is this tension between late binding and allowing the
most efficient code possible which allows CL to compete successfully
with other low-level languages like C.

The same could be said of constants. In fact, in my opinion the
purpose of defconstant is to provide a break from the normal late-
binding rules that apply to other variables and to thus allow the
constant to be embedded in the code without regard to the problem of
what to do with the code when the constant is redefined.

Duane
.



Relevant Pages

  • Re: "STL from the Ground Up"
    ... high-level intermediate language than can interoperate with many other ... If your language lacks expressive features then you cannot write code ... memory management in comparison. ... Mostly because type errors mean that the programmer and compiler disagree ...
    (comp.programming)
  • Re: A note on computing thugs and coding bums
    ... It would handle international characters if the execution character ... method I used in "Build Your Own .Net Language and Compiler". ... work areas and counting on Nul is an illusion. ...
    (comp.programming)
  • Re: WaitForSingleObject() will not deadlock
    ... represent an incorrect implementation of the language. ... the *compiler* does not guarantee this. ... but to state it in terms of the execution instead of the formal semantics of the language ... as long as the optimizations do not change the semantics of the language). ...
    (microsoft.public.vc.mfc)
  • Re: subroutine stack and C machine model
    ... Use a compiler optimizer ... higher determinism means that optimizer has more information. ... C programmers like to brag that their "language" is more ... prospective computer science majors at Princeton. ...
    (comp.lang.c)
  • Re: "STL from the Ground Up"
    ... are not features of a language. ... To support reflection you make a compiler embbed type and functional information in the compiled program. ... When the OCaml compiler is given a complicated nested pattern match it ... virtual const Base *clone= 0; ...
    (comp.programming)