The Rose Project (March 2017)
Making programming better
As a computer science educator, I see students struggling to learn to code every day. Much of this struggle is worthwhile: learning to model, to debug, and to think more precisely, iteratively, and systematically.
However, much of this struggle is unnecessary. Why should we make students memorize arcane syntax rules? Why should we make students cope with each historical accident that’s embedded into our languages?
The more I teach computer science, the more embarrassed I am for our industry and the less tolerance I have for the bad answers to these questions. We deserve better.
That’s why I’ve been working to create tools for computation. I started working on this project in January 2016, but took a break from it March 2016 through November 2016 to focus more on The Coding Space and WoofJS. I started back up on this project in December 2016. I originally called this project Cycle and I recently changed the name to Rose (more on that below).
Recently, I realized that by keeping my development journal within my own personal journal, I’m depriving others of my learnings, and I’m depriving myself of collaboration with the broader community of people who believe programming can be better.
This is my first public post of the Rose development journal. I will give a quick history of the project, explain where things are at now, and where I hope to head in the next months.
Cycle version 1
Jan — Feb 2016
It allowed users to create DOM elements, select them by their IDs, modify their properties, and react to their events — all without typing a line of code. You’d just drag blocks.
You can view it live at cycle.thecodingspace.com.
Pros — It was really easy to do some simple stuff, like making the background color change on click. Our students seemed to really enjoy playing with it.
Cons — It was entirely imperative, so if you wanted any HTML elements, you had to create and append them to the page. This seemed like a recipe for disaster for any sizable program, and that we could do this more declaratively like ReactJS.
Cycle version 2
December 2016 — Janurary 2017
The second version of Cycle was also built using Google Blockly. This experiment can be summed up as “blocks for ReactJS.” (Technically, the code compiled to VueJS.)
I was helped by Jonathan Leung and Nicole Kelner to craft the design priciples for this leg of the project.
When I started the project, my goal was to build a near pixel-perfect replica of ToDoMVC. I was able to accomplish this within a month of work here (however I later broke some aspects of this in later versions of Cycle so it’s probably no longer pixel-perfect.) I also built functionality for integrating with Firebase and making AJAX requests.
Last month, I began getting users to get feedback on Cycle version 2. My co-founder Eli Kariv and I began teaching it to some of our students at The Coding Space. Our students seemed excited by what they could create with the tool, but it wasn’t entirely as user-friendly as we’d hoped. They needed a lot of guidance from us.
I also gave talks at three hackathons on Cycle to encourage students to use it to build their projects. While the workshops went well and the students seemed engaged, I wasn’t able to convince a single student to use Cycle outside of my workshop.
At the same time, Eli reached out to potential users for a product like Cycle, including designers, programmers, software agencies, computer science teachers, and hackathon organizers. Through his research, I was exposed to Webflow, a WYSIWYG tool to build websites that I was very impressed with. However, we did not find a strong indication that there was a lot of demand for the tool we were building.
- It was definitely faster, easier and less frustrating to build in Cycle v2 than typing ReactJS or VueJS code…when it worked.
- When you ran into a bug, it was a nightmare that non-me users couldn’t come close to solving. Part of the problem is that VueJS often gives the worst, least helpful errors.
- It very closely mirrored the ReactJS declarative pattern so it was able to capitalize on the simplicity and power of that paradigm.
- While it enabled me to move incredibly quickly out of the gate, Google Blockly was limiting and hard to change. In particular it’s built on the Google Closure library and I did not have fun with that.
- Ultimately the worst part of Cycle v2 is that it’s an isolated system. The way it was built, it’s impossible to import or export a project. That means it would need to be so good that you’d rebuild your existing project in it, and you’d have to be convinced it could handle enough of your potential needs that you’d never want to export your project out of it. Basically, it’d have to be really, really good to get you to switch.
As I was pivoting away from Cycle version 2 and onto a new path for this project, the question I felt I needed to answer was…
Should programming be a language?
Ever since I fell in love with MIT’s Scratch programming language, I’ve believed that the future of programming is decidedly not typing characters into a text editor. I’m not sure if it’ll be dragging and dropping blocks, like in Scratch, but I feet strongly that text-editing computer programs is simply past its prime. It’s 2017 for goodness sake!
However, my thoughtful friend Jonathan Leung posed a good question: why do you think typing text isn’t good for programming but it is good for typing English prose?
So for me the question then became: when does a situation call for a language and when does it call for a GUI? Is it based on the number of possible things you’d want to do? Is it based on the technical know-how of the creator? It is based on the parsing ability of the object of your communication (ie either a person or a computer)?
One thing that makes English a good candidate for being written by typing letters is that the cost of a typo — in either spelling, grammar or sentence structure — usually has a negligible effect on a human reader’s ability to parse meaning. You can even misspell a majority of words in nontrivial ways and readers still have no problem gleaning meaning. However, if you randomly deleted any single character from a computer program it’s almost guaranteed to botch the entire program.
I’m no linguist, so this might be 100% wrong, but it seems to be like we still don’t know how to fully model the English language. For example, while we do know a lot about how sentences work, Siri and Alexa still have a lot of trouble answering even simple questions. I feel like the only reason it’s able to answer the question, “What the weather today?” is that it’s able to understand the single word “weather.” Thus, if you’re creating an interface for crafting English sentences, no GUI editor could contain any way you’d want to express something because there are too damn many ways to express things and we still don’t know how to model them all.
The difference with programming is that we already have a model for anything you’d ever want to say in a programming language. It’s called that language’s Abstract Syntax Tree (AST). To take a step back, let me explain what an AST is. When you tell your computer to run a program, it first needs to parse the text of the program into an AST. It then uses the AST to evaluate your program and do what you instructed. So if you wanted to change what the computer does, you’d need to modify the AST. However, currently the only way to modify the AST is by changing the text program and having the computer re-parse it back into a tree.
That seems crazy! Why don’t we edit the tree directly? Given that we know all the possible ways you can construct a program, it seems like it’s only a question of interface design to build a GUI that allows you to edit an AST.
So no, programming should not be a language. It should be a GUI. In the very worst case scenario, it should be a GUI that models an AST, but I think we can be cleverer than that.
Early this month (March 2017), I met with Samantha John of Hopscotch to get advice for building an code editor with “context in the cursor.” As opposed to Scratch and Blockly where you have a menu of blocks to drag into your program, Hopscotch’s iPhone app allows you to select a part of your program to edit and then allows you to pick from a selection of blocks that could logically go there. For example, if you click on a number it allows you to replace it with another number or an arithmetic function. I really loved this approach and was beginning to brainstorm ways to apply it as the base of my editor, partially as a way to finally get off of Google Blockly.
That same day I met with Sam, Alex Rattray sent me a link to a Hacker News post about Cirru, an editor for AST, which shared many of the ideas I was noodling on.
Even better, that HN posts linked to dozens of similar projects I had never heard of! I spent the rest of that day, over 5 hours, combing through all those posts. In particular, I was blown away by Unison and Prune.
Paul Chiusano has a grand vision for the future of computing. My vision to make programming not suck as much is only a small part of what his Unison project hopes to accomplish. He began his project by building a structured editor for a highly-typed language that’s similar to Haskell. Eerily enough, this is one direction that I was strongly considering taking my project in, so it was amazing to see someone else’s thoughts and work here before I wasted my time reinventing the wheel. (This partially explains why I’m starting this public development journal.)
I contacted Paul and we’ve talked a number of times about working together. His current focus is to make it easy to design distributed systems with Unison, so he hasn’t been as focused on the Unison editor as much recently. There could be an opportunity for us to work together in the coming months after the core Unison language API stabilizes.
The idea for this project also came from Alex Rattray. He’s building LightScript, a transpile-to-JS language that’s very similar to JS with a few niceties. He suggested that I build a way to visualize every type of node in the Babel parser, and then build my interface on top of that.
It turns out someone else had this idea: Prune came out of hack-a-month projects at Facebook by Kent Beck and Thiago Hirai. While they did not release any demos or source code, their postmortem post was unbelievably helpful to get me started. It wouldn’t be inaccurate to say that I’m trying to pick up their project where they left off.
Ever since one of my favorite programmers released CycleJS, I knew I’d have to change the name from Cycle. I wanted to name this project after my dad, Rodger, but decided that a man’s name for a programming language didn’t make sense. So we picked Rose, my father’s grandmother, who he was named after.
You can find the main link to Rose here. It currently links to:
- a demo of how Rose can generate JS and how JS can generate a Rose UI
- a demo of using Rose to create a WoofJS program
At the time of this posting, Rose is very buggy. It can currently:
- Change numbers and identifiers
- Add new variables, functions, parameters, etc
- Drag and drop code to copy and replace. (Super buggy!)
- Delete things
My current goals for Rose are:
- Bootstrap Rose so that I can add more features to Rose by using Rose. This is something that the Prune team did as well.
- Integrate Rose into woofjs.com to help students transition from block-based coding to text-based coding. In this way, Rose would be very similar to Pencil Code. (I originally tried to integrate Pencil Code with WoofJS but found it quite difficult.)
My current challenges with Rose:
- VueJS is has poor errors and is buggy. I’m considering switching to ReactJS.
- The TBD node. Currently, when you add a new node to Rose, it adds default values (usually null) where it needs them and allows you to change them later. However, it’s not great to have your code littered with nulls, so I’m considering taking a page from Prune and copying their notion of a placeholder node.
- Modeling all possible transformations. The way I model all the “things you can do at every node” currently is very imperative and error prone. I’m trying to come up with ways to do this more declaratively, like Prune suggests. What’s the core data structure that could hold all possible transformations at each node type?
Other challenges I’m thinking about:
- Displaying all possible transformations. One core challenge to this project is coming up with a user interface to allow users to browse, discover, select, and undo tree transformations. Currently I have a list of transformations that you can scroll through. This won’t scale. Unison and Prune both use a type-a-head style suggestion box to help users find what they’re looking for. I’m also open to other designs, like Scratch’s menus, or even nested folders.
- Context-specific suggestions. When I integrate Rose into woofjs.com so that students can write WoofJS programs, I’ll need a way to “customize” Rose for WoofJS in the same way I customized CodeMirror’s type-a-head suggestions to include WoofJS functions. The most generalized solution to this would be strong, declared types. That way we could know what things could go where at any time. In the short term, I’m open to more hard-coded solutions here.
One of the main reasons I’m writing this is to collaborate with the broader community. So if you have advice, suggestions, or want to work together here, please reach out at steveykrouse at gmail.com.
I hope to post here monthly. See you at the end of April!