smackcrane
smackcrane

Reputation: 1419

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!

Upvotes: 6

Views: 178

Answers (1)

6502
6502

Reputation: 114461

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

Upvotes: 7

Related Questions