Proposal: System.FilePath: current directory should be ".", not
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")
>> takeDirectory "foo" = "."
>> "."</> 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
> 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.
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
$ 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.
More information about the Libraries