Stream: ideas

Topic: import builtins


view this post on Zulip Richard Feldman (Dec 31 2025 at 18:56):

I'm coming around to the idea that, like Zig and Rust do, we should make builtins (Str etc.) be explicitly imported - e.g. import roc.Str to bring Str into scope.

view this post on Zulip Richard Feldman (Dec 31 2025 at 18:57):

I remember back when we were upgrading to a new Elm version that had breaking changes in the String module, it was really useful to be able to do import FutureString as String to incrementally migrate the code base over, and then once we finally had everything working with FutureString, all we had to do to upgrade was bump the Elm version number and delete all the import FutureString as String imports

view this post on Zulip Richard Feldman (Dec 31 2025 at 18:57):

we don't support import FutureStr as Str in Roc because that would shadow Str, and I don't want to introduce shadowing of imports like that

view this post on Zulip Richard Feldman (Dec 31 2025 at 18:59):

also, static dispatch means that it's pretty easy to write an entire script that never needs to import these because it doesn't use type annotations and otherwise has no need to call things in a qualified way - e.g. https://gist.github.com/rtfeldman/81d906afed8142dba5eecee01df95e05 would not even be affected by this change

view this post on Zulip Richard Feldman (Dec 31 2025 at 19:02):

the main downsides as I see it would be:

view this post on Zulip nandi (Dec 31 2025 at 19:03):

Richard Feldman said:

I had this exact thought process when I read this

view this post on Zulip nandi (Dec 31 2025 at 19:05):

Richard Feldman said:

This thought process also came up as I was reading, but I couldn't figure out how people could actually implement a different stdlib since they are builtins.

view this post on Zulip nandi (Dec 31 2025 at 19:08):

The one hesitation I have is that since roc proper is so small what is there to actually be gained by a new implementation of builtins that a platform or module couldn't provide, although I like the FutureStr idea since that isn't technically external to the project

view this post on Zulip Richard Feldman (Dec 31 2025 at 19:18):

nandi said:

Richard Feldman said:

This thought process also came up as I was reading, but I couldn't figure out how people could actually implement a different stdlib since they are builtins.

just different APIs that wrap the actual builtins, e.g. renaming Str.inspect to to_str etc.

view this post on Zulip nandi (Dec 31 2025 at 19:26):

Still kinda confused how something like import Str maps to wrapping to_str

view this post on Zulip Sky Rose (Dec 31 2025 at 19:46):

The issue isn't just the time to type the extra boiler plate, it's also that every time you forget to put it in, you have an extra cycle where you have to read a compiler warning, fix it, and recompile. That would happen all the time to beginners and experts alike, and would be pointlessly frustrating.

The benefit of smoother migrations are much rarer. If it really is important, I think allowing shadowing default imports, while theoretically a messy compromise, would likely be less pain for people overall.

view this post on Zulip Richard Feldman (Dec 31 2025 at 19:48):

fair point!

view this post on Zulip Brendan Hansknecht (Dec 31 2025 at 22:10):

I personally don't see much of a reason for this. Wouldn't mind it, but I don't think I have ever found this valuable in rust or zig.

view this post on Zulip Brendan Hansknecht (Dec 31 2025 at 22:11):

We technically could allow import FutureStr as Str while still having Str automatically import otherwise. I think python does some of this with importing from __future__.

view this post on Zulip Brendan Hansknecht (Dec 31 2025 at 22:11):

Given this is so rare, either is fine to me.

view this post on Zulip Luke Boswell (Dec 31 2025 at 23:00):

I like having them imported by default, it seems like a really niche use case to be able to rename them. Is there another way to deal with that, like Roc language editions or something.

view this post on Zulip Richard Feldman (Jan 01 2026 at 00:02):

editions generally work on the entire code base...the use case is being able to migrate individual files one at a time across the code base

view this post on Zulip Richard Feldman (Jan 01 2026 at 00:02):

hmmmmmm actually

view this post on Zulip Richard Feldman (Jan 01 2026 at 00:04):

if we do strings the way we do numbers, which is something I'd like to do anyway (e.g. you can make any type work with number literals by giving it a from_numeral method, and we can do the same for strings and from_quote) so that you can do things like have a function accept a Path or Url or Regex and yet you can give it a string literal because each of those types have from_quote methods

view this post on Zulip Richard Feldman (Jan 01 2026 at 00:04):

that would mean you could actually do the migration incrementally anyway, just give StrFuture a from_quote method, and then call StrFuture.whatever for direct calls

view this post on Zulip Richard Feldman (Jan 01 2026 at 00:05):

another language feature made unnecessary by static dispatch :joy:

view this post on Zulip Luke Boswell (Jan 01 2026 at 00:09):

Very cool

view this post on Zulip Fabian Schmalzried (Jan 01 2026 at 09:11):

Would "my-str".some_fn() still always look in builtin Str for the static dispatch function?

view this post on Zulip Richard Feldman (Jan 01 2026 at 12:01):

yeah, just like how if (0.1 + 0.2 == 0.3) defaults to Dec


Last updated: Jun 16 2026 at 16:19 UTC