Ramblings for the New Year

January 04, 2021

effectsjs, programming language research and what next.

A new blog, a new year.

A little over a year ago algebraic effects were hot.

It was probably Dan Abramov’s article1 that first caught my eye, followed shortly by Sam Galton’s article 2. Yassine Elouafi’s series 3 was another great source of inspiration.

All the while, Algebraic Effects had also been growing quite popular on the r/ProgrammingLanguages subreddit. There week or so where I would read a comment referencing them pretty much daily. The people on r/ProgrammingLanguages are truly awesome. It is hands down one of the best communities on reddit. I was introduced to eff-lang through the community. I started hacking in Scheme.

Digressing, Generators and Control Flow

Completely unrelated, I’d also been really into generators around that time. This interest had been sparked from two different sources: the wonderful standard library abstractions that Rust provides, and a rediscovery of Kris Kowal’s GTOR 4. Specifically, I intrigued by the usefulness generators provide to asynchronous abstractions.

In general, I wanted to understand problems related to asynchronous control flow more completely. There was something that just didn’t feel right about the ECMAScript async/await specification. I was unhappy with the way functions composed , and reflecting on several of the codebases that I’d been working on. Reasoning about async code is a big pain point that I’ve observed in the wild. Smart people get it wrong and experienced devs can get tripped up.

We’ve seen a few incarnations of async control flow, and subsequent best practices. ECMAThe need for some kind of sugar to write asynchronous code in a direct-style is very real. The introduction of ES6 Harmony Generator Specification spawned several projects to take advantage of the power generators unlocked (co 5 and 6 suspend for a few). We don’t talk about generators that much as a community anymore, but I find them fascinating and woefully underused. They are arguably the most powerful primitive introduced to the language.

There are some open questions that I have, in relation to the async idioms and data structures we have in JS. I think that we deserve something better than async/await for writing direct-style asynchronous code. There are better options, but can we ever have them in ECMAScript.

This question is still on my mind. I suspect that we could have something better.

effectsjs

Shortly after reading Sam Galton’s article, I was fully on board with algebraic effects and wanted them in ECMAScript. I knew that there was overall two major approaches to creating an effects system in JS: throw/catch semantics, and generators. After reading a few papers, the throw/catch approach seemed inadequate due to that high level of abuse required for hijacking the call stack. Generators seemed much more appealing. My gut told me the transforms for generators would be more natural and more appropriate given that they exist to suspend and resume stackframes. I’m still confident that generators are the correct choice for building an effects system in javascript.

Programming Language Theory

I’ve always flirted with programming language design, but never really committed. Programming language research really hadn’t been on my radar up until this point. At the time I probably would’ve explained it away as an esoteric academic pursuit. I never really considered it relevant to other things that I enjoyed.

However, I decided that I wanted to build an effects system and draft ECMAScript specification to provide some sugar for the mess of generator code that I was sure would follow. I had this general inclination that being able to write non-color-changing direct-style asynchronous programming, would be a game-changer. But in order to test that hypothesis, I’d need to be able to write some code. And in order to do that, I’d need to draft a specification and write some transformations to a modified Babel fork.

Thus, effectsjs was born and I accidentally stumbled into doing amateur programming language research.

Project woes

The biggest challenge presented itself with this issue. It is the first indication I think that something wasn’t quite right with the first iteration of the project. The short of it is that for something written in continuation passing style (CPS for short), the continuation getting passed can not not perform without some state and being converted into a Promise. This problem is far-reaching.

It of course has nothing to with functional interfaces, but with preserving the correct context as control is ceded to the callee such that the virtual stack remains whole. At it’s heart, this is a conflict of two different control-flow styles. Further exacerbating the issue is that CPS-style code expects continuations, not generators or promises. You can’t just perform willy-nilly and expect seamless interop with other librarys.

So EffectsBoundary was introduced to sort of patch over these problems. However, the boundary solve never really sat well with me. It’s not very elegant, requires too much buy-in and syntax to do normal things. Worst of all, it requires the consumer to be acutely aware of the effects-system. Effects are no longer this wonderful sugary prose that allow you to isolate dependencies and mutations in a meaningful way. Instead, the perform keyword becomes a burden. One must apply mental gymnastics in order to use it correctly. “Do I need to use an EffectsBoundary here?”, “Where is the virtual stack right now?” and so on…

Having said all of that, the effects boundary was not all bad. It actually solved the problem in a meaningful way in the short term. It would’ve been totally possible to go on experimenting with the EffectsBoundary in place. But it’s not good enough, and it killed my interest in the project for a while.

Interests at large

2020 has been a hard year for a lot of people. I wasn’t an exception in this category, though I do feel fortunate to have come out on the other end relatively unscathed. In the last week or so in doing some reflecting on where life has taken me so far, and where I would like to see it go— the one thing I regret is not writing more.

I learned a great many things over the last year. Interests around PL theory have really gelled. Had I been writing about all of the info I soaked up along the way, about the Category Theory, Algebraic Data Structures, realizations and discoveries made around effectsjs, I’d be much farther along.


Written by @dpchamps Thoughts on PL and Engineering