At Thu, 10 Jan 2019 09:06:50 -0800 (PST), "David K. Storrs" wrote:
> Hm. I'm not seeing it. Perl, Python, and (ugh) Java can all handle
> strings for paths and manage them portably. (e.g. Perl will understand
> that, when on Windows, "/foo/bar" should be equivalent to "\\foo\\bar".)
> Sure, if you pass "/usr/bin/touch" to a freshly-installed Windows box it
> will tell you to take a hike because none of the elements of that path
> exist. That's not the point. If you pass a string that models a path that
> is valid on a machine then it should work regardless of OS. Granted,
> Windows is a bit of a special snowflake in that "/foo/bar" is relative to
> the current drive on Windows but absolute on a Unix box. Still, provided
> that I manage my expectations correctly and ensure that the necessary file
> structures exist, I see no reason why it shouldn't work.
No, Windows paths are not remotely that straightforward. As the
simplest example I can think of, "//for/bar" is completely different
from "/foo/bar". If you manipulate the Windows path "//foo/bar" as a
Unix path, then you might end up thinking that the directory path
"//foo" or "/foo" is a prefix of "//foo/bar" (which is a UNC drive).
Another example: suppose that you read "C:/foo " (with a trailing
space) from some input, where pretty much all Windows tools all
recognize as a reference to a "foo" directory on your "C:" filesystem.
If you then simply append "/bar" to that string then, you don't get a
path that refers to the "bar" file in "foo", because "C:/foo /bar" has
a space in the middle, and that's different than a space at the end.
Replace " " with "."; same deal.
Of course, if you want to directory refer to a directory named "foo "
with a trailing space, you can do that by using the form "\\?\c:\foo "
--- because "\\?" means "no, really, I meant it", and it changes how
"/" and "\" work. (I am leaving out the escaping "\" needed to render
those as Racket strings.) And "\\?\" has its own parsing rules.
If your program somehow only needs to generate paths and never needs to
consume any path --- not even though `current-directory` --- then you
can probably stick to a subset of pathnames where string functions and
"/" will work. Otherwise, Racket's path API is trying to help you see
where you're doing it wrong.