red / red

Red is a next-generation programming language strongly inspired by Rebol, but with a broader field of usage thanks to its native-code compiler, from system programming to high-level scripting and cross-platform reactive GUI, while providing modern support for concurrency, all in a zero-install, zero-config, single ~1MB file!
http://red-lang.org
Boost Software License 1.0
5.55k stars 411 forks source link

`make object` vs `copy object` inconsistency in index handling #4810

Open hiiamboris opened 3 years ago

hiiamboris commented 3 years ago

Describe the bug

Inner series are copied differently:

Expected behavior

I prefer copy scenario as it is less surprising and is lossless, while after make any logic that relied on changed index becomes broken.

Platform version

Red 0.6.4 for Windows built 20-Dec-2020/21:04:56+03:00 commit #7a6d9a9

Related: https://github.com/red/red/issues/4533 https://github.com/red/red/issues/4523

dockimbel commented 3 years ago

The object copy does not seem consistent with copy on series:

>> a: "string"
== "string"
>> b: next a
== "tring"
>> head copy b
== "tring"

So the make behavior should be privileged then, as it is more consistent with overall copy semantics.

hiiamboris commented 3 years ago

I disagree. copy and copy/deep are consistent:

>> o: object [s: next "1234"]
>> p: copy o
>> q: copy/deep o
>> head p/s
== "1234"
>> same? p/s o/s
== true
>> head q/s
== "234"

>> b: reduce [next "1234"]
== ["234"]
>> c: copy b
>> d: copy/deep b
>> head c/1
== "1234"
>> same? b/1 c/1
== true
>> head d/1
== "234"

make behavior seems less useful. This is what I hit in my https://gitlab.com/-/snippets/2066140 experiment. I needed a copy of this object:

    object [
        width: either pair? size [size/x][0]
        part:  none
        data:  make [] either pair? size [size/y * size/x][size]
    ]

But with width field changed, and data remaining the same. make old [width: new] looked like obvious solution but it didn't work, so I had to copy it. Current make seems to work like copy/deep, whereas in Rebol it worked like copy.

OTOH if we look into the series inside function bodies https://github.com/red/red/issues/4533 https://github.com/red/red/issues/4523 that's quite a design question how to make it all consistent and still useful...