In the pre-internet world of the early ’90s, we had mainly two camps: 8bit vs. 16bit and Atari vs. Commodore (and some Sinclair). People in each other camp were considered taboo :) Each platform was basically a completely separate scene… but apart from the chosen hardware providing each scene’s main identity, we swore no further allegiances to specific software or languages used and the community was IMHO much more inclusive (and without a need for CoC’s). In our bi-weekly club meetings we’d talk about & experiment with anything interesting to do, not just with the Atari: be it strange languages, books, new games, tools, events, disk mags or hardware hacks. Anything went. Most members were all-rounders.

In the vastly larger open source creative computing demographic of today, the by far biggest groups are tight-knit communities around individual frameworks and languages. There is much these platforms have achieved in terms of output, increasing overall code literacy and turning thousands of people from mere computer users into authors. This is a feat not be underestimated and a Good Thing™! Yet my issue with this siloed general state of affairs is that, apart from a few notable exceptions (especially the more recent arrivals), there’s unfortunately a) not much cross-fertilizing with fundamentally different and/or new ideas in computing going on and b) over time only incremental progress is happening, business as usual, rather than a will to continuously challenge core assumptions among these largest communities about how we talk to machines and how we can do so better. I find it truly sad that many of these popular frameworks rely only on the same old imperative programming language family, philosophy and process, which has been pre-dominant and largely unchanged for the past 30+ years, and their communities also happily avoid or actively reject alternative solutions, which might require fundamental changes to their tools, but which actually could be more suitable and/or powerful to their aims and reach. Some of these platforms have become and act as institutions in their own right and as such also tend to espouse an inward looking approach & philosophy to further cement their status (as owners or pillars?) in their field. This often includes a no-skills-neccessary, we-cater-all-problems promise to their new users, with each community re-inventing the same old wheels in their own image along the way. It’s Not-Invented-Here on a community level: A reliance on insular support ecosystems, libraries & tooling is typical, reducing overall code re-use (at least between communities sharing the same underlying language) and increasing fragmentation. More often than not these platforms equate simplicity with ease (go watch Rich Hickey taking this argument eloquently apart!). The popular prioritization of no pre-requisite knowledge, super shallow learning curves and quick results eventually becomes the main obstacle to later achieve systemic changes, not just in these tools themselves, but also for (creative) coding as discipline at large. Bloatware emerges. Please do forgive if that all sounds harsh, but I simply do believe we can do better!

Every time I talk with others about this topic, I can’t help but think about Snow Crash’s idea of “Language is a virus”. I sometimes do wonder what makes us modern humans, especially those working with computing technology, so fundamentalist and brand-loyal to these often flawed platforms we happen to use? Is it really that we believe there’s no better way? Are we really always only pressed for time? Are we mostly content with Good Enough? Are we just doing what everyone else seems to be doing? Is it status anxiety, a feeling we have to use X to make a living? Are we afraid of unlearning? Is it that learning tech/coding is (still) too hard, too much of an effort, which can only be justified a few times per lifetime? For people who have been in the game long enough and maybe made a name for themselves in their community, is it pride, sentimentality or fear of becoming a complete beginner again? Is it maybe a sign that the way we teach computing and focus on concrete tools too early in order to obtain quick, unrealistically complex results, rather than fundamental (“boring”) knowledge, which is somewhat flawed? Is it our addiction to largely focus on things we can document/celebrate every minor learning step as an achievement in public? This is no stab at educators — much of this systemic behavior is driven by the sheer explosion of (too often similar) choices, demands made by students and policy makers. But I do think we should ask ourselves these questions more often.

Of course, I realise there too are a number of important commercial and social benefits and effects this tool-based self-identification of programming communities has produced and I gladly had a tiny share of those. On the other hand, as someone standing more on the fringes, I think it’s a strange & worrying development that use of some of these (by now) established tools increasingly is becoming an almost mandatory requirement, a kind of brand or quality label and job qualification, as well as a delineation for (sub-)disciplines (as if there’s always just this one right tool for the job), especially in the creative applications spectrum/market. By doing this we’re forgetting something. If we allow it to happen that entire coding disciplines again are to be defined by only the currently popular tools, we seem to forget that most of these tools first appeared exactly to provide more choice, more means and ranges of expression and to break the former monopolies of the previous generation (e.g. Director/Flash) — only now to take over that role as new defacto standards. This is not so much the direct fault of these tools themselves, but we have to acknowledge that as more and more people are only becoming exposed to the fine art of coding through these frameworks, we’re losing track that there’re many, many more choices out there, and many of them underexposed by the light beams of existing communities. We must not forget that “New needs friends”, as so nicely stated by Anton Ego in Pixar’s Ratatouille. The same goes for “Different”! So in some ways it does come down to the stewards of those existing communities to more actively encourage and allow re-thinking of core assumptions to take place. We all know that community building takes a lot more time and effort than churning out the Next Great Idea in code form. But communities are programmed themselves and I strongly believe, that even though we cannot fully overcome the Tower of Babel effect, we can shift our communities’ primary means of identity from being tool-specific / technology-based to become more focused on broad-concepts / targets, we’ll all be learning more (from each other).

As I look back (triggered by recent research) on my own life with computers, I began to realise why, after climbing the language ladder of abstractions, I’ve been rejecting frameworks more and more over the past years. As explained earlier, my trajectory has always followed more of a “bottom-up” approach and I often still struggle with its polar opposite (“top-down”), both in coding as in design. Creative projects require creative tools. For example, my toxiclibs project was partly started out of concrete needs for work projects, but to work around Processing’s lack of abstract data models for its core themes (e.g. creation of visuals). However, it never was purely a Processing specific project (even though 99% of people have only ever been using it in that context). Over the 6 years that I worked almost daily on this project, my only ever design philosophies were No-lock-in & Open-endedness: 1) to not force myself/users becoming dependent on a single framework (it’s already enough to be constrained to a given language, Java in this case), 2) to define as many useful things as possible and define them to be as extensible as feasible and 3) to document some of these options via 100+ small examples and the larger work projects I myself and others used these libraries for. Another key principle was to use it all as teaching tool. There’re many things I’ve learned since, but this same guiding philosophy still too forms the basis for toxiclibs’ successor, the collection of thi.ng’s for (initially) Clojure & Clojurescript and is (hopefully) expressed even more clearly. Providing many, only loosely coupled constructs with many points for customization, but without overly dictating how they can be used or combined, is key to enable flexibility in design tools and for me is the primary mark of a bottom-up tool. It’s also the trademark of a language.

Toxiclibs community showreel from 2009.

Toxiclibs community showreel 2010.

In terms of programming languages, that bottom end usually means Assembly. It is said that coding in Assembly for prolonged periods can cause the infamous “God complex”, often associated with general Nerdom and bragging rights in coding circles. Maybe it’s because Assembly is the only available language without any extra layer of conceptual translation between human thought and silicon and hence it is widely considered Black-belt Hard Stuff™. On the other hand, Assembly is often seen as very hard, because writing in this language not just assumes, but literally requires, a much deeper and more detailed understanding of the nature of the machine and this is what new programmers are often lacking (see previous section). The usual argument for justifying this conscious gap in knowledge often runs along the lines of “You don’t need to know how an injection engine works in order to drive a car”, which is very true of course. However, programming is a very different discipline to driving and even though I largely agree with the reasoning for most common use cases on modern desktop environments with hundreds of complex API layers, I believe that actively avoiding this knowledge gap outright, by design, in the world of embedded devices and IoT, is something we should seriously question and counteract.

Denno Coil was an anime series about a group of hacker children in an augmented reality city. One of the characters, Yuko Amasawa used special knowledge to alter the government control AR infrastructure by drawing complex fiducial markers (used for computer vision) in chalk — the equivalent of coding in Assembly (and also good portrayal of the God complex).

“I still believe in abstraction, but now I know that one ends with abstraction, not starts with it. I learned that one has to adapt abstractions to reality and not the other way around.” — Alexander Stepanov

Everything in computing has a cost, either in space, time or energy. Yes, higher level (more abstract) languages like Javascript or Python allow for shorter dev cycles, but these savings come with other costs in terms of lack of understanding, loss of direct hardware control, more tooling needed, slower runtime, magnitudes more resources (support code, memory, clock speed, virtual machines, interpreters etc.) and therefore overall higher energy demands too. The extra layers between the code we write and its final result can also become an hindrance when debugging. Furthermore, it’s a fallacy to assume that one’s Javascript knowledge from working with web browsers is directly transferrable to microprocessors, which often require a very different model of programming for anything more than just reading a sensor or flashing an LED. Whereas these days we can mostly ignore these incurred costs on desktops and in the cloud, for embedded devices we still should to be paying more attention, not only because their CPUs are still largely timed in MHz rather than GHz, but also because of physics — more efficient code, less resources needed (smaller, lower powered chips), longer battery life, less waste. This stuff matters, or rather it should matter more, especially if we’re supposedly going to spill them by the billions into the environment over the coming years. Also from the hardware manufacturers’ side, these considerations are being taken seriously with many available options to dynamically control power consumption. So why not in software then too?

Embedded devices often really don’t need a full blown Operating System like Linux and usually have a more simple hardware architecture than their bigger siblings (although this is changing too). This all actually makes them the perfect contemporary learning environment to understand how a CPU (or whole System-On-a-Chip) and communication with peripherals operates. We can play a game of catching up. Sometimes doing so without crutches, in Assembly, can be incredibly enlightening and refreshingly simple (again, in the Rich Hickey interpretation of the word, go watch it!!!), often even surprisingly so. To anyone who’s developed a sense of code aesthetic and has a love of lightness and minimalism in how we work with computers, out-of-fashion languages like Assembly (but also the many flavors of Lisp, Forth) or new contenders like Rust, Pony provide an appealing choice — if not for their speed and elegance, but at the very least for learning purposes and a different glimpse of what programming was like, is (in some fields) and could be (in ours). Some languages have introduced ideas which only became truly viable decades later, when hardware and sufficient numbers of humans had finally caught up. However, recently it seems our software world, not hardware, has more and more catching up to do. Learning these concepts can lead one into a rabbit hole, but the knowledge gained certainly isn’t a one-way street and will make you a better programmer, even if your final choice for a project is a more mainstream language.

“The true delight is in the finding out rather than in the knowing.” — Isaac Asimov

The code below is a complete Assembly “Hello world” equivalent, a blinking LED, for a 32bit ARM Cortex M4 CPU. Its ~20 lines of source code (excl. comments, configuration and variables) equal the same number of operations the CPU is executing (usually 1 per line) and produce a final binary version of just 76 bytes (not KB!). Even in C, considered the primary low-level systems programming language, a programme producing the same effect requires between ~1,100–10,000 bytes (this comparison uses Arduino, depends on target platform 8bit vs. 32bit), that’s 15–140 times more (e.g. the Arduino Blinky example compiles down to 10,092 bytes for a similar CPU [Cortex-M3])!

A version complete with linker & flash scripts is available here.

Strong platform dependency has always been another key criticism of Assembly: Code written for one CPU usually doesn’t work on another. Even though this remains a fundamental, unresolvable issue, I too believe that in the current market situation it is somewhat of a lesser concern than it used to be (especially if we’re also honest about the realistic lifespan and scope of much of our software): For example, ARM and its IP-only business model has somewhat ensured that there’re now dozens of manufacturers with hundreds of different versions alone of the Cortex M chip family. And although they do slightly vary in terms of instruction set features, they’re are not entirely incompatible and all upwards compatible by design.

For me Assembly isn’t (just) about maximum speed and code density. My recent interest in going back to my programming cradle has also not much to do with sentimentality. Having said this, I think there’s a level of cross-domain ingenuity present among embedded system coders, which I sometimes miss in our main platforms. It’s also nice to see that the demoscene is embracing some of these platforms:

Jupiter & Beyond by SVatG (2013) running on a $15 STM32F4 dev board without GPU/VGA support. In addition to the visuals and audio, the demo too generates its own VGA signal, which is passed to a real display via a series of resistors. Productions like this are great to actually understand how powerful even such small computers are/can be.

Instead, I want to revisit this world “closer to the metal” with the by now very different mindset obtained from working on the other side of the abstraction spectrum. Especially my last 4 years spent with Clojure (one of the notable, open-your-mind exceptions I talked about earlier) have provided me with an incredible (and incredibly useful) amount of new insights and research ideas. I’ve already noticed how this has positively impacted my coding style in C and also triggered me to revisit other forgotten languages from my past, e.g. Forth — one of the seemingly most shunned & unknown languages today (though judging by Github activity over the past year, slowly gaining again more activity than I remember previously).

Languages like Clojure, a modern dialect of Lisp, are not just different because of their “strange” looking syntax, or in the case of Forth, the almost complete lack of syntax. To me it’s their very different view of what computing can be like, what makes these languages so fascinating. And here I’m talking about the full experience of programming a machine. As much as I’m interested in final outcomes, I’m equally invested in bettering the way we work with machines. Even single concepts like persistent data structures or the presence of a REPL (an interactive programming environment) are core to the way we think, plan and express our ideas with these languages and can be transformative to our entire workflow. The ability to break the write/(compile)/run cycle or hot-swap code in a running system without destroying application state already has transformed the often-times frustrating experience of modern webdesign. It also enables live coding, a field which is rapidly gaining popularity, not just for musical applications (though being a timebased medium, that’s where most of the research and education is happening).

The following are the perfect examples why we can’t (and shouldn’t) rely on just general purpose mainstream languages for everything we do with our computers.

Andrew Sorenson is one of my livecoding heros. He has been working on his Impromptu and Extempore languages for many years.

Sam Aaron is the founder of the Overtone and Sonic-PI projects, Supercollider based livecoding languages & environments, with the latter primarily aimed at music education using Raspberry PI (but also available for OSX/Windows).

My own Sonic-PI livecoding demo/session recorded at the Retune 2014 conference in Berlin.

Over the past year I’ve started researching and working on a new music programming environment again myself. It’s a theme I seem to keep on revisiting every few years, only this time using low-cost embedded devices and with the aim to combine it with livecoding, gestural / environmental inputs and applying & testdriving concepts from other languages in this controlled environment.

Forever by Universal Everything at Victoria & Albert Museum, 2008/9. In addition to coding all visuals for this installation, I too designed a rule-based, generative music composition system using 200+ single shot samples by Simon Pyke, all recorded in the same key. With a custom made annotation tool, we defined rules, constraints and musical scales for all instrument groups, which then were used to evolve the composition in realtime, non-stop over the 3 months of the installation.

If many people already take issues with Lisp’s extensive use of parenthesis, then Forth and the family of concatenative languages will seem even more alien, dare I say radical. However even a brief cursory examination should show some unique benefits: Forth has an unique focus on programmer freedom, simplicity and being lightweight. It constitutes a stack based, hyperstatic, but interactively programmable environment, dynamically switching between compiled & interpreted modes (though the interpreter incurs much less costs than in other languages). Most Forth implementations are also self-compiling (with most of the core language words defined in Forth itself). The lack of syntax and being stack-based makes it trivial to implement domain-specific languages — essentially any application written in Forth is written in its own DSL.

“If you know one Forth, you know one Forth.” — Bernd Paysan

Forth (by now) seems to be more of a family than a fixed language, the above quote nicely sums it up. There is a (much debated) standard though, however the community seems fractured. Due to the freedom the language inspires, it really shouldn’t be surprising to see a large number of “North” (as in “Not Forth”) languages. Depending how one looks at it, it’s either the best example of the NIH Syndrome, or on the other hand, the logical conclusion of its core philosophy: To avoid any unneeded junk. Nonetheless, it has been used successfully for 40+ years for both complex and extremely resource constrained applications, incl. much work done for NASA and in the early years at Apple (MacFORTH was the first full development system for the Mac in ‘84).

“…Forth does it differently. There is no syntax, no redundancy, no typing. There are no errors that can be detected. …there are no parentheses. No indentation. No hooks, no compatibility. …No files. No operating system.” —Chuck Moore, creator of Forth

In the same article “1% the Code”, he further continues:

“I must say that I’m appalled at the code I see. Because all this code suffers the same failings, I conclude it’s not a sporadic problem. Apparently all these programmers have copied each others style and are content with the result: that complex applications require millions of lines of code. And that’s not even counting the operating system required. Sadly, that is not an undesirable result. Bloated code does not just keep programmers employed, but managers and whole companies, internationally. Compact code would be an economic disaster. Because of its savings in team size, development time, storage requirements and maintainance cost.” — Chuck Moore

A practical example of this: When I started my journey of ARM C programming using an STM32F429 dev board, I was shocked to find the bundled system source files add up to 160,000+ lines of C (excluding comments!), which don’t provide much more than common ARM definitions & macros, system initialization, basic peripheral drivers and an hardware abstraction layer. On the other hand, a complete Forth environment with core peripheral drivers and livecoding capabilities (via Serial port/UART) for the same CPU (and dozens others) clocks in at only 8,550 lines of Assembly (that’s 5%). Of course that isn’t a fair or even very meaningful comparison, but the magnitudes in difference speak volumes here…

The following videos provide more of an Forth overview and demonstrate livecoding on an Arduino and an FPGA (the latter includes a custom Forth CPU itself):

AmForth can be downloaded from here: http://amforth.sourceforge.net/. The AmForth website also contains a cookbook of various examples. The book reference shown in the video is Starting Forth by Leo Brodie, generally a great intro to programming.

James Bowman and his open source J1 Forth CPU running on a Lattice FPGA. This project uses the first fully open source FPGA development toolchain, Project IceStorm. More info

To clarify where I’m going with all this: I’m not at all proposing that we should be dropping everything and (re-)adopt languages like Forth, but I do think a) there’re definite commercial, educational & scientific research segments which would greatly benefit from fresh community investment in these style languages and b) some of the ideas are highly interesting to me even if applied to more mainstream environments (incl. audio & shader development).

One of the experiments done with my own JS & browser based Forth VM & REPL to define pixel shaders in Forth and transpile them into GLSL. The original idea comes from the Forth Haiku Salon, however the transpiler implementation here is entirely Forth based and produces more efficient code.

Since this article is getting rather long, I will have to defer a more complete treatise of my foray into this language to another post. However, in closing, I’d like to leave you with some work-in-progress results of this (currently still C based) musical ARM adventure of mine.