Subject: Re: A modest proposal (long)
From: Erik Naggum <erik@naggum.no>
Date: 2000/03/02
Newsgroups: comp.lang.lisp
Message-ID: <3160966858202840@naggum.no>

* Erann Gat
| The problem is not special variables.  The problem is the way you tell
| Lisp which variables you want to make special and which you don't.

  so let me disagree vociferously with that, too.  if we make necessary
  things inconvenient to express, it is not their expression that will
  suffer the most, but common recognition of their necessity.  the fact
  that special variables solve a problem that exist in _every_ programming
  language so conveniently, namely how to ascertain proper restoration of
  global variables, means that people aren't going to reinvent tricks with
  unwind-protect and the like (if they know about unwind-protect -- Kent
  Pitman has made the cogent argument that languages can be judged on the
  existence of such a language feature -- I'll argue that the same applies
  to programmers and whether they know about it).

  as soon as you start to make these special variables stand out as the
  wart on the language that you appear to believe they are, people will
  naturally avoid them (and the more so the more weirdo syntax soup you
  introduce, the threat of which I now realize is part of my objection to
  your syntax-heavy proposal), and choose the next best thing that looks
  like it could be sufficiently convenient.  then they start to make buggy
  or needlessly verbose code, which they'll loathe.  you're rocking the
  boat and making life miserable for those who _need_ special variables and
  need them _not_ to look _too_ special, because that destroys their very
  significant convenience factor.  I say: don't do that.  solve the actual
  problems, don't just push your special brand of cosmetics.

| The issue is not just one of querying.  It's also one of control.  There's
| no way to undo the effects of a defvar short of uninterning the symbol.

  so let's find a way to do that, instead, then.  (how hard can this be?)

  I think a Common Lisp environment needs universal functionality to "undo"
  or "kill" all definition forms.  Allegro CL has a nifty feature to kill
  various definitions from the Emacs interface, and I use it seldom enough
  to appreciate it very highly every time, but it does not accept defvar.
  (I'll file a request for enhancement for that.)  this might be considered
  annoying, but in the meantime, here's a couple tiny functions to muck
  with the gory internals of symbols in a way that is guaranteed to make a
  whole slew people want to puke violently, but if they get over it and
  realize that Common Lisp is all about _exporting_ an elegant interface to
  lots of really hairy stuff to begin with, they might actually rejoice and
  use these functions.

(in-package :excl)

#+allegro-v5.0.1
(defun symbol-special-p (symbol)
  (declare (optimize (speed 3) (safety 0)) (symbol symbol))
  (check-type symbol symbol)
  (if (and (not (eq nil symbol))
	   (zerop (ldb (byte 1 #.(system::mdparam 'compiler::md-symbol-flag-constant-bit))
		       (excl::sy_flags symbol))))
    (not (zerop (ldb (byte 1 #.(system::mdparam 'compiler::md-symbol-flag-globally-special-bit))
		     (excl::sy_flags symbol))))
    nil))

#+allegro-v5.0.1
(defun (setf symbol-special-p) (special symbol)
  (declare (optimize (speed 3) (safety 0)) (symbol symbol))
  (check-type symbol symbol)
  (if (and (not (eq nil symbol))
	   (zerop (ldb (byte 1 #.(system::mdparam 'compiler::md-symbol-flag-constant-bit))
		       (excl::sy_flags symbol))))
    (setf (excl::sy_flags symbol)
      (dpb (if special 1 0)
	   (byte 1 #.(system::mdparam 'compiler::md-symbol-flag-globally-special-bit))
	   (excl::sy_flags symbol)))
    (error "Cannot change special status of constant symbol ~S." symbol)))

  perhaps needless to say, you can hurt your Allegro CL system with the
  latter function, even though I have tried to restrict a few particular
  damages that users are likely to try (and I know how to restrict).

  if you don't have Allegro CL 5.0.1, this won't necessarily fail, but _you_
  had to remove the read-time conditionals so _you_ take the responsibility.

| >   again, there is a need to change the language to make it more amenable to
| >   beginners and experienced users alike: unlike all other languages now in
| >   current and widespread use, Common Lisp violates the notion that what you
| >   see is what you get with respect to the _names_ of the symbols.
| 
| Maybe it would help to review the distinction between a variable and a
| symbol (and the name of a symbol) just to make sure we are all on
| the same page.

  find, but sometimes, it isn't everybody else who need to be on your page.

| The point is that none of this has anything to do with symbol names.

  duh.  I'm trying to redirect your attention to a worth-while problem,
  entirely _away_ from messing with stuff you shouldn't be messing with.

| I thought that's what I was doing, but it seems I still have not made
| myself clear.   You seem to think that I am saying that the problem is
| the existence of dynamic variables and symbol-value.   I'm not saying
| that at all.   What I am saying is that the way things currently stand,
| when you write 'X' you can't in general know whether what you've written
| is a reference to a stack frame or a slot in an object on the heap.
| And, in fact, as you yourself pointed out the meaning of X can change
| over time if you are running interpreted.  IMO that's bad.

  and IMNSHO, it isn't bad at all.  I have pointed out that we need a few
  accessors into the environment to solve your uncertainty problem, and
  perhaps we need a `notspecial' or `lexical' declaration to be able to
  undo the pervasive effects of the `special' declaration.  however, I care
  so much about the language that I'm unwilling to consider your proposal
  when I understand the issues so much better than you do and I consider
  your proposal to be a major disturbance over a petty issue that mainly
  has to do with a disportional sense of uncertainty.  now, I fully
  recognize that uncertainty is one of those things that make people go
  nuts and that it is vitally important in a community to avoid swarms of
  neurotics who run around with proposals that are mainly intended to
  affect their mental state in some vaguely positive way, so I instead
  propose something that will make the uncertainty go away by adding a very
  low-level certainty instead of making any changes to superficial features
  that will take yet more forms as the swarm of neurotics has only been
  decimated for now, not actually cured of their unhealthy uncertainty.

| >  it's not a question of case,
| >   it's a matter of making (setf (readtable-case *readtable*) :preserve)
| >   work the way people _actually_ expect it to.  think about it.  please.
| 
| It would help if you would stop talking in riddles.

  geez.  there are no riddles.  I'm talking about something other than you
  do, because I think what you're talking about is counter-productive.  you
  missed that point entirely when you thought I was still talking about
  your concerns over specialness when I talked about symbol names.  I'm a
  little concerned with the breakdown of communication that occurs when
  people don't notice that others aren't talking about the same thing they
  are, anymore, but just keep on and on about whatever they had in mind.

| Works the way I'd expect it to.

  so try typing in (setf (readtable-case *readtable*) :upcase) and tell me
  what you expect to happen and/or that this is not a useful thing to do.
  (note again that this is no longer a question of special variables.)

#:Erik