Another long-tail stand: No backslashes in FILE!

There is behavior in Rebol2 and R3-Alpha where the scanner just automatically flips backslashes into forward slashes in FILE!

rebol2>> %C\Projects
== %C/Projects

That's the kind of random fiddling that I call "the worst answer". Red preserves the backslashes as-is, which is at least a slight improvement:

red>> %C\Projects
== %C\Projects

But one theoretical benefit of being able to paste your file paths "as-is" is missing, because colons aren't legal:

red>> %C:\Projects
*** Syntax Error: (line 1) invalid word at :\Projects

Could Restricting FILE! Be A Selling Point?

For whatever it's worth, UNIX does allow you to have backslashes in filenames. (They typically have to be escaped (as \\) in shell commands.)

But mechanically speaking, FILE! does not need to be able to contain all characters...because TEXT! is the currency used for naming local files. Red follows this convention:

red>> to-local-file %a/b/c
== "a\b\c"  ; on Windows

But it does this regardless of if you give it a FILE! or a TEXT! as input:

red>> to-local-file "a/b/c"
== "a\b\c"

Ren-C doesn't do this, and instead says that TO-LOCAL-FILE only works on FILE!...(unless you use the /PASS refinement, in which case TEXT! is allowed to pass through unmodified):

ren-c>> to-local-file "a/b/c"
** Error: Filename already in local format (as a TEXT!), use /PASS to allow

ren-c>> to-local-file/pass "a/b/c"  ; pass-thru
== "a/b/c"

I think this suggests a means for sanity checking to prevail. FILE! can be a tool for righteousness.

What to do if you have a weird filename

If you're making some kind of dialect with filenames in it, and you want to give people the ability to copy/paste literally things like "C:\Projects\red\README.md", you use TEXT!.

file-list: [
    %ren-c/README.md
    "C:\Projects\ren-c\LICENSE"
]

Maybe you have to decorate the TEXT! with something like <file>, if you have other baseline uses for strings in the dialect.

Then when you're writing your code and find you have a filename in a TEXT! you have these options:

  • With "sane" filenames, just use LOCAL-TO-FILE to get a FILE! out of it. If you have something in your hand that's either a FILE! or a TEXT!, then use LOCAL-TO-FILE/PASS. This should work for "sane" filenames and handle most cases.

  • With "insane" filenames, your first instinct should be to just FIX them So let's say you have something like this on UNIX:

    file-list: [
        %/usr/local/bin/gcc
         "/home/crazy\file"
    ]
    

    Just drop out to your OS shell and rename it with whatever tools you've got, mv crazy\\file sane-file. Or automate it with CALL out to the shell, if you like. We did you a solid by making LOCAL-TO-FILE refuse to call that a FILE!, and the world is a safer place.

  • If you insist on keeping the file with its name and still operating in it, then manually use mechanisms that let you specify PORT! with TEXT!. I don't know what the exact syntax of this is, but it would be in the spirit of:

    p: make port! compose [type: 'file name: (crazy-filename-as-text)]
    data: read p
    close p 
    

    So that takes the place of the failing call to read file-to-local/pass crazy-filename-as-text which refused to make the FILE!.

I Think These Bold Moves are The Point

Software has gotten so bad that we never know what's going on. Some people just pile on layer after layer of filter...like the people who use ad blockers, and pass on URLs of crappy sites to others not knowing what version of it they're going to see.

Experienced programmers (or at least old ones who remember The Times Before) have a sense of when things have gone beyond control. I think the long tail of development is that people shake down systems to try and get sanity out of them with guidelines that become common-sense ("don't put backslashes in filenames").

Here we have an opportunity with a data type that doesn't exist in nature, the FILE!. We can make it discern from raw TEXT!. And we can ask you to keep unprincipled things as TEXT!...letting those people with edge cases pay for it, and letting everyone else breathe easier.