NewPath Rising: Call for Examples

A proposal from 2014, before Ren-C existed, was NewPath. (yes, it was a very intentional Scanner Darkly reference)

I was talked out of wacky decomposition of URL! into PATH! with a SET-WORD! at the head, etc. @rgchris convinced me that URLs should be left "as-is", so you could copy and paste them between the browser and your script. At his direction, Scan_URL was changed to commit more fully to this than Rebol2/Red/R3-Alpha...see the comments there

But I think FILE! is a different case. For one thing, it's not standardized...spaces are legal, sometimes forward-slashed, sometimes back-slashed. Double quotes are legal even on Windows, basically everything legal on Linux. So if you want to grab a string out of your terminal session and paste it in source, your best bet is pretty much to {W:rap\it in\curly \"braces\".txt}

It seems to me the dream of FILE! achieving something great that TEXT! alone can't do has not been fulfilled, and is largely un-fulfill-a-ble. Pigeonholing Windows file paths to get stored in formats as %/c/Wherever instead of using "C:\Wherever"...just to get the FILE!-vs-TEXT! datatype bit when you LOAD...seems like a fool's errand to me--it's not that great a bit!! If it's not a manipulable structured PATH! then what was that work for, anyway? You lost the ability to copy/paste into your terminal...and got nothing for your trouble.

My growing suspicion is that we may want to scrap FILE! as a string datatype with weird behavior. Instead, start from a basis of using % as an escape character, to where %foo is just an escaped WORD! and %foo/bar is an escaped PATH!

one-file: %foo/bar.txt
some-files: [
    "Directory With Spaces"/"File With Spaces.txt"
alt-one-file: lit foo/bar.txt // LIT would behave like historical QUOTE

Carl himself went down this road. See the %file-list.txt from R3-Alpha When you stop thinking about the percent sign, you perhaps see more opportunities.

Living in a world without FILE!, but with NewPath

Many ingredients that weren't around in NewPath's time are now in Ren-C. PATH!s can feature GROUP!s and BLOCK!s, even in the first element position. You can put arbitrary strings in them, with spaces:

>> load {(a b c)/"d e f"/[g h i]/<j k l>} 
== (a b c)/"d e f"/[g h i]/<j k l>

My question is if we can do a thought experiment: pretend you never knew about FILE!, and all Rebol had was TEXT!, generic escaping (consider trying %), and these modern path parts. How satisfied could you be, with what pre-cooked helpers?

Can people find examples of code that manipulates and operates on filenames, and look at that problem from a fresh start? What kind of toolset would build up from it?

>> flag: true
>> root: %foo
>> base: %bar
>> extension: %.txt
>> file-to-local/full %(root)/(subdir)/(if flag [%skip])/[base "." extension]
== "C:\Projects\foo\baz\bar.txt"

It would be a wave of disruption to change % into escaping, that we're not ready for with an unproven idea. So you'll have to use your imagination, and pretend backslash or whatever is percent.

I know from experience that this is a problem space fraught with edge cases and issues. The old code has problems, and new code can't wish them away. But the code has never been in a better position to try and tackle this area with new tricks. So hopefully someone can dig up real examples and NewPath can get the shot it deserves.

1 Like

I see a similarity with TCL where all is text interpreted by context but it provides functions to build paths in text variable from lists. It's a try to hide the platform specific format of paths.

It's been a very long time since I've used TCL (> 20 years). If you're familiar with some relevant examples, could you write a few down to illustrate notable behaviors? If you can post new threads, we have a Foreign Inspiration category...otherwise here is fine.

NewPath has been on the back burner, but it's time to up the game on filenames one way or another.

I've come to accept that FILE! is a string currency to be used, and so you will not use PATH!s directly to open files with. So if you have a path in your hand, you will MAKE FILE! out of it.

But this should have some exciting possibilities, especially with TUPLE! in the mix:

make file! '(dir)/subdir/["file-" num].txt

MAKE FILE! can be smart enough to execute GROUP!s and perform UNSPACED on BLOCK!s. The composition behavior can intelligently vaporize path segments on NULL, as it does today:

>> compose 'a/(if true ['b])/c
== a/b/c

>> compose 'a/(if false ['b])/c
== a/c

This is the kind of coherent structural control I've been wanting.

Explicit MAKE FILE! should replace today's hacks like:

>> dir: %/home/files
>> path: dir/subdir/file.txt
== %/home/files/dir/subdir/file.txt

That notion of "path selection out of a file implicitly stringizes the remaining portion of the path and appends it" never sat well with me. It's much better seen as COMPOSE-like than as anything SELECT-oriented. Trying to define how path dispatch works is made that much more exasperating when you have it doing crazy things like this.

Biggest Issue to Sort is Slash Merging

So the one thing that's been on my mind is how to reconcile the cool NewPaths with the general policy that directories end in / while files do not. I want to see this sanity checked.

You can't just use COMPOSE for that, because it is a purely mechanical thing that does what you ask:

>> dir: 'some/where/

>> compose '(dir)/file.txt
== some/where//file.txt

That's great for the low-level behavior, but undesirably lax for files. :frowning: I feel like MAKE FILE! needs to guarantee you don't double up slashes, and it should use it as a kind of "type checking" to make sure you are doing it right.

This can be addressed without NewPath, if you used a BLOCK! and had a dialect where the / were special, and you either used it or didn't based on knowing whether the directory had

>> num: 1020
>> dir-with-slash: %dir/
>> dir-no-slash: %dir

>> make file! [(dir-with-slash) ["file-" num].txt]
== %dir/file-1020.txt

>> make file! [(dir-no-slash) ["file-" num].txt]
** Error: Missing slash in MAKE FILE! on (dir) as %dir

>> make file! [(dir-no-slash) / ["file-" num].txt]
== %dir/file-1020.txt

That's pretty slick. It's a little unfortunate that NewPath comes so close, but because it provides its own biases the slash presence the wrong way. :frowning:

Maybe the compromise one could take here is that PATH-based MAKE FILE! enforced slashes on spliced FILE! or PATH! non-terminals... but was more liberal with TEXT! or INTEGER!. And maybe you could use TEXT!, as long as they didn't contain they'd be wordlike.

I think something cool is coming together here, so let's see where it goes. Having the alternatives to use either a PATH! if you're following all the terminal slash rules (for anything that isn't just text), or a BLOCK! to get more control, sounds like it may be a place to start.

1 Like

No more 'Linux: everything is a file' but 'everything is a path'.