I’ve previously pitched the following stakes in the ground for TO conversions:
- A TO conversion won’t run arbitrary code that you pass to it. It won’t even GET any variables, much less evaluate.
- Every TO conversion targeting a series type performs a new allocation
- A TO conversion of a value to its own datatype will do the same thing as COPY
These rules are mechanical, and aren’t saying much about what TO means “semantically”. It feels like we should be able to say that TO TEXT! 10 is “10” and TO INTEGER! “10” is 10. But it gets a bit more vague from there.
As additional guidance, I’ve also proposed a rule for APPEND and its bretheren:
“If the type of the value being appended doesn’t match the type of what you are appending to, it will act as equivalently as if it had been converted with TO into the target type first.”
So whatever append copy [a b c] 'x/y/z does, it would be the same as append copy [a b c] to block! 'x/y/z.
Should there be symmetry?
The historical ergonomics of splicing by default are not always good:
>> block: copy [a b c]
>> path: 'd/e
>> append block path
== [a b c d e]
We know that [a b c d/e] would be more useful in almost all cases. If you have a PATH! in your hand, the path-ness is likely relevant to what you want to do.
I’ve proposed weird rules like “only splice if the types match”, but that can be a bit awkward:
>> group: copy quote (a b c)
>> append group collect [keep 'd | keep [e f]]
== (a b c [d e f])
Due to their nature (and special logographic [o] status), blocks really are just a good generic carrier for material. Hence their BLOCK!-ness quite well not be that important. So here, I’d think that having to say append group as group! collect […] is kind of annoying.
So I suggested “only splice blocks” might be a more predictable-feeling rule. This way, you’re not worrying about the combinatorics of what you’re inserting and what you’re inserting into.
Merging that with the rules above would give you some asymmetry, however:
>> to block! 'a/b/c
== [a/b/c]
>> to path! [a b c]
a/b/c
>> to block! quote (a b c)
[(a b c)]
>> to group! [a b c]
(a b c)
TO BLOCK! of any non-block array would just put it into a block, while TO PATH! or TO GROUP! of a block array would act more like COPY AS PATH! and COPY AS GROUP!.
But looking a bit closer, it seems that maybe the rule should really just apply to not breaking up paths.
So what if the difference is just PATH!s?
>> to block! 'a/b/c
== [a/b/c] ;-- 1 new element when APPENDed to BLOCK!
>> to group! 'a/b/c
== (a/b/c) ;-- 1 new element when APPENDed to GROUP!
>> to block! quote (a b c)
== [a b c] ;-- 3 new elements when APPENDed to BLOCK! (splice)
>> to group! [a b c]
== (a b c) ;-- 3 new elements when APPENDed to GROUP! (splice)
>> to path! [a b c]
== a/b/c ;-- 3 new elements when APPENDed to PATH! (splice)
>> to path! quote (a b c)
== a/b/c ;-- 3 new elements when APPENDed to PATH! (splice)
This puts BLOCK! and GROUP! into the same category of “things that splice by default”. They certainly -look- more similar to each other than either looks to path due to the elements being not glued together…perhaps “spaces mean splices”?
It also reduces the likelihood of creating 1-element paths via TO (you’d only get that for 1-element GROUP!s and BLOCK!s).
It’s an asymmetry, but feels sort of explainable. Note that the AS operators are fully symmetric, and you can say copy as block! 'a/b/c and get [a b c]. So this is really just about making the TO and APPEND/INSERT/CHANGE matrix more useful.
So…are people on board with this?