Stream: ideas

Topic: Path.read_utf8! and roc-lang/path


view this post on Zulip Richard Feldman (Jan 28 2025 at 05:03):

the platform-agnostic roc-lang/path package contains a Path module which is all pure functions and has nothing to do with effects

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:04):

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!

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:04):

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

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:04):

this makes it equally concise to call one or the other (depending on whether you have a Path or a Str)

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:05):

(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)

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:07):

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

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:07):

however, I did end up realizing there's a pretty simple solution!

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:08):

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:09):

in this design, instead of doing:

import cli.File
import path.Path exposing [Path]

...I just do:

import cli.File
import cli.Path exposing [Path]

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:09):

...and I'm all set!

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:09):

or at least, I'm all set in the static dispatch world :sweat_smile:

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:10):

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!

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:10):

Would docs for Path get exposed in basic-cli?

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:10):

If so, this makes a ton of sense

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:11):

That doesn't seem to be the current plan for docs rendering of aliases

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:11):

I think it's fine if the docs just say "type alias of [link]"

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:11):

that way you know where the original is

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:12):

actually I'd like to do auto-linking

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:12):

which would take care of that

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:12):

Probably fine, but auto-linking would be way better, yeah

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:12):

I think it's useful to have one source of truth for the docs rather than having them auto-duplicated

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:12):

because if they're linked, you can't mistakenly think the original is defined somewhere else

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:13):

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

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:13):

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

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:13):

yeah

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:13):

it's the only design that makes sense I think

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:14):

when we have an index, we can do something different

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:14):

but even in that world, we still need to support publishing without publishing to the index

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:14):

and for that use case, generating the docs for all dependencies (recursively) seems like the only way to get all your docs

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:14):

It's not great for duplicating a bunch of files, but it's just HTML

view this post on Zulip Richard Feldman (Jan 28 2025 at 05:15):

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

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:15):

Okay, I don't think we do that today. We should make an issue for docs gen

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:16):

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

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:16):

Great minds think alike

view this post on Zulip Sam Mohr (Jan 28 2025 at 05:16):

Or is it fools seldom differing?

view this post on Zulip Brendan Hansknecht (Jan 28 2025 at 06:41):

"All because great minds think alike doesn't mean mediocre ones don't" - My dad...all the time when I was growing up.

view this post on Zulip Jasper Woudenberg (Jan 28 2025 at 07:47):

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.

view this post on Zulip Sam Mohr (Jan 28 2025 at 07:49):

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

view this post on Zulip Jasper Woudenberg (Jan 28 2025 at 07:51):

Sorry, I don't completetely understand Sam, I don't think there's different types with the same name at play here, right?

view this post on Zulip Luke Boswell (Jan 28 2025 at 09:12):

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?
"

view this post on Zulip Sky Rose (Jan 29 2025 at 01:54):

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.

view this post on Zulip Richard Feldman (Jan 29 2025 at 02:02):

I agree that would be simpler, but I couldn't find names I liked :sweat_smile:

view this post on Zulip Richard Feldman (Jan 29 2025 at 02:03):

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