Stack Editor — programming by functions
I made Stack Editor. It’s designed for writing Clojure code by managing the definitions of functions. It’s quite different from what we currently have.
I record a video trying to explain how it works and why I created such an editor.
Now I’m trying to explain a little more detailed in this post. Let’s start from “Cirru Editor”, a project I started earlier to write code in AST.
Update: added one more video in 2nd Mar 2017. Stack Editor got quite some updates. The previous video was half a year ago.
Write in AST, not in text.
Years back after I learned about Lisp, I felt text syntax is too tedious. One day I came up with an idea of building an AST tree with browser technology, which may emit files of code in text for me. It was a long story, I made several attempts and finally got Cirru Editor written in React.js and generated Clojure files with a boot plugin.
In Cirru Editor, code in S-expressions are represented in a DOM tree, so writing code is modifying the DOM. There are enough keyboard shortcuts to help me speed up. Also, I made a sidebar to display the functions so that I can edit one function each time. It’s not necessary look at the whole file when writing a single function of it, isn’t it?
Switching but faster!
Sublime Text tips: Command+p to jump! Command+r to jump!
Cirru Editor is like a text editor. It barely understands my code. If I need to edit another function, I need to switch to the file and then switch to the function I want. After editing, I need to switch back to the previous function and write again. It’s always switching!
Adding command palette makes it smoother, but it’s not enough. There are many scenarios I have to switch between functions to debug, because one of them is calling another. Or that thing being called is a stylesheets so I have to switch between the virtual DOM code and their styles. A lot of scenarios like this.
I began to think about a solution to make it faster. One day I realised that the “Call Stack” panel in the DevTools is exactly what I need. All the functions appearing in the panel are related to the features or bugs we are focusing on. I can just click to switch among them. No more fuzzy searching!
In my case, the code I’m editing is not running yet. As a result, I need static analysis in this editor. As I already said, Cirru Editor is holding an AST tree, so no need to parse code. I can guess the dependent functions by matching the function names with the tokens inside the function bodys. And the I will get a sidebar just like “Call Stack”. Most code related to feature is now collected on the sidebar.
I did an experiment in a project called Clouditor. In Clouditor there are several functions and I can generate the dependency graph based on the special forms inside the function body. It’s quite nice that the editor is aware of the dependency graph. To conclude, “Call Stack” works.
Programming by functions, not by files
Now it’s time to bring out Stack Editor. The Stack is the most important part, it’s like file tab in Sublime Text. As you open a function it stays on the sidebar, so that you can switch between functions very easily even they are in different files. Stack Editor can guess the dependency function as you press “Command+d”, then append the function to the sidebar and show the function for you.
So the units in Stack editor is not “files”, it’s “functions”(or “definitions”). And we navigate by functions, edit by functions, and finally program by functions. It’s more like the program is running and we got a call stack here. We edit the code that’s collected for a specific purpose without constantly switching the context. It can be faster.
However, Clojure is not a language designed for that. Clojure uses namespaces just like Java and declares dependencies along with its namespace. So actually we still need to manage the dependencies by ourselves inside Stack Editor. I have to say this was not part of my initial idea, but it’s just required because I can’t analyze the dependencies with my code.
Stack Editor is not a mature project. As I said it’s hard to pick up. I introduced the features in the video actually, but I still need to add more guides in order to make it easy. I would say it’s currently a prototype, I still need time to make it better. And here are the parts of Stack Editor:
- Main repository: stack-editor
- Server of the editor: boot-stack-server
- Tree editor component rewrote in ClojureScript: respo-cirru-editor
- Seed project with Stack Editor: stack-workflow
- AST to Clojure code generator: sepal.clj
More on “Call Stack”
Stack Editor is going too far, people may dislike manipulating AST, instead, they want to edit code in text, but with smart tools to assist. Speaking to “smart tools” I think a “Call Stack” is smart enough to make us spent less time doing file switching. Then is that possible to build one in Cursive? What do you think?