[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
New symbols on the fly
- To: jbk@world.std.com (Jeffrey B Kane)
- Subject: New symbols on the fly
- From: Steve Strassmann <straz@cambridge.apple.com>
- Date: Thu, 2 Jul 1992 13:34:49 -0500
- Cc: info-mcl
>Now the problem that I'm having is this: if I use the above code:
>
>(ENTER 10)
>(STO 3)
>
>all works well, the number 10 is stored in R3. If I next type:
>
>(RCL 7)
>
>no R7 symbol has been defined yet, so LISP yips at me. I originally
>thought that "intern" would create a symbol if it needed to, otherwise
>it would simple return the value of the symbol, but I must be wrong.
>Using "find-symbol" does not seem to work either. There must be an
>easier way to do this, as this kind of thing is one of the chief advantages
>of LISP.
Yes, there is. Here's some code that does what I *think* you were
trying to do.
In lisp, creating a symbol doesn't necessarily bind it to a value.
It is an error to try to read the value of an "unbound" symbol.
Lessons:
1) Use more verbose names for functions and variables,
i.e. don't use "n" for both register names and values!
This makes your code easier to comprehend.
2) There's no need to use macros when functions will do.
3) Use SET instead of SETF to set variables whose names
you want to compute on the fly.
4) Use BOUNDP to see whether a symbol has been given a value
(see also FBOUNDP for functions).
----------------------
(defvar *current-register-id* 0 "The id of the current register")
(defun get-register-named (&rest args)
(intern (format nil "~{~A~}" args)))
(defun sto (value)
(set (get-register-named "R" *current-register-id*)
value))
(defun rcl (&optional (register *current-register-id*))
(let ((reg (get-register-named "R" register)))
(if (boundp reg)
(symbol-value reg)
(format t "Sorry, ~A has not been initialized yet." reg))))
(defun enter (register)
(setf *current-register-id* register))
? (enter 10)
10
? (sto 3)
3
? (rcl 7)
Sorry, R7 has not been initialized yet.
NIL
? (rcl 10)
3
Exercise for the reader: Modify GET-REGISTER-NAMED to keep
track of all known registers by saving them on a list
called *KNOWN-REGISTERS*.