Proposal: System.FilePath: current directory should be ".", not
""
Simon Marlow
marlowsd at gmail.com
Wed Sep 23 09:17:58 EDT 2009
On 22/09/2009 16:43, Duncan Coutts wrote:
> On Mon, 2009-09-21 at 12:00 +0100, Simon Marlow wrote:
>
>
>> The main change is that
>>
>> splitFileName "foo" = (".", "foo")
>>
>> and
>>
>> takeDirectory "foo" = "."
>>
>> and
>>
>> "."</> x = x
>
> So to re-iterate the point made in the ticket, the principle here is
> that the representation of the current directory is "." and not "". This
> lets us safely use results of System.FilePath functions as arguments to
> system and directory functions without having to check for "".
>
> However the principle is not without exception, we also want to elide
> the explicit representation of the current directory when it is not
> needed.
>
> If these are the principles then can we look at whether we apply them
> elsewhere in System.FilePath consistently?
>
> What about:
>
> joinPath [".", "foo"]
>
> should it be "./foo" or "foo" ?
>
> If "./foo" then it's not the same as</>, if the latter then we loose
> the property
>
> Valid x => joinPath (splitPath x) == x
>
> it would be some kind of limited normalisation.
>
> So I'm happy with the first two changes, I'm less convinced about
> changing</> to elide "." on the left. Perhaps people who worry about
> leading "./" when the FilePath is displayed to the user should just use
> normalise. That's what they do now and we seem to get along ok.
So this subject was discussed between Ian and myself in the original
thread, see e.g.
http://www.haskell.org/pipermail/libraries/2007-December/008776.html
The conclusion was that in the filesystem semantics "./foo" is equal to
"foo", but the string passed to rawSystem (and execp()) is not a
FilePath, it is something like Either FilePath String.
However, there are some oddities with the current proposal. e.g.
splitFileName "./foo" == ("./", "foo")
"./" </> "foo" == "./foo"
The current proposal just about hangs together because the tiny bit of
normalisation that </> does exactly undoes the creation of "." in
splitFileName, and there's no other way that splitFileName can generate
".". That's a terribly fragile property.
If we "fixed" </> to do more normalisation, then we would no longer have
the property that
uncurry (</>) (splitFileName x) == x (*1)
I don't actually care about the details here as long as we have a story
that is reasonably consistent. My main concern is that
isValid x => isValid (takeDirectory x)
the lack of which is the main problem with the current formulation, as
you (Duncan) mentioned above.
Perhaps we should drop the magic normalisation that </> does, and apply
the normalise function to both sides of (*1). There would probably be a
bunch more properties that would have to change too, I'm guessing that
normalise would proliferate.
Incedentally, I dislike the way that trailing slashes are treated in the
current filepath implementation. A trailing slash is significant in POSIX:
$ ls -l foo
lrwxrwxrwx 1 simonmar GHC 15 2009-09-23 14:04 foo -> /does/not/exist
$ ls foo
foo@
$ ls foo/
ls: cannot access foo/: No such file or directory
The path with the trailing slash dereferences a symbolic link, and may
fail if the link points nowhere.
I think trailing slashes should be dropped by splitFileName.
Cheers,
Simon
More information about the Libraries
mailing list