Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Working with constansts

2 views
Skip to first unread message

Decebal

unread,
May 10, 2009, 11:25:56 AM5/10/09
to
I would like to work with constants in my elisp code. I thought that I
could do this with defconst, but that doen not work.
After:
(defconst dummy "testing")
The variable dummy has the value "testing".
But after:
(setq dummy "changed")
The variable dummy has the value "changed".
What am I doing wrong.
I am working with 'myself compiled Emacs 22.3.

Pascal J. Bourguignon

unread,
May 10, 2009, 12:19:52 PM5/10/09
to
Decebal <CLDWes...@gmail.com> writes:

> I would like to work with constants in my elisp code. I thought that I
> could do this with defconst, but that doen not work.
> After:
> (defconst dummy "testing")
> The variable dummy has the value "testing".
> But after:
> (setq dummy "changed")
> The variable dummy has the value "changed".
> What am I doing wrong.

You're still thinking that constants don't change or that variables do.

If you don't want to change the value of a constant, then don't change it.

--
__Pascal Bourguignon__

Richard Riley

unread,
May 10, 2009, 12:20:54 PM5/10/09
to

Why is it called a constant if its not enforced?

Drew Adams

unread,
May 10, 2009, 12:31:07 PM5/10/09
to Decebal, help-gn...@gnu.org
> I would like to work with constants in my elisp code. I thought that I
> could do this with defconst, but that doen not work.
> After: (defconst dummy "testing")
> The variable dummy has the value "testing".
> But after: (setq dummy "changed")
> The variable dummy has the value "changed".
> What am I doing wrong.

From the Elisp manual:

"The difference between `defconst' and `defvar' is primarily a matter
of intent, serving to inform human readers of whether the value should
ever change. Emacs Lisp does not restrict the ways in which a variable
can be used based on `defconst' or `defvar' declarations. However, it
does make a difference for initialization: `defconst' unconditionally
initializes the variable, while `defvar' initializes it only if it is
void."

Nothing prevents a user or program from changing the value of a `defconst'
variable. Unless you somehow cripple Emacs Lisp, you can always find a way to
modify something. That's about the only constant. ;-)

Pascal J. Bourguignon

unread,
May 10, 2009, 12:33:38 PM5/10/09
to
Richard Riley <riley...@googlemail.com> writes:

For example we call PI a constant. But PI is the ration between a
circle circumference and its diameter, and this ratio depends on the
curvature of the universe, so PI is not really a constant: in our
universe it depends on the altitude, or the distance to the sun, (on
the gravity in general).

So if you want to avoid bugs in your emacs program when you travel,
you must be able to nudge the values of the constants.


--
__Pascal Bourguignon__

Drew Adams

unread,
May 10, 2009, 1:02:42 PM5/10/09
to Richard Riley, help-gn...@gnu.org
> Why is it called a constant if its not enforced?

As the doc says (explicitly): to signal programmer *intention*. It lets human
readers of the code know that it is *intended* that no one and no code will
change the value. Think of it as a comment to that effect, if you like: "Do not
change this value."

Coding with clear signals of intention is helpful, and too often overlooked.
Conventional distinctions of intention among `defconst' vs `defvar'; `when' and
`unless' vs `if' and `cond' vs `and' and `or'; and so on can make a big
difference in code legibility. Which in turn eases maintenance and makes it less
error-prone.

Likewise, wrt names of functions, variables, etc.: good names help maintainers
and code borrowers. Likewise, comments - good ones. Likewise, indenting and
whitespace generally.

All of these things are for human readers of code only. You, like the Lisp
reader, can do without them if you like. YMMV.

[I knew an excellent (in individual terms) Lisp programmer back in the 80s who
never used any whitespace that wasn't strictly needed for the Lisp reader and
never commented any code. He (almost) never hit the Return key. Needless to say,
no one else could work with his code. He did use reasonable names, however, and
he didn't use the same conditional (e.g. `if' or `cond') everywhere. He coded in
the way that was easiest to him and that got the point across to the Lisp
reader.]

Perhaps you have another question:
Q. Why isn't it enforced? A. Lisp.

Richard Riley

unread,
May 10, 2009, 1:28:43 PM5/10/09
to Drew Adams, help-gn...@gnu.org, Richard Riley
"Drew Adams" <drew....@oracle.com> writes:

>> Why is it called a constant if its not enforced?
>

> As the doc says (explicitly): to signal programmer *intention*. It lets human
> readers of the code know that it is *intended* that no one and no code will
> change the value. Think of it as a comment to that effect, if you like: "Do not
> change this value."
>
> Coding with clear signals of intention is helpful, and too often overlooked.
> Conventional distinctions of intention among `defconst' vs `defvar'; `when' and
> `unless' vs `if' and `cond' vs `and' and `or'; and so on can make a big
> difference in code legibility. Which in turn eases maintenance and makes it less
> error-prone.

No two ways. I agree.

>
> Likewise, wrt names of functions, variables, etc.: good names help maintainers
> and code borrowers. Likewise, comments - good ones. Likewise, indenting and
> whitespace generally.
>
> All of these things are for human readers of code only. You, like the Lisp
> reader, can do without them if you like. YMMV.

I don't think anyone would disagree. But this is really a lecture on
clear, structured programming for beginners and not really that
relevant to the specifics of LISP constants in question.

>
> [I knew an excellent (in individual terms) Lisp programmer back in the 80s who
> never used any whitespace that wasn't strictly needed for the Lisp reader and
> never commented any code. He (almost) never hit the Return key. Needless to say,
> no one else could work with his code. He did use reasonable names, however, and
> he didn't use the same conditional (e.g. `if' or `cond') everywhere. He coded in
> the way that was easiest to him and that got the point across to the Lisp
> reader.]

He sounds like a terrible programmer. Programmers that write for
themselves are a curse. Maintenance time exceeds initial development
time by factors of 10 or 100 in most cases.

>
> Perhaps you have another question:
> Q. Why isn't it enforced? A. Lisp.
>

Not really. It's not a constant. Having the specific type and then being
able to modify it proves that. You would be as well sticking CONST as the
name prefix as far as the language goes. As clear.

But yes, of course I agree with your comments on "intent". But it
strikes me that its no more effective than, say requiring a file called
"myconstants" that has a bunch of variables.

So really the question would be : why does Lisp not enforce constants
being, err, constant?

Pascal J. Bourguignon

unread,
May 10, 2009, 2:17:08 PM5/10/09
to
Richard Riley <riley...@googlemail.com> writes:
>> [I knew an excellent (in individual terms) Lisp programmer back in the 80s who
>> never used any whitespace that wasn't strictly needed for the Lisp reader and
>> never commented any code. He (almost) never hit the Return key. Needless to say,
>> no one else could work with his code. He did use reasonable names, however, and
>> he didn't use the same conditional (e.g. `if' or `cond') everywhere. He coded in
>> the way that was easiest to him and that got the point across to the Lisp
>> reader.]
>
> He sounds like a terrible programmer. Programmers that write for
> themselves are a curse. Maintenance time exceeds initial development
> time by factors of 10 or 100 in most cases.

pprint. To me he sounds like a very good programmer. There's no point
in doing something that a simple function can do for you...


>> Perhaps you have another question:
>> Q. Why isn't it enforced? A. Lisp.
>>
>
> Not really. It's not a constant. Having the specific type and then being
> able to modify it proves that. You would be as well sticking CONST as the
> name prefix as far as the language goes. As clear.
>
> But yes, of course I agree with your comments on "intent". But it
> strikes me that its no more effective than, say requiring a file called
> "myconstants" that has a bunch of variables.
>
> So really the question would be : why does Lisp not enforce constants
> being, err, constant?


In the case of emacs lisp, it's because the constant is still refered
to, even in compiled code, thru the constant name. So if the value
bound to the symbol change, it will change instantaneously for all the
functions that us it.

If you consider that emacs is usually a long running process that the
user is continuously modifying, it's rather a good thing: it means you
don't have to recompile everything when you correct the value of a
constant.

But you asked about Lisp.


We'd have to do a study of the numerous remaining lisp dialects still
in existance, but to take the example of Common Lisp, its standard
specifies that you shouldn't modify the value of a constant, and that
implementations are free to do whatever they want if you do. Indeed,
some implementation behave like emacs lisp (eg. clisp, which has
basically the same architecture as emacs lisp: both use a virtual
machine and a byte code compiler). On the other hand, in the case of
sbcl, which uses a native code compiler, the constants are inlined and
if you change them, it won't recompile automatically the code that
depend on them, so you may get inconsistencies. But it doesn't
matter, since you shouldn't do that anyways. If you really want to
change the value of a constant, you should recompile your system and
reload it. (Or else, don't use constants, so the new value of
variables may be taken into account immediately without
recompilation).


--
__Pascal Bourguignon__

Barry Margolin

unread,
May 10, 2009, 2:59:56 PM5/10/09
to
In article <mailman.6953.124197653...@gnu.org>,
Richard Riley <riley...@googlemail.com> wrote:

> So really the question would be : why does Lisp not enforce constants
> being, err, constant?

Because this would incur overhead on every assignment, as it would have
to check whether the variable being assigned was declared as a constant.
Since this is so rarely the case, this overhead could be seen as mostly
wasted and unnecessary.

On the other hand, it would be nice if the byte compiler would warn
about this. Declaring a constant could put something in its property
list, and the compiler could then warn if it sees assignments to the
variable.

Some Common Lisp implementations get around the overhead problem by
putting constants in a page of VM marked read-only, so a hardware trap
is raised if an attempt is made to assign it.

--
Barry Margolin, bar...@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 ***

Richard Riley

unread,
May 10, 2009, 9:36:13 PM5/10/09
to
p...@informatimago.com (Pascal J. Bourguignon) writes:

> Richard Riley <riley...@googlemail.com> writes:
>>> [I knew an excellent (in individual terms) Lisp programmer back in the 80s who
>>> never used any whitespace that wasn't strictly needed for the Lisp reader and
>>> never commented any code. He (almost) never hit the Return key. Needless to say,
>>> no one else could work with his code. He did use reasonable names, however, and
>>> he didn't use the same conditional (e.g. `if' or `cond') everywhere. He coded in
>>> the way that was easiest to him and that got the point across to the Lisp
>>> reader.]
>>
>> He sounds like a terrible programmer. Programmers that write for
>> themselves are a curse. Maintenance time exceeds initial development
>> time by factors of 10 or 100 in most cases.
>
> pprint. To me he sounds like a very good programmer. There's no point
> in doing something that a simple function can do for you...

Hold on.

I agree with concise and clean code.

But blatant showing off with NO whitespace or use of return code is the
sign of, frankly, a loony.

Which was basically my original question.

If you go to the bother of having a "const xyz" implementation then it
seems to me slightly silly not to enforce it.

Of course I understand if the answer is "history and that's the way it
is" but I would sympathise with a new programmer to Lisp that is
surprised he can modify a "const" especially if he came from a C/C++
background where we all fully understand WHY consts are useful for the
programmer but the compiler also enforced it.


--

Richard Riley

unread,
May 10, 2009, 9:38:49 PM5/10/09
to
Barry Margolin <bar...@alum.mit.edu> writes:

> In article <mailman.6953.124197653...@gnu.org>,
> Richard Riley <riley...@googlemail.com> wrote:
>
>> So really the question would be : why does Lisp not enforce constants
>> being, err, constant?
>
> Because this would incur overhead on every assignment, as it would have
> to check whether the variable being assigned was declared as a constant.
> Since this is so rarely the case, this overhead could be seen as mostly
> wasted and unnecessary.

I don't know enough about Lisp than I can only assume that in this case
it can not be detected at compile time IF you compile to byte/p code.

>
> On the other hand, it would be nice if the byte compiler would warn
> about this. Declaring a constant could put something in its property
> list, and the compiler could then warn if it sees assignments to the
> variable.
>
> Some Common Lisp implementations get around the overhead problem by
> putting constants in a page of VM marked read-only, so a hardware trap
> is raised if an attempt is made to assign it.

This makes sense. My initial enquiry was kind of "yeah, thats the way
you say it is, but should it really be like that". If you get my drift.

Pascal J. Bourguignon

unread,
May 11, 2009, 2:29:34 AM5/11/09
to
Richard Riley <riley...@googlemail.com> writes:

> Which was basically my original question.
>
> If you go to the bother of having a "const xyz" implementation then it
> seems to me slightly silly not to enforce it.
>
> Of course I understand if the answer is "history and that's the way it
> is" but I would sympathise with a new programmer to Lisp that is
> surprised he can modify a "const" especially if he came from a C/C++
> background where we all fully understand WHY consts are useful for the
> programmer but the compiler also enforced it.

The important point is that a lisp system is being programmed at the
same time it is executed. Therefore redefining a constant may be
taken into account, because it may be what the _programmer_ really
means.

In C, you would have to recompile the program before a change to a
constant is taken into account, but it would be very possible to
modify a constant: nothing prevents you to edit the C sources,
recompile and relaunch.

Some lisps (such as SBCL) do indeed issue a warning (actually a
continuable error) when you try to change a constant.


Usually, we apply a convention of naming constants surrounding them
with + signs:

(defconst +xyz+ 42)

so you notice immediately if you're doing something you don't mean
when you write:

(setq +xyz+ ...)

This low-tech solution is good enough, so there's no much point in
implementing further tests in the implementation.

(But unfortunately, these conventions are not often respected in emacs
lisp code).
--
__Pascal Bourguignon__

Tassilo Horn

unread,
May 11, 2009, 3:39:49 AM5/11/09
to help-gn...@gnu.org
Richard Riley <riley...@googlemail.com> writes:

Hi Richard,

> So really the question would be : why does Lisp not enforce constants
> being, err, constant?

I think it has something to do how lisp programs can be maintained.
What looks like a constant today may change in the future (maybe by
something totally unrelated like a new law). With java for example, you
would change that constant in the code, rebuild and restart the
application. With lisp you go to the repl and simply change the
constant without having to restart anything.

So you see that enforcing immutability of constants has drawbacks, too.
But the emacs byte-compiler issues a warning instead:

,----[ ~/test.el ]
| (defconst test-constant "CONSTANT")
| (setq test-constant "CHANGED")
`----

--8<---------------cut here---------------start------------->8---
% emacs -Q --batch -f batch-byte-compile test.el
In toplevel form:
test.el:3:7:Warning: variable assignment to constant `test-constant'
Wrote /home/horn/test.elc
--8<---------------cut here---------------end--------------->8---

Bye,
Tassilo
--
Chuck Norris once rode a bull, and nine months later it had a calf.

Decebal

unread,
May 11, 2009, 4:27:03 AM5/11/09
to
On May 10, 6:19 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

But if I make a library and distribute it, the receiver could -
unwittingly- change it. But the idea of using '+' to put before and
after the variable name is a good one. I'll do that.

By the way: you can only change sources if you have them. ;-]
Also: changing a source and recompiling is a little bit more obvious -
also for the person doing it- as a setq.

But my understanding of elisp has been amended. That never hurts.

Thien-Thi Nguyen

unread,
May 11, 2009, 5:58:31 AM5/11/09
to help-gn...@gnu.org
() Richard Riley <riley...@googlemail.com>
() Sun, 10 May 2009 18:20:54 +0200

Why is it called a constant if its not enforced?

Who calls it constant? Does Emacs call it constant?

thi


Barry Margolin

unread,
May 11, 2009, 9:31:58 PM5/11/09
to
In article <mailman.6988.124203621...@gnu.org>,
Thien-Thi Nguyen <t...@gnuvola.org> wrote:

From C-h f defconst: "Define symbol as a constant variable."

Of course, "constant variable" is a notorious oxymoron.

Nikolaj Schumacher

unread,
May 12, 2009, 5:44:27 AM5/12/09
to Richard Riley, help-gn...@gnu.org
Richard Riley <riley...@googlemail.com> wrote:

>> Because this would incur overhead on every assignment, as it would have
>> to check whether the variable being assigned was declared as a constant.
>> Since this is so rarely the case, this overhead could be seen as mostly
>> wasted and unnecessary.
>
> I don't know enough about Lisp than I can only assume that in this case
> it can not be detected at compile time IF you compile to byte/p code.

"Thanks" to dynamic scoping it cannot be caught at compile time.

(defconst xxx nil)

(defun change-xxx ()
(setx xxx t)) ;; const or variable?

(let ((xxx nil))
(change-xxx))


regards,
Nikolaj Schumacher


Nikolaj Schumacher

unread,
May 12, 2009, 5:46:18 AM5/12/09
to Decebal, help-gn...@gnu.org
Decebal <CLDWes...@gmail.com> wrote:

> But if I make a library and distribute it, the receiver could -
> unwittingly- change it. But the idea of using '+' to put before and
> after the variable name is a good one. I'll do that.

What about your internal variables? The user is probably not supposed
to unwittingly change them, either. So the problem isn't limited to
constants. It's Elisp's complete lack of data-hiding.

The proper way to mark a variable as user-changeable is to start the
docstring with a "*". To mark variables (or consts) as "private", it
has become somewhat common to use a double dash like prefix--value
instead of prefix-value.

regards,
Nikolaj Schumacher


Nikolaj Schumacher

unread,
May 12, 2009, 6:06:24 AM5/12/09
to Pascal J. Bourguignon, help-gn...@gnu.org
p...@informatimago.com (Pascal J. Bourguignon) wrote:

> Richard Riley <riley...@googlemail.com> writes:
>
>> Of course I understand if the answer is "history and that's the way it
>> is" but I would sympathise with a new programmer to Lisp that is
>> surprised he can modify a "const" especially if he came from a C/C++
>> background where we all fully understand WHY consts are useful for the
>> programmer but the compiler also enforced it.
>
> The important point is that a lisp system is being programmed at the
> same time it is executed. Therefore redefining a constant may be
> taken into account, because it may be what the _programmer_ really
> means.
>
> In C, you would have to recompile the program before a change to a
> constant is taken into account, but it would be very possible to
> modify a constant: nothing prevents you to edit the C sources,
> recompile and relaunch.

Certainly const in C doesn't mean the value is determined at compile
time. It just means: "This variable shouldn't be modified after its
initialization."

And in fact, you can cast constness away in C++, so it really has
nothing to do with execution versus compile time. It's just a helper
for the developer to prevent side-effects.

There really is no pressing requirement for the current behavior, the
run-time just doesn't verify it. It does one thing, though:

(setq xxx 'user)
(defvar xxx 'library)
xxx => 'user

(setq xxx 'user)
(defconst xxx 'library)
xxx => 'library

A tiny step towards enforcing the value.


regards,
Nikolaj Schumacher


Nikolaj Schumacher

unread,
May 12, 2009, 6:34:35 AM5/12/09
to Pascal J. Bourguignon, help-gn...@gnu.org

> For example we call PI a constant. But PI is the ration between a
> circle circumference and its diameter, and this ratio depends on the
> curvature of the universe, so PI is not really a constant: in our
> universe it depends on the altitude, or the distance to the sun, (on
> the gravity in general).

Certainly PI is a real constant. It is not defined by relative
physical properties, but my mathematics. (In the physical universe,
there is no such thing as a circle.[1])

Yes, when physicists use the word "constant", it's actually an
assumption or average measurement. But code is mathematics, not physics.


regards,
Nikolaj Schumacher

[1]: probably


Pascal J. Bourguignon

unread,
May 12, 2009, 7:43:52 AM5/12/09
to
Nikolaj Schumacher <m...@nschum.de> writes:

It could be caught, if it was so defined by the language.

For example, in the case of Common Lisp, it is forbidden to rebind
lexically or dynamically a constant.

The consequences are undefined when constant symbols are rebound
as either lexical or dynamic variables. In other words, a
reference to a symbol declared with defconstant always refers to
its global value.

Again, in both languages, a good solution is to mark constants with
plus signs, so you're not tempted to rebind them.


--
__Pascal Bourguignon__

Pascal J. Bourguignon

unread,
May 12, 2009, 7:54:02 AM5/12/09
to
Nikolaj Schumacher <m...@nschum.de> writes:

> p...@informatimago.com (Pascal J. Bourguignon) wrote:
>
>> Richard Riley <riley...@googlemail.com> writes:
>>
>>> Of course I understand if the answer is "history and that's the way it
>>> is" but I would sympathise with a new programmer to Lisp that is
>>> surprised he can modify a "const" especially if he came from a C/C++
>>> background where we all fully understand WHY consts are useful for the
>>> programmer but the compiler also enforced it.
>>
>> The important point is that a lisp system is being programmed at the
>> same time it is executed. Therefore redefining a constant may be
>> taken into account, because it may be what the _programmer_ really
>> means.
>>
>> In C, you would have to recompile the program before a change to a
>> constant is taken into account, but it would be very possible to
>> modify a constant: nothing prevents you to edit the C sources,
>> recompile and relaunch.
>
> Certainly const in C doesn't mean the value is determined at compile
> time. It just means: "This variable shouldn't be modified after its
> initialization."
>
> And in fact, you can cast constness away in C++, so it really has
> nothing to do with execution versus compile time. It's just a helper
> for the developer to prevent side-effects.

However, the C or C++ compilers are allowed to consider that the value
of the constant won't change, so they may inline any number of copies
they want. Changing the value stored in the const variable won't
archieve much. The same may occur in Common Lisp.

-*- mode: compilation; default-directory: "~/src/tests-c++/" -*-
Compilation started at Tue May 12 13:46:08

$ gcc -O3 -S -o constant.s constant.c ; cat constant.c ; echo ------------------- ; cat constant.s

const int c=42;

int f(int x){ return c+x; }

-------------------
.file "constant.c"
.text
.p2align 4,,15
.globl f
.type f, @function
f:
.LFB2:
leal 42(%rdi), %eax -------- first copy of the constant
ret
.LFE2:
.size f, .-f
.globl c
.section .rodata
.align 4
.type c, @object
.size c, 4
c:
.long 42 --------- second copy of the constant
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zR"
.uleb128 0x1
.sleb128 -8
.byte 0x10
.uleb128 0x1
.byte 0x3
.byte 0xc
.uleb128 0x7
.uleb128 0x8
.byte 0x90
.uleb128 0x1
.align 8
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB2
.long .LFE2-.LFB2
.uleb128 0x0
.align 8
.LEFDE1:
.ident "GCC: (Gentoo 4.3.3-r1 p1.1, pie-10.1.5) 4.3.3"
.section .note.GNU-stack,"",@progbits

Compilation finished at Tue May 12 13:46:08

> There really is no pressing requirement for the current behavior, the
> run-time just doesn't verify it.

Nothing would prevent emacs lisp to specify defconst in such a way the
byte compiler could do the same. Only in the case of emacs it's more
practical to change the value of the constant, because it means that
you can modify your program without having to restart emacs, which is
a good thing in the case of an editor/IDE/OS.


> It does one thing, though:
>
> (setq xxx 'user)
> (defvar xxx 'library)
> xxx => 'user
>
> (setq xxx 'user)
> (defconst xxx 'library)
> xxx => 'library
>
> A tiny step towards enforcing the value.
>
>
> regards,
> Nikolaj Schumacher

--
__Pascal Bourguignon__

Barry Margolin

unread,
May 13, 2009, 12:59:58 AM5/13/09
to
In article <mailman.7052.124212147...@gnu.org>,
Nikolaj Schumacher <m...@nschum.de> wrote:

> Richard Riley <riley...@googlemail.com> wrote:
>
> >> Because this would incur overhead on every assignment, as it would have
> >> to check whether the variable being assigned was declared as a constant.
> >> Since this is so rarely the case, this overhead could be seen as mostly
> >> wasted and unnecessary.
> >
> > I don't know enough about Lisp than I can only assume that in this case
> > it can not be detected at compile time IF you compile to byte/p code.
>
> "Thanks" to dynamic scoping it cannot be caught at compile time.

It could at least generate a warning.

> (defconst xxx nil)
>
> (defun change-xxx ()
> (setx xxx t)) ;; const or variable?
>
> (let ((xxx nil))
> (change-xxx))

This should also warn about binding a constant.

Ralf Wachinger

unread,
May 13, 2009, 9:41:27 AM5/13/09
to
* Barry Margolin wrote:

> In article <mailman.7052.124212147...@gnu.org>,
> Nikolaj Schumacher <m...@nschum.de> wrote:
>
>> Richard Riley <riley...@googlemail.com> wrote:
>
>>> I don't know enough about Lisp than I can only assume that in this case
>>> it can not be detected at compile time IF you compile to byte/p code.
>>
>> "Thanks" to dynamic scoping it cannot be caught at compile time.
>
> It could at least generate a warning.
>
>> (defconst xxx nil)
>>
>> (defun change-xxx ()
>> (setx xxx t)) ;; const or variable?
>>
>> (let ((xxx nil))
>> (change-xxx))
>
> This should also warn about binding a constant.

This recalls the discussions on constants (general), getters and setters
(OOP) in Python to my mind. Functions as wrappers to enforce the
intentions of the programmers. There are no constants (and even no
declarations) in Python, there's only the convention to write intended
constants in capitals.

For class and instance attributes there are no private, protected or
public declarations (you can even add attributes from outside later) in
Python, there's only a convention to start the intended non-public
attributes with an underline character.

"The pythonic way" informs the users about the intentions, it doesn't
restrict the users. I see that Python and Elisp have a pretty similar
concept on the whole, both are very dynamic and unrestricted.

Barry Margolin

unread,
May 13, 2009, 5:23:39 PM5/13/09
to
In article <20090513.ge...@wachinger.fqdn.th-h.de>,
Ralf Wachinger <rwnews...@geekmail.de> wrote:

> * Barry Margolin wrote:
>
> > In article <mailman.7052.124212147...@gnu.org>,
> > Nikolaj Schumacher <m...@nschum.de> wrote:
> >
> >> Richard Riley <riley...@googlemail.com> wrote:
> >
> >>> I don't know enough about Lisp than I can only assume that in this case
> >>> it can not be detected at compile time IF you compile to byte/p code.
> >>
> >> "Thanks" to dynamic scoping it cannot be caught at compile time.
> >
> > It could at least generate a warning.
> >
> >> (defconst xxx nil)
> >>
> >> (defun change-xxx ()
> >> (setx xxx t)) ;; const or variable?
> >>
> >> (let ((xxx nil))
> >> (change-xxx))
> >
> > This should also warn about binding a constant.
>
> This recalls the discussions on constants (general), getters and setters
> (OOP) in Python to my mind. Functions as wrappers to enforce the
> intentions of the programmers. There are no constants (and even no
> declarations) in Python, there's only the convention to write intended
> constants in capitals.

We also have naming conventions in Lisp: *var* for global variables,
+var+ for constants (although this convention postdates the Common Lisp
specification, so none of the constants defined in the language follow
it).

>
> For class and instance attributes there are no private, protected or
> public declarations (you can even add attributes from outside later) in
> Python, there's only a convention to start the intended non-public
> attributes with an underline character.

CLOS is similar, there's no information hiding. Packages are usually
used to distinguish the public vs internal interfaces, but the CL
package system doesn't prevent outsiders from accessing non-exported
symbols.

>
> "The pythonic way" informs the users about the intentions, it doesn't
> restrict the users. I see that Python and Elisp have a pretty similar
> concept on the whole, both are very dynamic and unrestricted.

The reason for Common Lisp's restrictions on constant is to give more
flexibility to implementors, to allow for better optimization. By
prohibiting assignment to constants, the compiler can perform inline
substitution.

This is less of an issue for interpreted languages, so they tend to be
more permissive.

Nikolaj Schumacher

unread,
May 18, 2009, 6:55:50 AM5/18/09
to Pascal J. Bourguignon, help-gn...@gnu.org
p...@informatimago.com (Pascal J. Bourguignon) wrote:

>> And in fact, you can cast constness away in C++, so it really has
>> nothing to do with execution versus compile time. It's just a helper
>> for the developer to prevent side-effects.
>
> However, the C or C++ compilers are allowed to consider that the value
> of the constant won't change, so they may inline any number of copies
> they want.

Yes, I was thinking of const references... And in lisp, consts would
actually be references (maybe with the exception of numbers)

(defconst x '(foo . bar)

We've talked about (setq x 'foo) being illegal, but that would not
prevent (setcar x 'bar). And even if you prevent that, you can have:

(defvar y '(foo . bar)
(defconst x y)

Now the compiler cannot assume that y will not change, it's just a
reminder to the developer.

>> There really is no pressing requirement for the current behavior, the
>> run-time just doesn't verify it.
>
> Nothing would prevent emacs lisp to specify defconst in such a way the
> byte compiler could do the same. Only in the case of emacs it's more
> practical to change the value of the constant, because it means that
> you can modify your program without having to restart emacs, which is
> a good thing in the case of an editor/IDE/OS.

And nothing would prevent the byte-compiler (and eval-last-sexp) to have
special privileges for overriding consts in a live environment. (You
don't have to format a disk to reclaim write-protected files, either.)

Certainly, inconsistencies might appear, unless every function inlining
the value is also re-evaluated. But that's also the case with macros.

regards,
Nikolaj Schumacher


Pascal J. Bourguignon

unread,
May 18, 2009, 8:20:50 AM5/18/09
to
Nikolaj Schumacher <m...@nschum.de> writes:

> p...@informatimago.com (Pascal J. Bourguignon) wrote:
>
>>> And in fact, you can cast constness away in C++, so it really has
>>> nothing to do with execution versus compile time. It's just a helper
>>> for the developer to prevent side-effects.
>>
>> However, the C or C++ compilers are allowed to consider that the value
>> of the constant won't change, so they may inline any number of copies
>> they want.
>
> Yes, I was thinking of const references... And in lisp, consts would
> actually be references (maybe with the exception of numbers)
>
> (defconst x '(foo . bar)
>
> We've talked about (setq x 'foo) being illegal, but that would not
> prevent (setcar x 'bar). And even if you prevent that, you can have:
>
> (defvar y '(foo . bar)
> (defconst x y)
>
> Now the compiler cannot assume that y will not change, it's just a
> reminder to the developer.


Well, you shouldn't modify quoted literals either, since this is
modifying the program:

(defun f (x)
(let ((y '(foo . bar)))
(prog1 (car y)
(setf (car y) x))))

(list (f 1) (f 2) (f 3) (symbol-function 'f))
--> (foo 1 2 (lambda (x) (let ((y (quote (3 . bar)))) (prog1 (car y) (setf (car y) x)))))

But what you say is correct, in the case of:

(defvar y (cons 'foo 'bar))
(defconst x y)


>>> There really is no pressing requirement for the current behavior, the
>>> run-time just doesn't verify it.
>>
>> Nothing would prevent emacs lisp to specify defconst in such a way the
>> byte compiler could do the same. Only in the case of emacs it's more
>> practical to change the value of the constant, because it means that
>> you can modify your program without having to restart emacs, which is
>> a good thing in the case of an editor/IDE/OS.
>
> And nothing would prevent the byte-compiler (and eval-last-sexp) to have
> special privileges for overriding consts in a live environment. (You
> don't have to format a disk to reclaim write-protected files, either.)
>
> Certainly, inconsistencies might appear, unless every function inlining
> the value is also re-evaluated. But that's also the case with macros.
>
>
>
> regards,
> Nikolaj Schumacher

--
__Pascal Bourguignon__

Nikolaj Schumacher

unread,
May 18, 2009, 3:19:08 PM5/18/09
to Pascal J. Bourguignon, help-gn...@gnu.org
p...@informatimago.com (Pascal J. Bourguignon) wrote:

> Nikolaj Schumacher <m...@nschum.de> writes:
>
>> (defvar y '(foo . bar)
>> (defconst x y)
>>
>> Now the compiler cannot assume that y will not change, it's just a
>> reminder to the developer.
>
> Well, you shouldn't modify quoted literals either, since this is
> modifying the program:

What program? No form is stored in that case.


regards,
Nikolaj Schumacher


0 new messages