Stream: ideas

Topic: How important is supporting Roc development in editors?


view this post on Zulip Jasper Woudenberg (Nov 10 2024 at 11:18):

This is a spin-off from the static-dispatch topic:
#ideas > static dispatch

The reason I'm somewhat motivated to finding an alternative for dropping module qualifiers, is that I think without them I might need to leave my current Vim setup behind and change to a more integrated editor experience. For instance:

I don't want to get into the pros and conts of qualifiers here, I'm more curious how you all see great tooling support as a "progressive enhancement" or more of a "replacement" for syntax conveniences. Like, how much value do we put in the ability to read and write Roc code when the tooling is off?

My sense is that today's integrated tooling is not at the point where it delivers consistently delightful experiences, and given the time and money that's been put into this domain I think it's not clear if that will change. Some data points from my own experience:

Which is to say, I'm excited for all the cool tooling we build in support of Roc development, and I think it's definitely possible to do better than the experiences above. But I'm also worried about betting on a future that assume the tooling is always there, because my experiences with integrated tooling so far have been so very far from delightful.

view this post on Zulip Sky Rose (Nov 10 2024 at 12:12):

I think it's really important to make it easy to write Roc even without a well-configured editor, especially because of how platforms will make it possible to support a long tail of use cases and reach some weird places. Some examples:

Both of these use cases would be worse if the language was built assuming that Roc would always be written with a good editor.

Roc has already made decisions that make the language easier to use without additional tools. It's a single binary, with built in formatter and unit testing. There's very limited configuration or manifest files. If Roc strongly depends on someone's editor setup to be configured just right, that's another place for the ecosystem to get complicated with opinions about the right setup, configuration files in weird places, or a barrier to get started before you can start writing Roc.

view this post on Zulip Brendan Hansknecht (Nov 10 2024 at 15:10):

Personally, I think it is totally reasonable to optimize for the expectation that most people will use an lsp

view this post on Zulip Brendan Hansknecht (Nov 10 2024 at 15:10):

I've written plenty of c++ and rust without an lsp. It's ok. They aren't optimized for it. If roc was in this boat, I don't think it would be much of an issue.

view this post on Zulip Brendan Hansknecht (Nov 10 2024 at 15:11):

I think having a good experience with lsp and assuming essentially everyone will be running one is a reasonable baseline.

view this post on Zulip Brendan Hansknecht (Nov 10 2024 at 15:12):

Sure it may get use without, but so do c++ and Java and etc, and people do ok.

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:23):

If we expected everyone to use a specific editor a la Kotlin, I would dislike this proposal (my life at work right now :sob:) but almost every editor supports LSPs, and even without inlay hints (which I don't use), between diagnostics, tab complete, go to definition, and type hover, I have everything I need to be a productive Rust dev

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:24):

So as long as 99% of modern devs use an editor with LSPs or equivalent integration (I don't think that's an exaggeration), designing around LSPs is fine

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:24):

I'm also not sure how GitHub's type hint system works, but even web browsing could probably be made to be easily "annotated"

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:27):

So between the assumption about how most people write code with the "guiding hand" of LSPs and my preference for legible concision when possible, no offense @Jasper Woudenberg but your wants contradict mine

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:28):

The verbosity here of qualification gets in the way of a smoother, "exploratory" writing experience

view this post on Zulip Jasper Woudenberg (Nov 10 2024 at 15:29):

Sam Mohr said:

The verbosity here of qualification gets in the way of a smoother, "exploratory" writing experience

Can you say more about this? I'm curious what the conflict is you see here.

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:38):

What I mean by this is that, like Helix over Vim, I need to do less planning ahead when using unqualified method chains to achieve my goal, whereas the current module qualified approach requires knowing where I'm going next a bit more

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:42):

Currently, I need to say "when I create a weaver.Cli.SubCmd, and then .finish it, (which of course is really Cli.SubCmd.finish) that converts to a weaver.Cli, meaning my next calls need to be in the shape Cli.xyz, like Cli.validate or whatever

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:42):

So I need to consider my destination type-wise when writing code

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:42):

Not necessarily a bad thing to encourage

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:43):

But that's because I know what I'm working towards

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:43):

Someone using a builder API that's unfamiliar to them likely won't know which module to get which type/function from

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:44):

They'll just say Foo.build().addDate({ }) and not know that .build is in the Foo.Builder module

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:45):

So in short, devs unfamiliar with APIs don't need to know where they're ending, they just need to know where to start and they can discover an API as they use it

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:45):

I don't think you get that with the current qualification-heavy system

view this post on Zulip Jasper Woudenberg (Nov 10 2024 at 15:46):

That makes sense to me, and I understand and definitely don't want to get in the way of a flow where you simply type . and get presented a menu of options of where you can go next.

I'm curious how you feel the proposal I wrote in the static dispatch thread, I specifically kept that flow in mind writing it, and I was hoping it might avoid needing to choose between explicit qualifiers and exploratory writing.

view this post on Zulip Derin Eryilmaz (Nov 10 2024 at 15:46):

Sam Mohr said:

I don't think you get that with the current qualification-heavy system

There's no reason you can't have it with the current syntax though. the autocomplete just isn't strong enough right now

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:48):

@Derin Eryilmaz for it to work, you'd need to look at any function that is type compatible across all modules, even those not it scope.

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:49):

So for example, when I type Foo.build().add..., I don't have to import Foo.Builder exposing [FooBuilder] for auto-complete to know I only want functions that take a FooBuilder that start with the word "add"

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:49):

But with the current system, a function addIdentity : x -> x (contrived, I know) would fit the bill as well

view this post on Zulip jan kili (Nov 10 2024 at 15:50):

would fit the bill as well

Good, I say! If that's not a FooBuilder method, then that function would have to already be in the local namespace, meaning you're already using it nearby. ...Right? (Sorry for interrupting. :sweat_smile:)

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:51):

So two weakened options. You either:

view this post on Zulip Derin Eryilmaz (Nov 10 2024 at 15:52):

that would actually be pretty good, as long as the most "relevant" functions (stuff defined in the same module as the type) are at the top of the autocomplete suggestion

view this post on Zulip Derin Eryilmaz (Nov 10 2024 at 15:52):

i'm talking about autocompleting all type compatible functions

view this post on Zulip Derin Eryilmaz (Nov 10 2024 at 15:52):

also if we went that way, non-nominal types would also work fine

view this post on Zulip Derin Eryilmaz (Nov 10 2024 at 15:53):

but it would be really tough to implement for the compiler, i'd guess

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:53):

I think I'm seeing your point, there are two proposals here: custom/nominal types, and static dispatch

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:54):

If you assume we add custom types but not static dispatch, you still get the benefit of auto-complete

view this post on Zulip Derin Eryilmaz (Nov 10 2024 at 15:55):

i'm talking about

it would allow autocomplete for structural types too

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:56):

Yeah, okay, I think I could get onboard with a system that:

view this post on Zulip Derin Eryilmaz (Nov 10 2024 at 15:56):

exactly, i was about to add that. it should import the module and qualify with the module name

view this post on Zulip Sam Mohr (Nov 10 2024 at 15:58):

JanCVanB said:

would fit the bill as well

Good, I say! If that's not a FooBuilder method, then that function would have to already be in the local namespace, meaning you're already using it nearby. (Sorry for interrupting. :sweat_smile:)

Interrupting is totes fine, as long as you don't mind waiting a bit longer for a response :smile:

You're saying you have two pools that the auto-complete pulls from, the type's methods and everything that's type compatible already in scope?

view this post on Zulip jan kili (Nov 10 2024 at 16:06):

With the hesitation of a developer who barely uses LSPs/IDEs and still hasn't touched AI/Copilot... yes? All good OOP IDE autocomplete I've used has prioritized methods so that instance methods > class methods > parent class methods > grandparent class methods... I imagine this would be similar: methods > local functions > maybe non-local functions it knows about somehow

view this post on Zulip Sam Mohr (Nov 10 2024 at 16:07):

that last one can just be anything type compatible in the already imported modules/builtins

view this post on Zulip jan kili (Nov 10 2024 at 16:09):

#WeOOPNow. Or rather, to celebrate :snake:... #we_OOP_now.

view this post on Zulip Ayaz Hafiz (Nov 10 2024 at 18:57):

everything auto-complete related in the new proposals can be done with the existing syntax - the semantics don't change at all, since in either case you need to lookup functions that have compatible first arguments in other module scopes. The only difference is the number of chars you need to press to trigger autocomplete (which you can adjust on a per-editor basis) and what auto-complete has to do, including qualifying or adding imports.

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:45):

Jasper Woudenberg said:

Every few months I try out enabling LSP support, but so far I've always switched it off again later because it was too flaky. I've had the LSP simply not doing anything and needing to dig into editor logs, then LSP logs to find out why it's not working. Or it is working good enough for my purposes, but there's some bit not set up yet periodically spamming me with in-editor notifications that prevent me from concentrating.

this definitely resonates with me! One of the original goals of the language, which was even in the first public talk I gave about it, was about the idea of designing the language with an editor experience in mind, with the goal of pushing the boundaries of what that editor experience can be

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:47):

the biggest part of that is the idea is the idea of creating an ecosystem where packages ship with editor extensions as a cultural norm, because the language has a first-class concept of specifying editor extensions

Screenshot 2024-11-10 at 3.46.10 PM.png

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:48):

actually one of the original motivations for adding Abilities to the language was to be able to support this, so you could specify type-specific editor customizations like "here is how to render an interactive (e.g. expandable/collapsible) version of this type in an editor, such as in a debugger or repl output"

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:49):

originally I thought that the only possible way to achieve this ecosystem goal was to create our own editor, and a super common (and valid) concern of that idea was "people aren't going to want to give up their preferred editor, so good luck getting that ecosystem off the ground"

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:50):

fortunately, later I realized that if we want the editor extensions to be accessible (which I absolutely do), they would need to be specified in a high-level enough way that multiple editors could implement them anyway - or to put it another way, if my package-specific editor tooling is described in a way where a screen reader can usefully render it, then of course Vim would be able to as well, as would Emacs, Zed, etc. etc.

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:50):

this very much remains a goal!

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:51):

we haven't worked on it in awhile, but when @Zeljko Nesic and I were at GOTO Copenhagen a couple years ago, we sketched out (I think it may literally have been on a napkin at the hotel bar?) what specifically the Abilities-based API for specifying editor extensions could look like

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:52):

this is a very long-winded way of saying that building this ecosystem of "packages ship with their own package-specific editor tooling" requires that we have a certain degree of editor functionality available

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:53):

so not just "LSP" but like an actual Vim extension for Roc that implements the Roc editor extension API, and same for Emacs, and same for Zed, etc. etc.

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:54):

and I agree that language servers today tend to be pretty buggy, which was even more true back when I gave that talk, and was another motivation for wanting to build our own editor - to be able to ship an experience that actually works reliably :stuck_out_tongue:

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:55):

anyway, the reason I bring all this up is to point out that "design the language with the assumption that editor tooling will be available" has been a design goal from the very beginning

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:56):

so my view is that if the basic Roc editor experience is too buggy to use (which today means language server), then we need to fix that regardless of any other proposals, because otherwise it will be a blocker for things we've wanted to do from the outset

view this post on Zulip Richard Feldman (Nov 10 2024 at 20:57):

and long-term I wouldn't consider it a reasonable outcome to be in a world where it's like "people don't want to use Roc with editor tooling because it doesn't work reliably" - because there is absolutely no chance of building the package-with-editor-tooling ecosystem if that's the case! :big_smile:


Last updated: Jun 16 2026 at 16:19 UTC