I am looking for an easy way to return a new structure that is a copy of the existing one with some changed fields, without changing the original.
I get that you can use setfto modify data in one of the fields, for example:
[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 said, this significantly destroys the source data, and this is not what I'm going to do.
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 work 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 changed.
PS Yes, I know that Common Lisp is not Erlang; but Erlang has simplified the work with records / structures invariably, and since the functional style is promoted in Common Lisp, it would be nice if there was a similar opportunity.