the platform-agnostic roc-lang/path package contains a Path module which is all pure functions and has nothing to do with effects
today, platforms that do file I/O also expose a Path module which has not only these pure functions (which I'd like to move into the platform-agnostic package and out of the platforms) but also effectful functions like Path.read_utf8!
the design is that there's a File.read_utf8! which takes a Str and a Path.read_utf8! which is exactly the same except it takes a Path
this makes it equally concise to call one or the other (depending on whether you have a Path or a Str)
(Rust does this via one set of functions that accept AsPath traits, but that wouldn't work in Roc because you can't give Str oprhan instances, plus I prefer how this makes the types of each function simpler)
I couldn't think of a nice alternative name for the Path module in platforms (e.g. FilePath really harms the conciseness benefit, and Fs is concise but it's not clear why File would be the Str one and Fs would be the Path one and would be easy to mix them up), and static dispatch can't help with this
however, I did end up realizing there's a pretty simple solution!
roc-lang/path exposes a Path module of all pure functionsbasic-cli also exposes a Path modulePath.read_utf8!Path type from roc-lang/pathPath, e.g. Path.from_strin this design, instead of doing:
import cli.File
import path.Path exposing [Path]
...I just do:
import cli.File
import cli.Path exposing [Path]
...and I'm all set!
or at least, I'm all set in the static dispatch world :sweat_smile:
because in that world, just having the correct Path type (regardless of whether it's a type alias) still lets me do my_path.whatever() regardless of what's imported
and since the cli.Path module re-exposes the Path type as well as the functions to create a new Path (e.g. Path.from_str), I can still use all of them as normal too!
Would docs for Path get exposed in basic-cli?
If so, this makes a ton of sense
That doesn't seem to be the current plan for docs rendering of aliases
I think it's fine if the docs just say "type alias of [link]"
that way you know where the original is
actually I'd like to do auto-linking
which would take care of that
Probably fine, but auto-linking would be way better, yeah
I think it's useful to have one source of truth for the docs rather than having them auto-duplicated
because if they're linked, you can't mistakenly think the original is defined somewhere else
whereas if they're duplicated you might spend all your time reading the docs and not notice the subtle : that tells you it's a type alias
Hmm, does that mean that roc docs would also generate the docs for your deps and upload all of them to GitHub pages? The URLs for doc sites are not consistent for packages unless they're in the registry
yeah
it's the only design that makes sense I think
when we have an index, we can do something different
but even in that world, we still need to support publishing without publishing to the index
and for that use case, generating the docs for all dependencies (recursively) seems like the only way to get all your docs
It's not great for duplicating a bunch of files, but it's just HTML
it can be a nice feature to have anyway, because it means if you want to generate absolutely all your docs offline because you're going somewhere with limited connectivity, you can just do it in one command locally and you're all set
Okay, I don't think we do that today. We should make an issue for docs gen
By the way, I like this plan because it's what I was thinking we were gonna do for stuff like URL and HTTP being exposed by platforms like basic-cli
Great minds think alike
Or is it fools seldom differing?
"All because great minds think alike doesn't mean mediocre ones don't" - My dad...all the time when I was growing up.
I wonder if there's an extra risk in this setup of application authors being confused when statically dispatching .read_utf8! on a path type doesn't work. There's a good reason it won't work, but it's pretty subtle! The app authors would be importing a Path type from cli.Path, and read_utf8 is defined in there too. Plus, with the two same-named modules and re-exports we're not making it super explicit that there are two different modules at play, which is key to understanding why static-dispatch can't be used to call effect-functions on a Path value.
Rust has a specific error message for when two types with the same name are actually different. We'd definitely want to do the same thing to avoid your concern
Sorry, I don't completetely understand Sam, I don't think there's different types with the same name at play here, right?
I wonder if there's an extra risk in this setup of application authors being confused when statically dispatching
.read_utf8!on a path type doesn't work.
Would it be feasible for roc to check the platform, and give a nice error message;
"
Hey you're trying to us the read_utf8! but that's not defined in path.Path package.
read_utf8! is available for the similar cli.Path type, perhaps you meant to use this type instead?
"
This seems way more complicated than File.read_file_path!(path) just to save a few characters. The important thing here is the file reading, not the string vs path, so they should both be in the File module.
I agree that would be simpler, but I couldn't find names I liked :sweat_smile:
for example, File.read_utf8_path! sounds like it's reading a UTF-8 path, which is not what it's doing :grimacing:
Last updated: Jun 16 2026 at 16:19 UTC