Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

variable trouble in lisp

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!

like image 687
smackcrane Avatar asked Jun 14 '11 23:06

smackcrane


People also ask

Are there variables in Lisp?

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.

Which types of variable are used in Lisp?

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.

How do you give a variable a value in Lisp?

Since there is no type declaration for variables in LISP, you directly specify a value for a symbol with the setq construct.

How do you change a variable in a Lisp?

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.


1 Answers

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...

like image 87
6502 Avatar answered Nov 15 '22 08:11

6502