My Ideal Developer Toolset

15 Aprilie 2019

As developers, we have different sources of motivation for creating a piece of software. Some do it to learn a new technology, some do it to play around. Others do it because they want to develop a business, while others like to see their work used and make a difference. For some it's a job.

But we all have one thing in common: we want our tools to make our lives easier. Because, in the end, we want to focus on the features we are developing. We don't want to spend time looking for that missing semicolon or figuring out the encantations required by the build tool. How the ideal tools look like depends on who you ask. Below you'll find my version of the answer.

Note: While writing this, I realised that the answer revolves around Haskell and PureScript. Some of these features already exist in other languages. Some could provide inspiration for other languages.

I'll use the stages in the life of a piece of software to describe the features I would like to have. The stages are:

Implementation

Input Validation

We develop software that forces users to enter valid values in certain fields. They receive the feedback as they type, so they don't waste time inputting the wrong thing. Unfortunately, we as developers don't benefit from the same tight feedback loop.

I would like an interface that only allows valid code. Both syntactically and semantically. 

No more need for linters. No more need for pre-commit hooks. No more committing code that doesn't compile.

Import Management

If you can only enter valid code, you never have to write an import statement. When you first use an identifier, the IDE looks for it in other modules and prompts you to choose the one you want. Then it adds the import statement for you. 

You could also always use the identifiers prefixed by their module, but make the IDE hide the module. This would avoid any ambiguity. You could even hide the imports by default, like PyCharm does for Python and TypeScript.

Identifier Alias

There are many functions whose name I can never remember. Or when I see them in code, I don't remember what they do, because their names are opaque to me. Haskell has lots of them: nub, cons, uncons, snoc. That last one is from PureScript actually. I'd love to have my editor show them as unique, prepend, append, and so on (I can't think of any alternative for uncons). Of course, the source would contain the original names.

It would work in reverse too. If I write append, the editor can ask me if I mean snoc.

Symbol Discovery

In Haskell, I want to hover over a type variable in a type definition and see the implementations for all methods required by the type class constraints. If I hover over a type class, I want to see its methods.

Semantic Highlighting

I'd like a clear distinction between types and values. I want this, so I can distinguish at a glance type constructors from value constructors, because by convention they have identical names.

I'd also like consistent colours. Modules should always have the same color, so should type classes and types. Not like current syntax highlighting implementations.

Semantic Autocomplete

Since you can only enter valid code, it makes sense to only receive valid suggestions. For example, when I call a function, the compiler knows the types of the arguments and could only suggest values with matching types. If I write a type class instance, I only want suggestions for type classes, types and methods. 

If I'm defining a function, I want the editor to fill in the name at the value level, after I write the type definition. And I don't want random suggestions when I write the name, because they're useless.

Of course, this has to be fast enough to be useful.

Formatting

Since the editor deals with the AST internally and not with text, you can have it format and display the code as you want. No more fighting about indentation levels, alignment, line length and so on. You also get imports sorted alphabetically or any other way you want for free.

Redundant-Code Highlighting

I want to see all the identifiers I've defined and I'm not using. I'm thinking of some other things, but I don't know if they're possible:

Evaluate Expressions Inline

In Haskell (and PureScript), you have the type of all the values in an expression. QuickCheck uses them to generate random values for a specific type. I would like to have this in the editor. The editor would generate values for the input of a function, plug them into the function and show the resulting output. I would get instant feedback on whether the function does what I expect.

I wonder if this can also be used for profiling. If the editor could warn you about pathological cases, it would be useful.

Compilation

Once we're done coding, we're ready to compile. Since the editor deals with an AST, it can keep the whole thing in memory and/or on disk. Modifications to the code translate to instant updates to the AST. This means that when you want to compile, you only need to convert the AST to machine code or whatever you're compiling to.

If you persist the AST on disk, you don't need to wait the next time you're opening the editor. If you keep it in a database, you don't have to wait for it to load in memory.

Maybe we can also save time on the byte-code generation. Like keeping the byte-code in an easier-to-update format from which you generate executables. I don't know enough about this part to tell if it's doable and worth the effort.

Deployment

Generate Docker images? nix packages, OS-specific packages, minified JS bundles? That would be nice.

Runtime

The only improvement I can think of here is hot code reloading. I know that Erlang has this. I don't know if this can be implemented for Haskell or if it's worth it. At least PureScript has an Erlang back-end.

Other Random Ideas

I don't know if all these things can be implemented, but some can. Right now, I'm looking for an editor that will allow me to implement the structural editing features.

If you have suggestions or ideas, I'm happy to hear them.