[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: (OPTIONAL ...) &RELATED-ISSUES



Gads, I have a pile of mail from people responding to KMP's proposed change
of &keywords. I am glad for the support and I would love to not have to use
&optional and &rest, but I feel I should note that my original note didn't
propose changing things -- I was discussing an imaginary implementation where
no existing code cared.

Anyway, I have a few comments on mail that went by today...

 * It's hard to tell what they are. There's no actual rule forbidding &'s in
   symbols. Imagine how
		 #'(lambda (&bigfloat x) (list &bigfloat x))
   behaves functionally on the LispM now, and how it might behave someday
   if bigfloats were ever introduced. That's the bad thing about parsers.

 * It's hard to tell what the scope is. While visually, 
		(a &optional x y &rest z)
   might be easy to scan, imagine how a poor program feels about it. It needs
   a parser. Think about this. In your mind, you had grouping around the x and
   the y, then you threw it away when you wrote it down because you figured the
   program should be able to infer easily what you meant. Heck, the reason we
   use (+ X (* Y Z)) instead of X+Y*Z is that it's what we mean and we know
   it's what we mean and there is no sense in throwing away info that you have.

 DLA,
   GJC's suggestions of an &-readmacro comes close, but it still means you are
   throwing away info you had and then asking the readmacro to reconstruct it.
   Note this is info you *really* were conscious of at the time you wrote it
   down. Please don't hit me with ``but if you don't want to trust the machine,
   why not specify bit patterns?'' because that is something that i am *not*
   conscious of -- that is something it would take me work to figure out.
   Besides, I think GJC's &-readmacro thing would parse 
		(&quote x &eval &rest y)
   as
		((quote x) (eval) (rest y))
   which serves to illustrate my point. A little parentheses go a long way.

 RMS, 
   I agree 99.2% with GJC's comment that (OPTIONAL) is as bad as &OPTIONAL.
   Suppose I tell you there is a new keyword &FOO. Does my use of
		(&foo x y)
   tell you whether I mean ((foo x) (foo y)) or ((foo x) y)? I don't think
   it does. Suppose I were doing:
	(defun foo (flag &foo x y) 
	   (if flag ...code involving x only...
		    ...code involving y only...))
   then if you knew flag was always nil, you might be able to look at the code
   and not worry about what the foo declaration was at all, if you knew that
   &foo wasn't a sticky flag. If I said
	(defun foo (flag (foo x) y)
	   (if flag ...code involving x only...
		    ...code involving y only...))
   then you don't have to know what the foo declaration  does at all, as long
   as you know flag is nil.

   This, by the way, is related to why CASEQ is such a winner and computed
   GO's are such a loss. Other than grouping, there really isn't a lot of 
   difference between them -- but boy does that sort of constraint buy you
   a lot!

 GJC,
   Your suggestion of (OPTIONALS ...) and (REST ...) is better visually, but
   has the disadvantage that it is not so nicely recursive in nature. It
   looks to me like my definitional syntax:
	(defun f (x y (optional (fixnum x) x-default x-p)
		      (optional w)
		      (optional (fixnum ww) w-default)
		      (rest (special r))) ...)
   would look like:
	(defun f (x y (optionals ((fixnum x) x-default x-p)
				 w
				 ((fixnum ww) w-default))
		      (rest (special r))) ...)
   which is bad because in mine the body of the OPTIONAL and REST clauses
   take the same sorts of fillers, but in yours, the bodies have different
   types of things in them. This seems to me to be a rather severe weakness.

   Additionally, yours is hard to do certain code-transformations on using
   a single level of MAPC/MAPCAR/MAP's. It requires mapping down the 
   subcomponents in a way I think is much hairier.

It might well be reasonable to make certain common declarations shorter.
eg,
	(defun f (x y (opt x xd xp) (opt y) (rest z)) ...)
instead of
	(defun f (x y (optional x xd xp) (optional y) (rest z)) ...)
might go a long way.

Also, a readmacro char that really did specify what you wanted ...
	(defun f (x y #:2O (x xd xp) y #:R z) ...)
That might take some getting used to. Note that it allows for LSB's 
one-or-more-of hack by things like:
	#:1,O  ; means 1 required, up to infinity allowed
        #:2,5O ; means 2 required, up to 5 allowed

These are just ideas. I agree that the problem of repeating the key is
an annoying one, but I feel that it's not the most severe problem being
addressed. This loss of ability to MAPCAR down them because they need to
be parsed and indeed the need for a parser to begin with is a more severe
issue in my mind.

-kmp