I’ve released a site for a tool called Elm-pair and I’d love people’s thoughts and feedback. The tool’s pitch is this:
Elm-pair helps you write Elm code. You tell Elm-pair about the change you want to make and it will do the actual work. It’s a bit like using an IDE except you don’t need to learn any keyboard shortcuts.
You talk to Elm-pair by making a change in your code and saving it. Elm-pair will notice the change you made, and if it understands your intent will respond with a change off its own.
If that sounds interesting to you then please take a look at the site for more details and demo’s! I’d love to learn what you think of it.
Hey Jasper. I love these ideas! I also think that much more powerful environments for code editing/exploration/transformation are possible.
For example, to add to your examples of editing code, I’ve been considering some ways to explore code:
I might want to see all functions that have values of a particular type in their definition (say, to find out what the type is for)
I might want to see the definitions of all functions used in a given function (say, to refactor something across these functions)
I might want to improve documentation, so I’d want to see all the functions and types without comments attached (or maybe functions without type annotations)
I might want to clean up, so I’d want to look at a list of unused functions and other symbols like types and type aliases
I might want to evaluate my use of a package, so I’d want to see all the places where any symbols from that package appear
I might want to see all uses of a given symbol in context (eg within functions where it’s used)
I might want to review all the types in the code base (eg to see if there is duplication or field name discrepancies)
I might want to find all functions that return a particular type.
Imagine the answers to all these questions showing up in a single view in the editor (ie not as a list of search results), allowing me both to see results in context and to edit anything, eg refactoring something across a whole chain of functions or deleting unused functions, without jumping between files or scrolling around a lot.
This is probably just the tip of an iceberg! Some of this is possible now, some of this could be possible with sufficiently advanced editors. I think, however, that to take this to a logical conclusion and allow entirely new ways of working with code, it’s necessary to go beyond text. I believe that representing code as text is a limitation on how we work with it.
I like the ideas, but my main concern with the tool would be trust. It’s very much “action at a distance”, and I would be nervous about it doing unintended changes. When I use a refactoring tool in my IDE, I have a pretty good idea about what it’s going to do, and I can trust it won’t do anything aside from that. But here it’s not really obvious to me what the tool wants to do based on the changes I’m making, so I’m not sure I trust it to do what I intended to happen. For example, when I add a new argument to a function, maybe adding Debug.todo and keeping everything compiling for now is what I want, but maybe I’d rather just have the compiler list all the places that I now need to update.
I agree this is an important aspect. If the tool does the wrong thing even a small percentage of the time, then I imagine it quickly becomes more annoying than useful.
One defense against this I imagine is that elm-pair should only jump into action if the code was compiling before the user made a change and compiles again after elm-pair responded with a change. The suquence of events would look like this:
Base state: the project is compiling.
The user makes a change over one or several saves.
Elm-pair diffs the current state of the code with the state it was in when it last compiles (1). If it thinks it understands the change than it responds with a change of its own.
Elm-pair compiles the code with the change applied somewhere out of the way. Only if the project compiles again with the change applied will it apply the change for real.
I think that would give decent assurances that Elm-pair doesn’t misunderstand intent, but probably the only way to really tell is to try build this thing.
Yeah, that’s a fair point. For that particular example, I think if Elm-pair adds Debug.todos it should add all the places where it does that to the editor’s ‘error list’, so it becomes easy for the user to go through all those places. Generating a unique string in the Debug.todo might also help. That way, if the programmer decides not to fix those todos immediately but comes back at them later, it’s easy search across the project for all occurrences of a particular todo once you find one.
Lastly I would love it if all the changes elm-pair introduces could be undone by a single ‘undo’ operation in the editor.
In my example the auto editor triggers on a user writing out the import in a qualified manner. So if you’d only write map elm-pair wouldn’t do anything, but if you’d write Thing.map it would add an import for the Thing package, if such a page exists and isn’t imported yet. You could then as a second step remove the Thing. qualified from the import, and elm-pair would respond by exposing map from Thing so it can be used in an unqualified manner.