Designing a Paths Julep

I suppose all of these points have been made already somewhere in this thread, but just my 2 cents on the different issues:

  1. Path joining and string concatenation are entirely different things that should not use the same operator under any circumstances: "root" * "folder" is "rootfolder", but Path("root") / "folder" is Path("root/folder").
  2. AFAIK, there is not a single language where the same infix operator is used for string concatenation and path joining. In fact, using / is completely universal (possibly up to Haskell, but </> is close enough). I would consider it completely insane for Julia not to follow precedent here. If you really can’t stomach / being used both for division and path joining, make it separately importable, although that seems silly to me. Or come up with something that at least involves /, the way that Haskell does (a macro @/ isn’t possible, right?). In any case, there would still be joinpath(p"folder", p"subfolder", "file.ext") for anyone who doesn’t want to use an infix operator.
  3. There is no such thing as string division (existing or planned) as an inverse to *, so there is absolutely no confusion with / as an operator on Paths. Nobody in the world would ever be confused by this.
  4. I don’t think Path("root") * "folder" (i.e., the * operator for Path objects) absolutely needs to be defined, but if it is defined, it should obviously be equivalent to Path("root" * "folder"). That is, it should implement concatenation, not joining.
  5. It’s nice to have a string-macro p"folder". I don’t know that that macro absolutely needs to support things like interpolation, but if it does, p"$root$directory$file" should be exactly the same thing as Path("$root$directory$file"). Under no circumstances is interpolation an alternative to path joining. I think all the semantics of p"folder" are pretty clear if you remember it as a shorthand for Path("folder")
  6. It would definitely be possible to have p"folder" / ("filebase" * ".ext"). It might be okay to have p"folder" / "filebase" * ".ext" without parenthesis if * already has higher precedence than /, or if we want to allow * for Path and String objects. Of course, p"folder" / "$(filebase).ext" is always okay, with the caveat:
  7. While combining path joining and string concatenation is obviously possible, for file extensions in particular, those should be part of the Path API, and should be something like p:folder" / "filename" |> with_extension("ext") to change or add extensions. With a well-designed Path API, the actual need for string interpolation or concatenation should be extremely minimal.
  8. p"relative_path" / p"absolute_path" should not be an error, but simply return p"absolute_path". This is what enables cwd / file to save a file with an absolute or relative path inside cwd, without having to make manual distinctions. I would note that, e.g., Python’s pathlib is very well-designed and has thought about details like that. It behooves us to learn from that design and the design of other proven solutions. I would strongly recommend following pathlib’s design overall, with the obvious change that in Julia, we need to design around functions, not OOP class methods.
11 Likes