Programming

I was recently flattered by a former colleague, Ilya Rostovtsev, about my knowledge of computer programming languages. I was surprised because I have always found I have so much more to learn about programming itself and the languages we use.

I have been asked recently by potential employers to rate my knowledge of particular languages. Most of the languages I use regularly are in significant motion - not just in terms of language features but also in the paradigms communities are inventing to use them. This makes my judgements of myself rather challenging. I am an expert C programmer because that languages has largely stabilized and I have used it a lot. As for C++ it feels like playing "snakes and ladders: from intermediate to expert as C++ and its use evolves. An encouraging trend in recent releases is welcome compensations for the challenging syntactic complexities templates introduced. It's impressive how C++ has been able to track ideas from other languages and communities and integrate those paradigms. Here is an example of how much cleaner code can be with (C++17): https://adrianfreed.com/content/c-container-output-stream-header-file

I am an expert and experienced programmer - expert because I have addressed challenges that stretch what programming languages and computer systems can be used for - experienced because I have done this many times over the years.

Early on these challenges were stupidly mechanical like punching holes in paper tape, in cards with a stylus (remember the hanging chads?), and with an electronic punch. I never managed to get the endless microcassettes of the Sinclair PC to reliably store anything.

Another significant constraint in the early days was limited computer memory. I developed a C compiler for the 8085 processor I used in a home-built computer in the late 1970s. The assembler programming class I was taking at college at the time required us to run our code on 6809 development boards which were suprisingly similar in capability and complexity to the original Arduinos. I got a 6809 C code generator going to do those assignments. I managed to skirt around programming very much assembler code by this method. When I was trying to squeeze code into the limited memory I could afford I discovered the “readonly” reserved keyword in the PCC front end which I used to direct strings and constants into the EPROM of my DIY computer. I wasn’t very happy with the way this was defined in the early C compilers (as a storage class designator like static, register, volatile and auto). This prompted me to start correspondence with Dennis Ritchie and Steve Johnson (author of PCC) at Bell Labs. on how to proceed. It turned out that a few others had also started developing compilers for small microprocessors. What emerged eventually was of course “const” a type modifier which was much more flexible (allowing for const pointers for example).

In 1981, a colleague from the Unversity of New South Wales (UNSW), Peter Ivanov, proposed we take advantage of an interesting feature of “round the world” airline tickets - unlimited North America air travel. We visited UC Berkeley, Disneyland, and Bell Labs together. Somehow I managed to squeeze San Francisco, Paris, Sydney, and Montreal into that month. It is still a fond memory that when I ran out of tickets in my ticket boook for North American flights, the friendly Continental airlines clerk handed me another book full of open tickets. Flights were not full in those days and I just showed up at the airport and looked at where flights were going that day.

At Bell Labs we knocked on the door of a guy called Bjarne who we had heard was ruffling feathers at Bell Labs. by developing a preprocessor to add classes to C. I knew why this might be interesting because Wirth visited my alma mater while I was learning Pascal and talked about Modula.

Implementing things like “const” prompted his abandonment of a preprocessor strategy and the bifurcation that would become C++. By a fun coincidence Rick Mascitti, one of the programmers that joined the team I worked on at Bell Labs a few years later, named C++.

Another memory-saving trick used in those early compilers I developed required the assembly-code skills of a buddy, Graeme Elseworthy. I made the C compiler output calls to a library of code he wrote that emulated a stack machine. This short-cut was inspired by my study of Dijkstra’s many contributions including his enthusiasm for the fast one-pass Algol-68 compiler for the Burroughs Stack Machines. Inadvertently we had discovered a software architecture that is now standard (e.g. LLVM). Dijkstra also visited my alma mater while I was studying computer science. I was a nerdy fan - having asked for his 1972 book on structured programming as a high school math prize. A measure of his influence is that just in the last month his name has come up twice in my different technical projects - his graph algorithm is a common part of circuit routing software and his work on clock synchronization is still relevant and important.

In the mid 1980s, very few people were using C++ at Bell Labs or elsewhere. Other earlier languages were competing for mindshare in the reliable, object-oriented and functional programming spaces, e.g., ada, lisp, smalltalk. For Aegis, our Bell Labs project, we chose an object-oriented dialect of lisp. Still unpublished this work for the ATT PC, presaged News, Javascript and Java as a way to develop interactive graphical user interfaces with a DOM, and client/server architecture. This experience prepared me for the awkward accommodation that programmers have now been living with for over half a century - compiled languages for “efficiency” programming and interpreted languages for “productivity” programming. My most recent programming projects reflect this: a Python program for analog circuit design, and a C++ program for a MIDI touch controller. This bifurcation has practical and historical roots although I am one of many who think this is technically unnecessary. I was fortunate to be part of the Parlab where we developed a model of how this unification might work under the rubric, “Sejits”.

This bifurcation has produced two different ways of doing object-oriented programming: static classes as exemplified by C++ and dynamic (prototype) object-orientation implemented in Smalltalk, Self, NewtonScript and Javascript. This latter approach is central to graphical programming languages like PD and Max/MSP/Jitter.

After John MacCallum’s promising early experiments exploring whether OSC messages could be the basis of a new object-oriented language, I enthusiastically joined and managed a team effort to integrate the language into PD and Max/MSP/Jitter to address their notorious lack of user-defined data structures.

The “odot” language favors an interesting programming style which simplifies challenges often encountered in conventional programming languages. For example, exceptions are handled by delegation - already a fundamental part of language and the basis of its object dynamism. There is no hidden name mangling or type signatures - introspection isn’t an exceptional facility it is built from the ground up. Object, Class, and Message are all implemented in a single concept in “odot”.

One of the biggest reliefs using “odot” is not worrying about memory management or invalidated states during iterations. This and the complexity of “const” are avoided by using cloning semantics where expressions transform objects into new objects functionally. Recent standardizations of C++ have introduced features with some parallels to this paradigm- notably C++20’s range views, and string_views. Unfortunately, in C++ we still have the cognitive burden of knowing which operations might invalidate a view - a situation that doesn’t arise by construction with “odot”.

Although we haven’t adapted this cloning paradigm to native Python, “odot" has influenced my programming style in Python3. I rarely write or modify the contents of a Python class. In my recent analog design environment, PAD, the key data structure (eDict) is assembled functionally by accretion without modification.

Software engineering is an aspect of programming language knowledge with its own rich history. It’s not enough to know the “features” of a programming language. How to employ those features to produce reliable software is essential in engineering programming as opposed to what I call exploratory or experimental programming where reliablity of a rapidly evolving program is often not the goal. Here I have learned that the quality of the IDE and underlying tools is very determinant.

I was amused to discover people after all these decades still appreciate the efficiency of the old PCC compiler. It is usually 5 times faster than GCC. I remember very fast compile times when I was a student on time-shared machines with about the same memory as an Arduino with 3% of the speed. This fast compile time encouraged me to build programs incrementally with testing every few lines or every new function and I still seek development environments with this focus on speed. The Teensy microcontroller is optimized for fast load and run times and has enormously contributed to the quality and quantity of my embedded systems programming.

My least favorite software engineering task is debugging with a step by step, breakpointing debugger. I prefer to take longer and write code that is correct by construction. As I have refined this I spend less and less time debugging. On rare occasion when I am stuck with a debugger it is usually tracking a bug in the compiler or libraries. These debuggers have also been useless for about 70% of my code because I have written a lot of real-time audio and gesture processing code and they can’t recreate the context the code is running in.

This real-time requirement helped a lot of fellow programmers at CNMAT develop good software engineering practices like defensive programming. I like to build the test harness as early as possible. As it turned out Max/MSP turned out to be a great environment for this. We could do our efficiency programming in C or C++ and build rich tests and examples in Max/MSP to exercise the code. I was so enthusiastic with the value of this I encouraged Amanda Chaudhary to to take this to the next level with her language OSW. She was able to provide a way for people to build their C++ extensions (the externalizer) and load them dynamically into a running patch - significantly increasing productivity of programmers and encouraging incremental development now fashionable under the rubric of agile programming.

The biggest change in IDE’s over the years has been the hinting and navigation tools. Some people really like their direct access to versioning systems. I don't use these very much as I try to test as I go - rarely referring back to old releases. A subtle but important aspect of these systems is a normalization of coding styles and paradigms. This normalization is a two-edged sword. Python indentation is an annoying extreme example. Fast access to libraries and documentation encourages people to reuse well-tested libraries whilst at the same time discouraging some interesting alternative ideas that might have been pursued.

Some of the IDEs I use currently have interesting hinting that can, for example, explain which standards of C++ a particular paradigm works for.

An insight about programming languages that has been consistantly helpful came from conversations with Georgina Born, an anthropologist/sociologist who studied IRCAM, an institution I was working at in the 1980s. Her studies of our practices ended up bootstrapping what is now called software studies. The insight is that programs are written by people for other people to read and that might be their primary value. That they also are interpretable instructions for computers is an important side effect but programs are rarely static so one’s code is likely destined for transformation and reuse by another person - likely a stranger.

I didn’t learn to program from text books, my computer science classes, or web tutorials. I learned by studying other people’s large programs: initially the C Compiler, a Basic interpreter and UNIX itself. As I write code for others to use, I ask myself what are the valuable things I and others can learn from what I am writing? This puts me at odds sometimes with common dogma which discourages expressive uses of a programming language. I have encountered this in recent years around the Arduino IDE which has a few folk zealously proclaiming we shouldn’t use fancy C or new C++ features to avoid confusing “beginners". This is thinly disguised infantalization. There will always be beginner programmers but there are also a lot of people have been doing embedded programming on Arduinos for 15 years. My most recent C++ program, FingerPhoneUSB is an exploration of what aspects of C++ will significantly improve an embedded systems application. The current version sticks with the Arduino constraints of no RTTI, or standard libraries. Others have become impatient with the lack of the standard libraries with Arduino and have created special lightweight implementations. I am enthusiastic to see which of those library features my example will evolve to include.

Repos

https://github.com/adrianfreed/pad

https://github.com/adrianfreed/fingerphoneUSB

Selected Writings on Programming

o.OM: Structured-Functional Communication between Computer Music Systems using OSC and Odot, Bresson, Jean, MacCallum John, and Freed Adrian , FARM 2016

Dynamic Message-Oriented Middleware with Open Sound Control and Odot, John MacCallum, Rama Gottfried, Ilya Rostovtsev, Jean Bresson, Adrian Freed , ICMC, 2015

Agile Interface Development using OSC Expressions and Process Migration, MacCallum, John, Freed Adrian, and Wessel David, NIME 2013

Composability for Musical Gesture Signal Processing using new OSC-based Object and Functional Programming Extensions to Max/MSP, Freed, Adrian, MacCallum John, and Schmeder Andrew , NIME 2011

Dynamic Instance-based, Object-Oriented Programming (OOP) in Max/MSP using Open Sound Control (OSC) Message Delegation, Freed Adrian, MacCallum John, Schmeder Andy, ICMC 2011

Advances in the Parallelization of Music and Audio Applications, Eric Battenberg, Adrian Freed, David Wessel, ICMC 2010

Music Programming with the new Features of Standard C++, Freed, Adrian, and Chaudhary Amar , ICMC 1998

Guidelines for signal processing applications in C, Freed, Adrian , C Users Journal, 1993

The Portable C Compiler, Freed, Adrian , Australian UNIX User Group Meeting, 1980, Canberra, (1980)

AttachmentSize
rbfi.png679.21 KB