In my current project I have several constants, some of which are
complex lists of structs of lists and so on. They don't change during
program operation, but do change during development. Example: the list
of items available in a videogame, with their various constant
properties, such as the item name.
A perfect fit for defparameter, right? Updated when rolling out code
changes, but otherwise untouched? Almost.
See, I also have a few variables to keep the program status, such as the
list of items currently in the player's bag (it is indeed a videogame.)
My question is: how should I link each CURRENT-ITEM variable to its ITEM
constant description?
If I use a reference to the ITEM object, every operation becomes simple:
(item-name (ci-item ci))
But I can't reload the program without deleting all the current games,
unless I find a way to update all the existing references, deep inside
the game variables.
Using a "constant" kind of pointer instead, such as a symbol (following
the example: 'sword-of-doom), avoids any "dangling reference" problem,
but adds unnecessary syntax all over the place:
(item-name (symbol-to-item (ci-item-symbol ci)))
I can think of a few ways to solve the syntactic issue, but I'd like to
get some input on what's the "lisp way" of dealing with this situation.
Toby
Lisp newbie
Toby <·······@gmail.com> writes:
> If I use a reference to the ITEM object, every operation becomes simple:
>
> (item-name (ci-item ci))
>
> But I can't reload the program without deleting all the current games,
> unless I find a way to update all the existing references, deep inside
> the game variables.
>
> Using a "constant" kind of pointer instead, such as a symbol (following
> the example: 'sword-of-doom), avoids any "dangling reference" problem,
> but adds unnecessary syntax all over the place:
>
> (item-name (symbol-to-item (ci-item-symbol ci)))
(defun ci-item (ci) (symbol-to-item (ci-item-symbol ci)))
;; and you're back to:
(item-name (ci-item ci))
> I can think of a few ways to solve the syntactic issue, but I'd like to
> get some input on what's the "lisp way" of dealing with this situation.
--
__Pascal Bourguignon__ http://www.informatimago.com/
Wanna go outside.
Oh, no! Help! I got outside!
Let me back inside!
Pascal Bourguignon wrote:
> (defun ci-item (ci) (symbol-to-item (ci-item-symbol ci)))
> ;; and you're back to:
> (item-name (ci-item ci))
Yeah... I know you can work around the syntactic problems, I just wanted
to know whether using symbols as pointers is overall a good approach.
Toby
Tobia <·······@gmail.com> writes:
> Pascal Bourguignon wrote:
>> (defun ci-item (ci) (symbol-to-item (ci-item-symbol ci)))
>> ;; and you're back to:
>> (item-name (ci-item ci))
>
> Yeah... I know you can work around the syntactic problems, I just wanted
> to know whether using symbols as pointers is overall a good approach.
Probably. It's one of the simpliest indirections you can have.
--
__Pascal Bourguignon__ http://www.informatimago.com/
ATTENTION: Despite any other listing of product contents found
herein, the consumer is advised that, in actuality, this product
consists of 99.9999999999% empty space.
Toby <·······@gmail.com> writes:
> Using a "constant" kind of pointer instead, such as a symbol (following
> the example: 'sword-of-doom), avoids any "dangling reference" problem,
> but adds unnecessary syntax all over the place:
>
> (item-name (symbol-to-item (ci-item-symbol ci)))
>
> I can think of a few ways to solve the syntactic issue, but I'd like to
> get some input on what's the "lisp way" of dealing with this situation.
Indirection via a symbol is the approach taken with DEFUN
and FUNCALL. Funcall expects a function object, but if it
finds it has been passed a symbol it looks it up in the
global function namespace.
CL-USER> (defun f () 'outer)
F
CL-USER> (flet ((f () 'inner))
(list (funcall #'f)
(funcall 'f)))
(INNER OUTER)
So I think the "lisp way" is to indirect via a symbol, and
deal with the syntax issue by using the dynamic typing and
hiding the symbol-to-object conversion in the accessor
function, eg
(defun item-name (item)
(when (symbolp item)
(setf item (symbol-value item)))
(check-type item item-type)
;; now the item is really an item
;; and is up to date
(extract-name item))
Alan Crowe
Edinburgh
Scotland