Hacking away on the TO and MAKE Matrix

I'm reminded of another thing I thought about which might help distinguish a TO from a MAKE. That could be that you are assured that TO won't evaluate anything you pass in. So if you said x: does [print "hi" 10] | to text! [x + 20], whatever did happen, it would not print out "hi" and come back as the text string "30".

That would limit what to text! of a BLOCK! would be allowed to do, e.g. to things like MOLD or FORM (but not "REMOLD" <gack!> or "REFORM" <gaaack!>)

As far as I know, there aren't any TOs today that break this rule. e.g. TO STRING! doesn't evaluate:

>> x: 10
>> to string! [x + 20]
== "x+20"

And even though some TOs and MAKEs fall through to each other willy-nilly, TO OBJECT! of a BLOCK! isn't one of the things that acts like the evaluating MAKE OBJECT! of a BLOCK!:

>> to object! [x: 10 + 20]
** Script Error: Cannot use to on object! value

Not being able to evaluate might help narrow down what a TO conversion still could do that's useful. For instance, to object! [...] might be like R3-Alpha's CONSTRUCT, used in loading script headers without risking doing any evaluation.

It also might suggest that so-called "construction syntax" should be sharing code with TO... not with MAKE. Consider what you get in Rebol2/R3-Alpha/Red today:

>> obj: make object! [x: quote 'foo]
== make object! [
    x: 'foo
]

>> type? obj/x
== lit-word!

If you actually ran the make object! that came back in the "molding" of the first result, you wouldn't get the same data pattern...because make object! [x: 'foo] would evaluate to putting a WORD! in foo. to object! [x: 'foo] could be work "as-is", and perhaps to object! [x: y:] could put the SET-WORD! of y: into the x key.

Really just a continuation of the brainstorming. Summary so far of potentially known things:

  1. A TO conversion won't run arbitrary code that you pass to it, or possibly A TO conversion won't even GET any variables, much less evaluate
  2. Every TO conversion targeting a series type performs a new allocation
  3. TO TEXT! 10 is "10" and TO INTEGER! "10" is 10
  4. A TO conversion of a value to its own datatype will do the same thing as COPY

One sort of sad-seeming part of accepting this so far is #4, which means TO TEXT! of something that is already a TEXT! would not be a mold, since COPY would not add delimiters. That sways the purpose of TO as being the mechanic the system uses for any "automatic" conversion.


I mentioned a potential invariant that APPEND of two non-matching types should be equivalent to converting and then appending. This would mean that TO BLOCK! of any atomic item would wrap it in a single element block, while TO BLOCK! of something that was already a block would just copy it and not add another outer layer. This would be different from history, which is

 rebol2/r3-alpha/red> to block! "foo 10"
 == [foo 10] ;-- acts as load

 rebol2> to block! #foo
 == [foo] ;-- hm, loading again?

 rebol2> to block! <foo 10>
 == [foo 10] ;-- yup, that was a good guess

 red/r3-alpha> to block! #foo
 == [#foo]

 red/r3-alpha> to block! <foo 10>
 == [<foo 10>] ;-- no LOAD here

 red/r3-alpha> to block! "foo 10"
 == [foo 10] ;-- okay, only loads if STRING!

This makes TO BLOCK! not too useful for one of its imagined purposes...to get a block out of something if it wasn't one already (e.g. for enumeration). So I'd suggest the TO BLOCK! of a TEXT! fall in line with putting the single element in a block. This gets that invariant that append [a b] "c" can act compatibly with append [a b] to block! "c".

Scanning strings to blocks would then be done with another operation.