On Thursday, 6 June 2013 at 15:36:17 UTC, Walter Bright wrote:
I've succumbed to the temptation to do this several times over the years.

I always wind up backing it out and going back to strings.

The objections have all been already mentioned by others in this thread. I understand the motivation for doing it, it seems like a great idea,
Yay!
but I am strongly opposed to it.
Oh.

To repeat the objections:

1. Making a more 'palatable' interface is pretty much chasing rainbows. It really isn't better, it is just different. In many ways, it is worse because it cannot hope to duplicate the rich interface available for strings.

.toString ?

2. APIs that deal with filenames take strings and return strings, not Path objects. Your code gets littered with path and filename components that are sometimes Paths and sometimes strings and sometimes both.

As for APIs that return strings, a `Path toPath(string)` function could be added in std.path? Another solution would be to migrate the parts of Phobos that use path strings to using actual paths. They could be overloaded with a counterpart that also takes a string, but the toPath function would be pretty useful here.

3. Every time you deal with a filename or path, you have to decide whether to use a Path or a string. This may seem like a small thing, but when writing a lot of code to deal with paths, this becomes a fracking annoyance.

If there should only be one API used, I'd suggest just use Path.

4. An awful lot of path manipulation is done using string functions. Ever do regexes on paths? I do. But regex deals with strings, not Path objects. Ditto for the rest of the universe of code that deals with strings.

Path implicitly converts to a string.

5. You wind up with two parallel universes of functions to deal with paths - one dealing with strings, one with Paths, oh, and a third universe of crap that deals with mixed strings and Paths.

Well, I didn't say this in my OP, but I did a few comments back: I'm more partial to deprecating the string API and moving to Path. I didn't think many would go for this, but the more I think about it, the more I realize how little code would break, and how easy it'd be to fix that.

6. If you try not to do (5), you break all existing code.

7. People like writing paths as "/etc/hosts", not Path("/etc/hosts"). People will not stand for a Path constructor that winds up allocating memory so it can rewrite the string in a canonical path representation.

string s = "/etc/hosts"
Path s = "/etc/hosts"

It even takes less chars :-P and it only allocates on Path == Path and Path == string comparison. Which would have been done manually anyways.

8. There really isn't any such thing as a portable path representation. It's more than just \ vs /. There are the drive prefixes in Windows that have no analog in Linux. Sometimes case matters in Linux, where it would be ignored under Windows. There are 8.3 issues sometimes. The only thing you can do is come up with a subset of what works across systems, and then of course you have to go back to using strings when you need to access D:\foo\abc.c

Well, that's not so much a limitation of Path or path functions as much as it is with the operating systems themselves. You still run into that with strings. I'm not trying to do anything groundbreaking, just abstract away the concept of a path so it's easy to write larger applications.

9. People think about paths in terms of strings, not Path objects. Adding an abstraction layer always produces the feeling of "what is it doing, is it allocating memory, is it slow, is it doing something clever that I don't need/want?". This is cognitive baggage, and interferes with writing clear, correct code.

It's easy to think about a path as a string for trivial code. Once the application uses paths in a nontrivial manner, people write wrappers around path functions anyways. Type safety is very useful. Good practice says don't worry about the implementation of what you can't see. If the programmer is worried about the speed of the abstraction, deal with that separately. FWIW, the Path wrapper doesn't allocate unless it needs to :-)

Reply via email to