Blake O\'Hare.com

3.141592920353982300884955752212389380530973451327433628318584070796460
Login | Register

An update on Crayon

June 8th, 2024

As you've probably noticed I haven't shipped a stable version of Crayon in about a million years. If you follow some of my other sites you've probably noticed some other weird things I've shipped and I just wanted to post an update of where this is all going.

One of the things that stalled Crayon is basically my own perfectionism. Two of the things I tout about Crayon is that 1) it has a very light footprint by all metrics and 2) it aims to be highly portable and platform agnostic. Although in its early MVP stages it somewhat failed at 2, it excelled at 1. During the pandemic years I actually got it rewritten such that it would excel at 2. But guess what happened to 1?

Yeah.

Instead of having highly compact native frameworks that were re-written to work in each platform, I decided it was more pragmatic to use full cross platform libraries. The UI stack was written in Electron and I upgraded to modern .NET Core instead of .NET Standard (now legacy) and Mono, and well, do you want to download Crayon if it's 1GB of mostly .NET libraries and an embedded version of Chromium? Yeah, didn't think so. I started exploring alternate options to bring the size back down such as using new WebView components or MAUI instead of Electron or dropping C# altogether and either bootstrapping Crayon or using Pastel for the frontend. But even in the latter case, Pastel (my language that the Crayon VM is written in) compiles to only a handful of interpreted languages and I'm back to solving the same problem with a slightly less readable code base. The WebView technology was still not very mature in 2021. I also experimented (several times) with adding C support for Pastel to no success since the memory management model is so different. Thus the major Crayon rewrite kind of fizzled away at this point.

I started working at another job around that time and didn't have much time for projects. However a couple things happened during that time. For starters, I added Go support to Pastel, thus solving the small-native-binary problem. Go also has pretty good webview support.

I also wrote an operating system. Well, a fake one at least. It's called PlexiOS and the technical term for it is a "webtop" operating system. If you haven't seen it yet, you can see a demo version of it running on asdfjklsemicolon.com.

After I finished PlexiOS, I decided it was a good idea to write a new version of Crayon and Acrylic for Plexi OS (Acrylic is my statically typed language that runs in the Crayon runtime). This was going to be a full rewrite of Crayon/Acrylic and the goal was…well…everything. I figured if I was going to do a full rewrite, I should take the list of everything I wish I had built into Crayon from the start and actually put it in. Parity with all Java OO concepts and most of the practical C# ones. Native big integer support. Dynamic loading of binaries. Dynamic unloading? Sure! However the big items were that Plexi would have a package manager that works both like a traditional package manager, but also a consumer-facing platform-independent app store like Steam. These apps could be downloaded for all platforms that Crayon supports but also run directly in the browser in any valid PlexiOS deployment. Additionally, since the apps were all written in a language that static analysis can tell you exactly what out-of-VM behaviors it performs, it would also be the only app store that would be 100% safe from malware. And even if you were still paranoid, you could run the apps in the safety of the browser in PlexiOS either in full desktop mode or in web app "kiosk" mode.

On top of being a fully sandboxed, it would also be de-centralized (no, not hype-decentralized like crypto, actual de-centralization like the free and open web). Basically anyone with a domain name could host an app server on their domain. App IDs use reverse domain notation so there would be no central app gatekeeping or management. For example, if you downloaded the Plexi App client for Windows and saw an app you liked that had an ID of com.example.game.tetris, downloading the app would fetch it from the example.com app server. Obviously this would mean there would be no chance of monetization for me, but also virtually no costs and a new medium of free and open content and creativity for the internet. But I was never a good businessman anyway.

While I'm thankful that I finished a deliverable version of Plexi OS despite my ADHD (largely in part by the urging of friends), the Crayon rewrite was way over-ambitious and I started working on it erratically. And as my ADHD tends to do, I started working on other random things. Even if I hadn't stopped working on the grand Crayon/Acrylic rewrite, I'm not sure I would have finished it anyway as some of the technical problems became too overwhelming even in just the language rewriting phase. This was kind of hard to recognize since each individual problem was not overwhelmingly difficult itself, but rather there were hundreds of little problems.

Since my job was in computer science education, one of the problems I constantly think about is "what is the best way to learn programming?" Having taught people to program as early as 1996, again in 2004-2006, and again in the modern era, it's been amazing to watch how the quality of programming education has gone from non-existent, to kind of okay, to absolutely terrible. I started designing a long-form coding tutorial targeted to people with zero previous coding knowledge. My goal was to design something that was completely optimized for long term serious learners that avoided gimmicky "see how easy it is?"-isms and frameworks-over-fundamentals abuse. To settle the "what's the best language to start with?" debate, I created the notion of CommonLang. Basically a programming language that is specifically designed with the intention of avoiding magical shortcuts and abbreviations but at the same time closely resembles most major programming language constructs in the most canonical way possible such that switching from CommonLang to another language or vice-versa would be basically effortless. By teaching CommonLang instead of say, Python or JavaScript, most concepts could be taught more effectively for longevity of understanding, eliminate the noise of hyped frameworks that obscure clear understanding, and also create a single common language that future tutorials in the series could be written against regardless of topic. CommonLang had two sub variants: Dynamic Common Lang and Typed Common Lang. As the above stated goals were also the design goals of Crayon and Acrylic, you can already guess what these two languages looked like.

Despite the Crayon rewrite taking months and months and still not making meaningful progress, I wrote the bulk of Dynamic Common Lang in about a day and half and it existed as a ~30kb standalone drop-in JavaScript file. Even though it didn't have all the features it would ultimately need, this was still a bit of a wake-up call when I looked back at my Crayon rewrite progres.

I still want to create a de-centralized app store that works both inside Plexi OS and on any other platform based on a secure version of Crayon and Acrylic. This goal hasn't changed. I also want to create a highly flexible Common Lang that is open source and can be used as both an educational language and also a drop-in scripting language that can be used in…well…anything.

I also realized that some of my Crayon rewrite goals, while not impossible, were basically going to make none of this ever happen in my lifetime with my level of ADHD.

So here's my new plan:

I'm going to write Dynamic Common Lang and Typed Common Lang in Pastel, the same language that the old Crayon VM was written in that makes it able to transpile everywhere. I added Go transpilation support for Pastel, so this is a fine language to write things that I want to run natively with a low-ish footprint.

I'm going to rename Dynamic Common Lang to CommonScript, and Typed Common Lang to just CommonLang. Those two were a mouthful and I feel like CommonScript rolls off the tongue much more easily.

I'm going to set CommonLang (the typed one) on the back burner for a while and just focus on CommonScript and the rest of this outlined plan. However when I get to CommonLang, its path will look basically the same as CommonScript.

CommonScript will ship as a drop-in single-file library for various languages that Pastel supports. It will be able to do the same things that any programming language can do (i.e. move data around within itself), but it will also feature a robust extension model where you can register external behaviors and callbacks. For example, if you wanted to write your website in CommonScript instead of JavaScript, you could drop in the JS-exported version of CommonScript and register a bunch of DOM interaction methods into the language as extensions. If you wanted to use CommonScript as your in-game scripting language for a game you wrote in Unity/C#, you could drop in the C#-exported version of CommonScript and register methods like "moveCharacter" or "showNarrationDialog", etc. If you wanted to write a coding tutorial for CommonScript on a web page that had an animated turtle that moves around, you could register extensions like "moveTurtle". Basically whatever you want. CommonScript is intended to be one-size-fits-all adaptable scripting engine.

I will then add a set of system functionality to PlexiOS. Everything from "showNotificationInTaskBar" to "openWindow" or "saveTextFile", etc. This will be called the Plexi Native Interface and can be called from a CommonScript engine. This combination of the Plexi Native Interface and CommonScript will be known as the next version of Crayon.

Basically the relationship between CommonScript and Crayon will be the same idea as V8 and Node.

This doesn't mean that Crayon will only run in PlexiOS in a browser. The Plexi Native Interface is just that, an interface. Other versions of the same interface can be built for standalone runtime engines or application harnesses, so you'll still be able to write and run Crayon code on your OS of choice, but also export standalone and small-footprint executables for any platform.

Another feature of CommonScript is that it also has a fairly flexible module system that can audit which extension calls are being called from which module, and which modules interact with other modules. This is something that can be done at compile-time, which means an app can be properly labeled and permissioned with the types of things that it is able to do and Crayon will be just as safe as before.

Once Crayon is working and most of the technical hiccups solved, my hope is to implement CommonLang in the same fashion and create the Plexi Native Interface version of CommonLang as the next version of Acrylic.

This does mean I will likely abandon a few of my language rewrite goals. The largest cut will be that Acrylic and Crayon will no longer use the same runtime or be able to interop with each other. I think this is okay and isn't something anyone is going to cry over. With the robust extension system and the Plexi Native Interface, I am less concerned about library-reuse and if I really want to write a bunch of code that runs in both, I'll just add CommonLang and CommonScript support to Pastel. By not forcing languages to run in a single be-all-end-all runtime in favor of consistent and shared extension systems, I think this also opens up interesting possibilities of having more runtimes in Plexi OS. For Example, one could add Python scripting to Plexi OS by porting the Skulpt library to use the Plexi Native Interface, something I'll probably do later.

My goal is always to focus on systems that empower flexibility and fight against lock-in platforms and the power of centralized algorithms. Ultimately, my goal is still set on the creation of a decentralized app store. There's very little left in this world that we truly have authority over anymore, even if it's something we "own". If you create an app and try to sell it, do you truly own the app? If you purchase and download the app, do you own it? In the CDs-in-boxes era or Flash games era, the relationship between software creator and user was clearer and the answer to these questions were more obvious and typically "yes". We now live in an era where millions of companies create apps, billions of people purchase apps, but true ownership only lies in the hands of a couple of companies that have ultimate authority over what one can and cannot do with software. If your digital life feels stale and monotonous, this is one of the two main reasons (and I have a whole rant on the other reason as well).

In the short term, I'm hoping to soon announce a release (with proper documentation) of CommonScript both as a standalone language and as a library that you can integrate into your own projects that could benefit from a clutter-free scripting engine. I'm hoping this scripting engine will not just serve those that wish to tinker with languages, but also be a useful tool for those looking for an alternative answer to the typical Python vs JavaScript debate in beginning-programming education.

Stay tuned!

--Blake

Back to blog archive
MSPaint: Linear Gradients
MSPaint: How to Draw a Stereogram
MSPaint: Curved Gradients
Custom Programming Language: Mark Sideways
An update on Crayon