Dedicated (sub)module for punctuation-based symbols (//, /, etc.)
What I want:
- the ability to access all the infix operators (
/,//, etc.) directly withopen Fpath.Operators; - not putting the other names in scope like
open Fpathdoes.
Usage:
open Fpath.Operators
...
let abs_dir ?(cwd = Unix.getcwd () |> Fpath.v) path =
cwd // path |> Fpath.parent
If I'm not missing an operator, the signature of the submodule would be:
module Operators : sig
val (/) : t -> string -> t
val (//) : t -> Fpath.t -> t
val (+) : t -> ext -> t
val (-+) : t -> ext -> t
end
I like the long name Operators because it makes it clear to the reader of the code that this is probably where the exotic operators come from. Since it's only meant to be used as open Fpath.Operators or let open Fpath.Operators in, it's not that frequent and doesn't need to be extremely short.
On a related note, we're experimenting with the prefix operator !! which would make !!file an alias for (Fpath.to_string file). I can make a dedicated issue or PR once I'm convinced it's a good idea.
If anything it will be Syntax but I'm not convinced in providing this. All the uses of the operators should be quite localized, so it's meant to be used with the Fpath.() notation:
let abs_dir ?(cwd = Unix.getcwd () |> Fpath.v) path =
Fpath.(cwd // path) |> Fpath.parent
Good point. In this case, I think I'd rather write this:
let abs_dir ?(cwd = Unix.getcwd () |> Fpath.v) path =
Fpath.append cwd path |> Fpath.parent
(we don't have to worry about whether Fpath.cwd or Fpath.path exist)
An alternative is to let users define their own module that provides operators. This is what we're doing right now in semgrep. It's not a huge deal because it's a large application and we already have our own custom "standard library". It's more annoying in small projects where I'd go with let (//) = Fpath.append at the beginning of each module where it's used.
Earlier, I mentioned that we use !! as an alias for Fpath.to_string because we use it widely, more so than the other operators and really makes the code lighter in my opinion. Here's an example:
open Fpath.Syntax
...
if Sys.file_exists !!file then (
...
)
Compare with
if Sys.file_exists Fpath.(!!file) then (
...
)