[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
A keyword data type
Date: Tue, 8 Mar 88 11:06 est
From: "mike@gold-hill.com after 1-April-88" <mike%acorn%live-oak.lcs.mit.edu@ics.uci.edu>
Date: Sun, 06 Mar 88 12:08:16 -0800
From: kipps%etoile.uci.edu@ICS.UCI.EDU
The comments I've heard so far about keywords lead me to believe that
there shouldn't be a keyword package at all; instead, there should be a
keyword data type, i.e., a data type of symbolic literals. A keyword data
object always evaluates to itself and has only one user-visible component,
its print name.
Frankly, I think this is a great idea. However, there are interactions with
various features. E.G., &key parameters. For the sake of
language extensions like CLOS, the identifiers for &key parameters are
not really going to be required to be "keywords" at all; rather, they
can be any symbol in any package. Use of real "keywords" for this just
saves making an extra symbol. We would need to change terminology
so that &key would become &name or &sym or something to avoid confusion.
Such a terminology change might be necessary whether or not keywords
were a distinct data type. Even without the new data type, the
"keywords" corresponding to &KEY parameters will not be required to be
keywords under the old definition (a symbol in the KEYWORD package).
A variation of your idea which might capture its value and yet avoid
turmoil in the CL world would be to make KEYWORD officially a subtype
of SYMBOL, and to exactly define which symbol operations work on this
subtype. My suggestion is that SYMBOL-NAME work, but not
SYMBOL-PLIST, SYMBOL-FUNCTION, SYMBOL-VALUE, etc. Currently, keywords
are real symbols, not a subtype, and therefore the issue arises of
whether you can IMPORT a keyword, etc.
Actually, I think that SYMBOL should be a subtype of KEYWORD! Anything
you can do to a keyword you can also do to a symbol, but not vice versa.
Using CLOS syntax (we'll need to get used to this soon):
(defclass keyword ()
((name :initarg name
:reader symbol-name)))
;;; This should actually be a shared slot, but I'm not sure how to
;;; access it in the allocate-instance meta-method, because I don't
;;; have Part 3 of the CLOS spec.
(defvar *keyword-table* nil)
(defmethod eval ((object keyword))
(symbol-value object))
(defmethod symbol-value ((object keyword))
object)
(defmethod initialize-instance :after ((object keyword) &rest ignore)
(unless (slot-boundp object 'name)
(error "A name must be specified.")))
(defmethod allocate-instance :around ((class (eql (symbol-class 'keyword)))
&key name &allow-other-keys)
(or (and (stringp name)
(find name *keyword-table* :key #'symbol-name :test #'string-equal))
(let ((object (call-next-method)))
(push object *keyword-table*)
object)))
(defun intern (string &optional package)
(if (or (eql package 'keyword) ; back-compatibility
(string-equal package "keyword"))
(make-instance 'keyword :name string)
(intern-in-package string package)))
(defclass symbol (keyword)
((value :accessor symbol-value
:writer set)
(function :accessor symbol-function)
(plist :initform nil
:accessor symbol-plist)
(package :initform nil
:reader symbol-package)))
(defun symbolp (object)
(typep object 'symbol))
(defun keywordp (object)
(and (typep object 'keyword)
(not (typep object 'symbol))))
I suspect the last function was the reason Mike said keywords should be
subtypes of symbols. I think the ultimate reason for this backwardness
is that the data types we really need are NAMED-OBJECT, with two
subtypes KEYWORD and SYMBOL.
barmar
- References:
- A keyword data type
- From: "mike@gold-hill.com after 1-April-88" <mike%acorn%live-oak.lcs.mit.edu@ICS.UCI.EDU>