Stream: contributing

Topic: Path.replace_utf8! (basic-cli #386)


view this post on Zulip Dzmitry Misiuk (Jul 24 2026 at 16:34):

Picking up basic-cli #386 next — read a UTF-8 file, substitute, write it back. It's pure Roc on top of Path.read_utf8! / Str.replace_each / Path.write_utf8!, so no host or glue changes.

Three things I'd rather settle before writing it:

1. Where it lives. The issue asks for both File.replace_utf8 and Path.replace_utf8, but File is now only buffered readers and all whole-file operations moved to Path. So I'd add just Path.replace_utf8! and leave File alone — matching @Luke Boswell's triage note. Worth retitling the issue too?

2. Scope. Start with the replace-all form only, mirroring Str.replace_each:

replace_utf8! : Path, Str, Str => Try({}, [PathErr(IOErr), ..])

Or add replace_first! / replace_last! at the same time, since the Str counterparts now exist? My preference is just the "each" form — that's what the issue asks for, and the others are easy to add later if anyone wants them.

3. Atomicity — the one I'd most like a second opinion on. Read-modify-write is not atomic: if the process dies mid-write, the file is left truncated. Two options:

I lean toward the first — the second is a meaningful behavior change that probably deserves its own issue covering write_utf8! too, rather than being smuggled in here. But if you'd rather replace_utf8! be the safe one by default, I'm happy to do that instead.

Minor: Str.replace_each names its arguments source, delimiter, replacement. delimiter reads a bit odd for file contents — any objection to needle/pattern, or should the platform stay consistent with the builtin?

view this post on Zulip Anton (Jul 25 2026 at 13:19):

So I'd add just Path.replace_utf8! and leave File alone

This sounds good @Dzmitry Misiuk, I have retitled the issue.

view this post on Zulip Anton (Jul 25 2026 at 13:20):

My preference is just the "each" form

Yeah, go with that.

view this post on Zulip Anton (Jul 25 2026 at 13:22):

I lean toward the first

:+1:

view this post on Zulip Anton (Jul 25 2026 at 13:23):

any objection to needle/pattern

I like pattern.

view this post on Zulip Dzmitry Misiuk (Jul 25 2026 at 20:20):

Thanks for settling all four @Anton — opened as #461. Path.replace_utf8! only, "each" form, pattern, and kept non-atomic with a doc note. Pure Roc over read_utf8! / Str.replace_each / write_utf8!, no host or glue changes.

There's a new examples/file-replace.roc that doubles as the behavioral test — it replaces both occurrences of "Hello" and asserts the exact result, so the replace-each semantics are actually checked (and I verified the assertion fails when the expected string is wrong).


Last updated: Aug 12 2026 at 12:35 UTC