Set script variable to list argument

Custom block, with argument "my_list"
script variable "a"
set a to my_list <== What is this doing, internally?
change a
report a

Outer block (main program)
initialize list named "list_1"
say reported value from custom block, passing list_1 as argument
say "hello"
say list_1 (which shouldn't have changed)

BUT ... list_1 has all of the changes I made to "a" in the custom block.

Are these calls by name? If so, how can I do (or simulate) a call by value?



As for all dialects of Lisp, the best way to understand Snap! argument passing is that it's by value (so, the called procedure can't assign a different value to a caller's variable), but all values in the language are of type Pointer. So if it's a pointer to a mutable data structure, the called procedure can mutate that structure. That is, if the called procedure uses the SET block to assign a different value to its formal parameter, that doesn't change anything in the caller, even if the new value is a list. But if the called procedure mutates the same list, then the list is mutated when viewed from the caller too.

If you want a (top level) copy of a list, you can use

If you need a deep copy (because the called procedure is going to mutate a list that's inside the argument list) you need a procedure: