The AS and TO distinction feels very clarifying, and I think it's a winner. But there are some inconvenient truths, and a question of how to mitigate potential problems.
Under this system, we understand that AS aliasing doesn't make a copy by default:
>> text: copy "foo"
>> file: as file! "foo"
== %foo
>> append file "bar"
== %foobar
>> text
== foobar
So you need to be sensitive about whether you need to make a COPY or not. Seem fair enough--and COPY AS TEXT! reads fairly light and literately.
But now remember the angle is that if you're not using AS, then the TO conversion will assume you meant the delimiters were part of the deal. This is why TO TEXT! on a tag will give you the angle brackets in the series. And it's also why TO FILE! on TEXT! will assume you meant you wanted the quotes, however that winds up presented:
>> file: to file! "foo"
== %^"foo^"
>> first file
== #"^""
>> second file
== #"f"
This is not completely outlandish...especially when you consider that quotes are legal in filenames in linux.
But there's been an idiom in practice something like this:
foo: func [
item [file! word! path!]
"Will be converted to file!
][
file: to file! item
...
]
Under the new rules you can't write this with AS FILE!, because a PATH! is an array. So in that case, cannot be aliased as a string, you really do need a conversion. But if you use TO FILE! under these rules you'll end up getting the % character in it, if it was a file to start with!
>> to file! %foo
== %^%foo
So you'll end up writing:
if match [word! path!] file [
file: to file! file
]
Though that gives you a situation where it's a unique copy only if it was a WORD! or PATH!. To get a new copy in all situations:
file: either match [word! path!] file [
to file! file
][
copy file
]
In a way, I think that what this is doing is "weird" enough that it should take responsibility for its weirdness. Think of the following list--which is similar to the motivating example in Rebol's make process:
source-files [
%foo.reb
bar.reb
mumble/foo.reb
mumble/"bar with spaces.reb"
%mumble/frotz.reb
"stuff.reb"
]
There you've got a FILE!, a WORD!, a PATH! with two words, a PATH! with a word and a string, a FILE!, and a STRING!. It's hard to argue that you get much closer to a solution when TO FILE! of something that is already a FILE! is a no-op, especially when it breaks the other advantages.
What if MAKE of a type to itself was always a COPY?
There's a third place we might look to, which is the infamous MAKE. Where TO is similar to casting/conversion in other languages, MAKE's concept is more like construction from a loosely defined "spec". The difference between TO and MAKE has been debated (it seemed rather ad-hoc), but it's known that to string! 10 would give you "10", while make string! 10 could give an empty string with 10 units of data in it.
Given MAKE's nebulous nature, might it be the missing link here, so that MAKE FILE! on something that was already a FILE! would leave it as-is...and could it be creative with the interpretation of PATH!s, STRING!s, and WORD!s? We might even force that MAKE SOME-TYPE! of a value of type SOME-TYPE! would just copy it. It may not be a ton of terra firma, but it means you'd only have to worry about the way MAKE would be interpreting types other than what you gave it.
(Note: This would be giving MAKE a rule similar to C++ handling of static_cast conversions. You can't write a cast operator of a type to itself, just to any other type. Just interesting to look at parallels in other systems.)
And there's an advantage to going this route. It's compatible with R3-Alpha, Rebol2, and Red:
>> make file! %foo
== %foo
>> make file! %foo/bar
== %foo/bar
>> make file! "foo"
== %foo
Given that this option exists, it seems there's no good reason to undermine the initiative for to text! "abc" to be {"abc"}. All it means is people would have to use MAKE in places they previously expected to use TO, sometimes.