I'm looking for a simple way to return a new structure which is a copy of an existing one with some fields changed, without modifying the original.
I get that you can use setf
to change the data in one of the fields, like so:
[1]> (defstruct foo bar)
FOO
[1]> (defvar quux (make-foo :bar 12))
QUUX
[1]> (foo-bar quux)
12
[1]> (setf (foo-bar quux) 15)
15
[1]> (foo-bar quux)
15
But as I stated, this essentially destroys the original data, which isn't what I'm going for.
I could of course do something like this:
(defstruct foo bar baz) ; define structure
(defvar quux (make-foo :bar 12 :baz 200)) ; make new instance
(defvar ping (copy-foo quux)) ; copy instance
(setf (foo-bar ping) 15) ; change the bar field in ping
But it seems more like a work-around than anything.
In Erlang you can do something like this:
-record(foo, {bar, baz}). % defines the record
example() ->
Quux = #foo{bar = 12, baz = 200}, % creates an instance of the record
Ping = Quux#foo{bar = 15}. % creates a copy with only bar changed
No data modified.
PS Yes I'm aware that Common Lisp isn't Erlang; but Erlang made it convenient to work with records/structures immutably, and since functional style is encouraged in Common Lisp, it would be nice if there was a similar option available.