Rebol sort of had an ethos of “modify by default”…but not everywhere. REDUCE and COMPOSE made new arrays.
Typically in usage, this is what you want…as the same template of code is used many times. Saying data: compose copy [foo: (bar) baz: (mumble)] gets to be a mouthful.
So you can pretty much take for granted you get a new array out of a COMPOSE, but what about a COMPOSE/DEEP? Are things copied if no substitutions exist underneath them? What about the material that gets inserted…does it get copied?
Ren-C lets you know what’s up pretty easily, because you get an error if you try to mutate source things without copying them. Let’s try:
>> x: compose/deep [a [b c] ([d [e f]])] == [a [b c] d [e f]] >> append x/2 <1> == [b c <1>] >> append x/4 <2> ** Access Error: series is source or permanently locked, can't modify >> append x <3> == [a [b c <1>] d [e f] <3>]
The outer array got copied. Then [b c] got copied even though it didn’t technically need to be…there were no compositions underneath it. But the inserted material didn’t get copied, it was just put in as-is.
Why not have COMPOSE/DEEP only copy as-needed?
It seems that the outer level should always be copied–people tend to take that for granted.
But once you go deeper than that, why copy anything that doesn’t need a substitution underneath it? You’re not getting automatic copies of anything you’re inserting, so it’s not like there’s any big guarantee you have an all-new deep data structure.
Think of the efficiency gain if you say something like:
make object! compose/deep [ x: (...) // the one substitution y: [... [... [... [ // some huge bunch of stuff that doesn't // have any GROUP!s in it at all... ] ...] ...] ...] ]
So I’m going to change it. If anyone notices, let me know. We can always have a COMPOSE/DEEP/FULL or somesuch.
Now you’ll see this:
>> x: compose/deep [a [b c] ([d [e f]])] == [a [b c] d [e f]] >> append x/2 <1> ** Access Error: series is source or permanently locked, can't modify >> append x/4 <2> ** Access Error: series is source or permanently locked, can't modify >> append x <3> == [a [b c] d [e f] <3>]