Subject: Re: reduced size symbols/keywords
From: rpw3@rpw3.org (Rob Warnock)
Date: Fri, 29 Aug 2008 21:18:15 -0500
Newsgroups: comp.lang.lisp
Message-ID: <r5adnfP2ood6MCXVnZ2dnUVZ_vudnZ2d@speakeasy.net>
John Thingstad <jpthing@online.no> wrote:
+---------------
| Pascal J. Bourguignon <pjb@informatimago.com>:
| > That wouldn't be a symbol anymore.  As indicated by John, use a
| > hashtable to unify your strings.  ...
| > (defparameter *unique-strings* (make-hash-table :test (function equal)))
| > (defun intern-string (s)
| >   (or (gethash s *unique-strings*)
| >       (setf (gethash s *unique-strings*) s)))
...
| > What do you need the value slot for?
| 
| Fair enough. I was thinking more in terms of a lexer.
| If you have more control over the value returned you can use this.
| consider
| (get-symval "reserved1")
| ...
| (get-symval "reservedn")
| (setf *reserved-word* (get-symcounter))
| (defun reserved-wordp (sym)
|    (< sym *reserved-word*))
| 
| So you use the fact that reserved words are inserted before the ones  
| introduced by the user.
+---------------

You can still do this with a hash table, by using the optional
default of GETHASH. Just change Pascal's suggestion to:

    (defparameter *unique-strings* (make-hash-table :test (function equal)))
    (defparameter *unique-count* 0)
    (defstruct interned-string count string other-data)
    (defun intern-string (s &optional other-data)
      (or (gethash s *unique-strings*)
	  (setf (gethash s *unique-strings*)
		(make-interned-string :count (incf *unique-count*)
				      :string s
				      :other-data other-data))))

Then your desired code becomes:

    (intern-string "reserved1" {magic data for "reserved1"})
    ...
    (intern-string "reservedn" {magic data for "reservedn"})
    (setf *reserved-word* *unique-count*)
    (defun reserved-word-p (sym)		; See rules for when "-P".
       (<= (interned-string-count sym) *reserved-word*)) ; Note "<=".


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607