From xemacs-m  Thu Apr 17 15:57:01 1997
Received: from synaptics.synaptics.com (synaptics.synaptics.com [207.92.223.3])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id PAA10136
	for <xemacs-beta@xemacs.org>; Thu, 17 Apr 1997 15:56:56 -0500 (CDT)
Received: (from mail@localhost) by synaptics.synaptics.com (8.7.5/8.7.3) id NAA20227 for <xemacs-beta@xemacs.org>; Thu, 17 Apr 1997 13:56:09 -0700 (PDT)
X-Authentication-Warning: synaptics.synaptics.com: mail set sender to <daveg@thymus> using -f
Received: from synaptx.synaptics.com(192.147.44.16) by synaptics.synaptics.com via smap (V1.3)
	id sma020220; Thu Apr 17 13:55:49 1997
Received: from thymus.synaptics.com by synaptx.synaptics.com (4.1/SMI-4.1)
	id AA04729; Thu, 17 Apr 97 13:55:24 PDT
Received: by thymus.synaptics.com (4.1/SMI-4.1)
	id AA19801; Thu, 17 Apr 97 13:55:17 PDT
Message-Id: <9704172055.AA19801@thymus.synaptics.com>
To: xemacs-beta@xemacs.org
Subject: Re: CL features 
In-Reply-To: Your message of "Thu, 17 Apr 97 09:41:21 EDT."
             <199704171341.AA011674481@martigny.ai.mit.edu> 
Reply-To: daveg@synaptics.com
Date: Thu, 17 Apr 97 13:55:15 -0700
From: Dave Gillespie <daveg@synaptics.com>

Bill Dubuque writes:
> [There may well be a 'defstruct' in CL.EL

There is.  It's fully CL compliant, except that due to Emacs
limitations it must implement all structs as either vectors
or lists---no opaque struct objects.

> but what good is it if no one uses it -- usually for abolutely
> ludicrous reasons such as worrying about the space taken up by CL]

I think people see the size of cl-macs.el and run away, but
they really shouldn't.  The reason cl-macs.el is so big and
monolithic is that I deliberately designed it to be needed
only during byte-compilation.  If you merely load and run
compiled code, there will be no macro calls so cl-macs.el will
never get autoloaded.  And I think it's unreasonable to worry
about the size or load time of cl-macs.el *while* byte-compiling.

I also paid a lot of attention to efficiency.  For example,
`defstruct', `setf', and `loop' are extremely powerful and
general notations, but in compiled code they are usually just
as efficient as the equivalent Emacs Lisp code would be if
written "longhand."

The CL package really does bring Emacs Lisp reasonably up to date.
The only major feature that's missing is CLOS, which *could* be
implemented on top of Emacs Lisp but only with a pretty huge
effort.  (At least, if you wanted good performance.)

There are a few other things missing: the Condition System, for
example, and Common Lisp's version of `format'.  I judged the
value of those features beyond Emacs' own counterparts to be not
worth the cost of implementing them.


Bill further writes:
> (rotatef (first x) (last x))   [aka Suzuki pointer rotation]

I didn't know `last' was an acceptable place form in Common Lisp.
It wouldn't be hard to write a `defsetf' definition for it,
though.

I used Steele's _Common Lisp, the Language_, second edition (1990)
as my reference when I wrote the CL package.  I haven't kept up on
the Common Lisp standard since then, so maybe `(setf last)' is a
last-minute addition.

> (rotatef (subseq line1 0 8) (subseq line2 0 8))

This works fine in the CL package.

> (incf (ldb byte-field variable) increment)

I omitted `ldb' from the CL package---it didn't seem as useful
when all integers are limited to twenty-something bits.  But it
would be easy to define `ldb' and its setf-method if anyone
wanted it.

> (setf (getf (custom-variable-plist var) :doc) "some doc")

This would work if someone defined a setf-method for
`custom-variable-plist'.

> (setf (values quotient remainder) (truncate linewidth tabstop))

Steele's CLtL2 noted that `setf' on `values' had been proposed
but not yet formally added to the language, and it looks like I
used that as an excuse not to implement it.  :-)

I gather this feature was finally added to the language.  Here
is an implementation suitable for inclusion in cl-macs.el:

----
(define-setf-method values (&rest args)
  (let ((methods (mapcar #'(lambda (x)
			     (get-setf-method x cl-macro-environment))
			 args))
	(store-temp (gensym "--values-store--")))
    (list (apply 'append (mapcar 'first methods))
	  (apply 'append (mapcar 'second methods))
	  (list store-temp)
	  (cons 'list
		(mapcar #'(lambda (m)
			    (cl-setf-do-store (cons (car (third m)) (fourth m))
					      (list 'pop store-temp)))
			methods))
	  (cons 'list (mapcar 'fifth methods)))))
----

This code is similar to what you'd write for true Common Lisp,
but it has been adapted to Emacs in several ways.  First, it uses
`cl-macro-environment' to get the lexical environment instead
of an `&environment' argument; the latter is supported by the
CL package and would work fine in your own code, but for technical
reasons you can't use `&environment' arguments in code that
appears in the cl-macs.el file itself.  Second, Emacs does not
support true multiple return values, so the CL package fakes
them up with lists.  This affects both the semantics of `values'
itself, and the way `get-setf-method' is called.  Third, the
`cl-setf-do-store' function builds an optimized version of a
`let' wrapped around a call to the storing form.  (For further
explanation, see Steele's book.)

With the above definition, your example works fine if you
replace `truncate' (an Emacs built-in that returns only one
value) with `truncate*' (the CL-compliant version from my
package).

> Also in CL setf methods are first-class function names,
> so you can do  
>     (defun (setf cadr) ...)

I have this working "in the lab," so to speak, but the released
version of the CL package does not support this notation.  You
have to use `defsetf' or `define-setf-method' instead.

								-- Dave

