I'm writing a program in Common Lisp in which I need a function with this basic outline:
(defun example (initial-state modify mod-list)
(loop for modification in mod-list
collecting (funcall modify initial-state modification)))
The problem is that I need initial-state
to be the same every time it is passed to modify
, but modify
can be destructive. I would simply make a copy, but I don't want to make any assumptions about what type of data initial-state
is.
How can I make this happen? Or is it even possible?
Thanks!
A variable is a name used in a program to stand for a value. In Lisp, each variable is represented by a Lisp symbol (see Symbols). The variable name is simply the symbol's name, and the variable's value is stored in the symbol's value cell9. See Symbol Components.
These types include integer, float, cons, symbol, string, vector, hash-table, subr, byte-code function, and record, plus several special types, such as buffer, that are related to editing.
Since there is no type declaration for variables in LISP, you directly specify a value for a symbol with the setq construct.
The usual way to change the value of a variable is with the special form setq . When you need to compute the choice of variable at run time, use the function set . This special form is the most common method of changing a variable's value.
If the function can be destructive and you cannot do anything about it then it's clear you need to make copies of initial-state
.
One possibility to avoid preconfiguring what kind of data does initial-state
contains is to leave providing a copy operation explicitly a problem for the caller or to make it a generic operation and relying on someone else to provide a method.
;; Version 1: the caller must provide a function that
;; returns a new fresh initial state
(defun example (build-initial-state modify mod-list)
(loop for modification in mod-list
collecting (funcall modify (funcall build-initial-state) modification)))
;; Version 2: copy-state is a generic function that has been
;; specialized for the state type
(defun example (initial-state modify mod-list)
(loop for modification in mod-list
collecting (funcall modify (copy-state initial-state) modification)))
The first version is more general because it allows the state to be any object while in the second version the copy operation depends on state object type (and this means you cannot have two callers both using lists as state with a different copy semantic).
However copy-state
is a general operation that can be probably used in other places and making the operation a generic increase usability (you don't need to pass around builder functions instead); it also allows the introduction of other generic operations like compare-state
, write-state
, read-state
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With