June 06, 2013
On Wednesday, 5 June 2013 at 06:27:46 UTC, Dylan Knutson wrote:
> Hello,
> I'd like to open up the idea of Path being an object in std.path. I've submitted a pull (https://github.com/D-Programming-Language/phobos/pull/1333) that adds a Path struct to std.path, "which exposes a much more palatable interface to path string manipulation".
>
> As jmdavis points out, this has previously been discussed. However, I can't find that discussion, and I think that the benefits of including an OO way to deal with paths is a serious gain for the standard library.
>
> Why I think it should be reconsidered for inclusion in the std (listed in the pull):
> * Adds a (more) platform independent abstraction for path strings.
> * Path provides a type safe way to pass, compare, and manipulate arbitrary path strings.
> * It wraps over the functions defined in std.path, so behavior of methods on Path are, in most cases, identical to their corresponding module function.
>
> I'd like some feedback on what others think about this; I'd hate to see this commit closed due to a discussion that happened at a different point in D's development when the language had different needs.
>
> Thank you.

I like the idea to manipulate paths trough an object. API that taking path as parameter as better typed than with string. It's really usefull for file loaders, it's affirm the method will do path related operation and expect a particular string format.

Some methods seems miss like completeBaseName and completeSuffix.
You can take a look to : Qt API
http://qt-project.org/doc/qt-4.8/qfileinfo.html

The bad thing with the Qt API it's we can't know which method do a file system access, that why I prefer having 2 separated ojects.

It would be good to have the FileInfo object.
June 06, 2013
On Thursday, 6 June 2013 at 07:05:52 UTC, Lars T. Kyllingstad wrote:
> On Wednesday, 5 June 2013 at 06:27:46 UTC, Dylan Knutson wrote:
>> Hello,
>> I'd like to open up the idea of Path being an object in std.path. I've submitted a pull (https://github.com/D-Programming-Language/phobos/pull/1333) that adds a Path struct to std.path, "which exposes a much more palatable interface to path string manipulation".
>
> [...]

Let me add some more to this.  To justify the addition of such a type, it needs to pull its own weight.  For added value, it could do one or both of the following:

1. Maintain an isValidPath() invariant, for early error detection.  (On POSIX, this is rather trivial, as any string that does not contain a null character is in principle a valid path, but on Windows, the situation is different.)

2. Add in-place versions of path modifiers (setExtension, setDrive, etc.), for improved performance.

One solution would be for Path to be a trivial string wrapper which does (1) and not (2).  In this case, it is justified to have Path *in addition to* the existing functions.

Another solution would be for Path to do (2), possibly in addition to (1).  However, in this case it should be a *replacement* for the existing functions, and not an addition.  Otherwise, we have two almost-equal ways of doing the same thing, which should be avoided.  (I am not advocating this, however, as it will massively break user code all over again.)

Lars
June 06, 2013
On Thu, 06 Jun 2013 08:05:51 +0100, Lars T. Kyllingstad <public@kyllingen.net> wrote:
> Paths are usually obtained in string form, and they are normally passed to other functions and third party libraries in string form.  Having to convert them to something else just to do what is, in fact, string manipulations, is just annoying.

Agree 100%.

C# has Path.Combine which builds paths from strings, returning a string and this is good.

It also has System.File and System.Directory static classes with static methods taking string, also good.

But, C# also has System.IO.FileInfo and System.IO.DirectoryInfo which are constructed from a string, and then have methods which mirror the static methods from System.File plus a refresh method to update the cached file attributes etc obtained from the file system.  I find these objects useful.

It would be nice for D to have similar objects, IMO.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
June 06, 2013
On Thu, 06 Jun 2013 08:55:50 +0100, Lars T. Kyllingstad <public@kyllingen.net> wrote:

> On Thursday, 6 June 2013 at 07:05:52 UTC, Lars T. Kyllingstad wrote:
>> On Wednesday, 5 June 2013 at 06:27:46 UTC, Dylan Knutson wrote:
>>> Hello,
>>> I'd like to open up the idea of Path being an object in std.path. I've submitted a pull (https://github.com/D-Programming-Language/phobos/pull/1333) that adds a Path struct to std.path, "which exposes a much more palatable interface to path string manipulation".
>>
>> [...]
>
> Let me add some more to this.  To justify the addition of such a type, it needs to pull its own weight.  For added value, it could do one or both of the following:

Does System.IO.DirectoryInfo:
http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx

Add sufficient value to justify it's existence to your mind?

vs just having System.IO.Directory:
http://msdn.microsoft.com/en-us/library/system.io.directory.aspx

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
June 06, 2013
On Thursday, 6 June 2013 at 10:30:05 UTC, Regan Heath wrote:
> On Thu, 06 Jun 2013 08:05:51 +0100, Lars T. Kyllingstad <public@kyllingen.net> wrote:
>> Paths are usually obtained in string form, and they are normally passed to other functions and third party libraries in string form.  Having to convert them to something else just to do what is, in fact, string manipulations, is just annoying.
>
> Agree 100%.
>
> C# has Path.Combine which builds paths from strings, returning a string and this is good.
>
> It also has System.File and System.Directory static classes with static methods taking string, also good.
>
> But, C# also has System.IO.FileInfo and System.IO.DirectoryInfo which are constructed from a string, and then have methods which mirror the static methods from System.File plus a refresh method to update the cached file attributes etc obtained from the file system.  I find these objects useful.
>
> It would be nice for D to have similar objects, IMO.

It does have a similar type: std.file.DirEntry.
http://dlang.org/phobos/std_file.html#.DirEntry
June 06, 2013
On Thursday, 6 June 2013 at 10:32:36 UTC, Regan Heath wrote:
> On Thu, 06 Jun 2013 08:55:50 +0100, Lars T. Kyllingstad <public@kyllingen.net> wrote:
>
>> On Thursday, 6 June 2013 at 07:05:52 UTC, Lars T. Kyllingstad wrote:
>>> On Wednesday, 5 June 2013 at 06:27:46 UTC, Dylan Knutson wrote:
>>>> Hello,
>>>> I'd like to open up the idea of Path being an object in std.path. I've submitted a pull (https://github.com/D-Programming-Language/phobos/pull/1333) that adds a Path struct to std.path, "which exposes a much more palatable interface to path string manipulation".
>>>
>>> [...]
>>
>> Let me add some more to this.  To justify the addition of such a type, it needs to pull its own weight.  For added value, it could do one or both of the following:
>
> Does System.IO.DirectoryInfo:
> http://msdn.microsoft.com/en-us/library/system.io.directoryinfo.aspx
>
> Add sufficient value to justify it's existence to your mind?
>
> vs just having System.IO.Directory:
> http://msdn.microsoft.com/en-us/library/system.io.directory.aspx

They add great value, but that is a completely different discussion, as these are more similar to std.file.DirEntry.  The added value is mainly in the performance benefits; for example,

    if (exists(f) && isFile(f) && timeLastModified(f) < d) ...

requires three filesystem lookups (stat() calls), whereas

    auto de = dirEntry(f);
    if (de.exists && de.isFile && de.timeLastModified < d) ...

is just one.

I see no such benefit in the proposed Path type.
June 06, 2013
On Thu, 06 Jun 2013 11:43:51 +0100, Lars T. Kyllingstad <public@kyllingen.net> wrote:

> On Thursday, 6 June 2013 at 10:30:05 UTC, Regan Heath wrote:
>> On Thu, 06 Jun 2013 08:05:51 +0100, Lars T. Kyllingstad <public@kyllingen.net> wrote:
>>> Paths are usually obtained in string form, and they are normally passed to other functions and third party libraries in string form.  Having to convert them to something else just to do what is, in fact, string manipulations, is just annoying.
>>
>> Agree 100%.
>>
>> C# has Path.Combine which builds paths from strings, returning a string and this is good.
>>
>> It also has System.File and System.Directory static classes with static methods taking string, also good.
>>
>> But, C# also has System.IO.FileInfo and System.IO.DirectoryInfo which are constructed from a string, and then have methods which mirror the static methods from System.File plus a refresh method to update the cached file attributes etc obtained from the file system.  I find these objects useful.
>>
>> It would be nice for D to have similar objects, IMO.
>
> It does have a similar type: std.file.DirEntry.
> http://dlang.org/phobos/std_file.html#.DirEntry

Ahh.. excellent.  In that case, I don't think we want/need the Path being proposed.

Side-note;  DirEntry is a very UNIX centric name - I only know that because I have coded with it, I wonder what pure windows developers make of it..

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
June 06, 2013
On Thursday, 6 June 2013 at 07:26:53 UTC, Flamaros wrote:
> On Wednesday, 5 June 2013 at 06:27:46 UTC, Dylan Knutson wrote:
>> Hello,
>> I'd like to open up the idea of Path being an object in std.path. I've submitted a pull (https://github.com/D-Programming-Language/phobos/pull/1333) that adds a Path struct to std.path, "which exposes a much more palatable interface to path string manipulation".
>>
>> As jmdavis points out, this has previously been discussed. However, I can't find that discussion, and I think that the benefits of including an OO way to deal with paths is a serious gain for the standard library.
>>
>> Why I think it should be reconsidered for inclusion in the std (listed in the pull):
>> * Adds a (more) platform independent abstraction for path strings.
>> * Path provides a type safe way to pass, compare, and manipulate arbitrary path strings.
>> * It wraps over the functions defined in std.path, so behavior of methods on Path are, in most cases, identical to their corresponding module function.
>>
>> I'd like some feedback on what others think about this; I'd hate to see this commit closed due to a discussion that happened at a different point in D's development when the language had different needs.
>>
>> Thank you.
>
> I like the idea to manipulate paths trough an object. API that taking path as parameter as better typed than with string. It's really usefull for file loaders, it's affirm the method will do path related operation and expect a particular string format.
>
> Some methods seems miss like completeBaseName and completeSuffix.
> You can take a look to : Qt API
> http://qt-project.org/doc/qt-4.8/qfileinfo.html
>
> The bad thing with the Qt API it's we can't know which method do a file system access, that why I prefer having 2 separated ojects.
>
> It would be good to have the FileInfo object.

Having an object will also remove format normalization, with a string as parameter the normalization method have to always be called.
June 06, 2013
> Let me add some more to this.  To justify the addition of such a type, it needs to pull its own weight.  For added value, it could do one or both of the following:
>
> 1. Maintain an isValidPath() invariant, for early error detection.  (On POSIX, this is rather trivial, as any string that does not contain a null character is in principle a valid path, but on Windows, the situation is different.)

That's a possibility.

> 2. Add in-place versions of path modifiers (setExtension, setDrive, etc.), for improved performance.

I don't think that there'll be any performance improvements by making in place modification functions. Considering under the hood the path object is just a string, and that string's reference needs to be changed with each modification, I don't see how manipulation can be made faster.

> One solution would be for Path to be a trivial string wrapper which does (1) and not (2).  In this case, it is justified to have Path *in addition to* the existing functions.
>
> Another solution would be for Path to do (2), possibly in addition to (1).  However, in this case it should be a *replacement* for the existing functions, and not an addition.  Otherwise, we have two almost-equal ways of doing the same thing, which should be avoided.  (I am not advocating this, however, as it will massively break user code all over again.)

The more I think about it, the more partial I am to removing the existing string methods in std.path. At most, using a Path object increases number of characters typed by 6 (`Path()`). And even then, chances are you'll be saving characters as method names can be simplified to remove `path` from them: buildNormalizedPath -> normalized, isValidPath -> isValid, etc. Even with user code breaking, 1) D isn't exactly considered a stable language quite yet; I'm sure that users expect code breakage with each new release, and 2) it's trivial to convert code that uses the string based API to the object based API.
June 06, 2013
On Thursday, 6 June 2013 at 07:05:52 UTC, Lars T. Kyllingstad wrote:
> Paths are usually obtained in string form, and they are normally passed to other functions and third party libraries in string form.  Having to convert them to something else just to do what is, in fact, string manipulations, is just annoying.

Well, when designing Path, I didn't want to add much, if any, programmer overhead. Conversion to a Path is trivial: Change the type to Path, and 90% of the time it'll just work. The only case that comes to mind where a string can't be implicitly assigned/converted to a Path is when passing it to a function, in which case all it needs to be wrapped in is Path(). Or, have an overloaded version that takes a string (which all path using functions do now anyways).

> (One of my biggest gripes with boost::filesystem is that conversions between path and string necessitate a copy, which is not a problem with your Path type, so in that respect it is better than Boost's solution.)
>
>
>> [...]
>>
>> Why I think it should be reconsidered for inclusion in the std (listed in the pull):
>> * Adds a (more) platform independent abstraction for path strings.
>
> How is this more platform independent?  It is just a simple wrapper around a string, with methods that forward to already-extant module-level functions.

I should have said "makes it easier to be platform independent". Normalization is done automatically on comparison. There's nothing you can't do with normal std.path functions, but that's not the point. It's to be type safe and add convenience.

>> * Path provides a type safe way to pass, compare, and manipulate arbitrary path strings.
>
> How is it safer?  I would agree with this if it verified that isValidpath(_path) on construction and maintained this as an invariant, but I cannot see that it does.

Type safe. Once you've got a huge program with many concepts floating around, you don't want to have to keep track of which strings are paths and which aren't, and you don't want to do all the specifics like splitting, normalization, and joining with raw string functions. This isn't just conjecture either; there are D programs in the wild that abstract away path strings because it's easier to deal with them that way.
I didn't want to force paths passed in to be valid, because the programmer might want an invalid path passed around for whatever reason.

>> * It wraps over the functions defined in std.path, so behavior of methods on Path are, in most cases, identical to their corresponding module function.
>
> Then what is the added value?

See above. I didn't want to change functionality, just make it easier to use.

> As the author of std.path this may come across as hostile or jealous, but I don't see that the proposed change improves anything.

You came off as quite constructive; thank you :-)