Monday, February 18, 2019

Music Theory for Programmers


For this post I wanted to do something a little different. Although my profession is software engineering, I would also call myself an amateur musician. Maybe even a singer/songwriter. I play the guitar, keyboards and a handful of other instruments and also like to write and record music.

For a while now I've been thinking about how much writing code and writing music were similar. And maybe that's why I like doing both things so much. Just like programming I can get lost for hours making a song sound just right. So I decided to enumerate the ways that writing music and writing code are similar. No knowledge of musical notation or theory is required to enjoy this post!

Music Theory for Programmers

You might think that writing code and writing music have nothing in common, but they actually share a lot of similarities. Besides both being creative endeavors that build something from pure thought, the underlying processes are also very similar. For example both are made up of loops and modules, both have varying input and output, and both compile down to binary.

As a programmer I assume you already know a lot about programming. So let me talk a little about how music works. As a human being who listens to music you probably already know a great deal about music whether you realize it or not.
  • Songs are made up of sections such as verse, chorus and bridge
  • Those sections are usually repeated multiple times
  • Songs have a key that dictate which notes are played
  • Songs have an underlying structure or motif
Let's delve into some of the similarities between music and code.

Loops

There are lots of loops in code; we have for loops, while loops, recursive loops. Loops are everywhere in our code. They allow us to iterate over an array or do something over and over until a certain condition exists, or even find the factorial of a number.

Music has a lot of loops too. The drum beat, the bass line, verses and choruses. Without loops music would just be a long string of notes without structure, and pretty dang hard to follow and listen to. The human mind craves patterns. If the listener can't discern any patterns she will write the music off as noise.

Here's what a loop looks like in music notation, called a repeat sign. Here the second note is repeated.


Modules

Code is made up of modules within modules within modules. Programs contain classes, classes contain methods, methods contain code blocks. Modularity is the cornerstone of programming. It's what makes it possible for us to read and understand code and keeps our code DRY (don't repeat yourself).

Music contain modules too. A song contains sections, those sections contain measures, those measures contain notes. Without modules written music would be hard to read too. Imagine pages and pages of musical notes with no delineation. You would get lost pretty quickly.


Which is equivalent to something like this minimized code.


Input/Output

Just as code modules can accept parameters as input to produce different output, so can music. Think of the verse of your favorite song; there probably isn't just one. There are usually at least two or three different verses. But the verses sound pretty much the same, just the words are different. The verse module takes words as an input and applies the structure of the verse's melody to it to produce different output.

Here's the structure of a song represented as if it were a set of code modules.

intro()
verse(A)
$chorus()
verse(B)
$chorus()
bridge()
verse(C)
$chorus()
outro()

Here's an example of a module with varying input. There are two lines of lyrics both set to the same melody.



Development Lifecycle

In code we have a development lifecycle. First we come up with an idea for an application. Then we write some specifications. Next we do the development by writing our code. Finally we debug and refactor our code until it's ready to be released into the wild.

Creating music isn't much different. First you come up with an idea for a song, play around with some chords until it sounds good and then write it down. Next you fire up your DAW and start recording the instruments and vocals then mix and apply effects. Then you find every thing that doesn't sound right and refactoring it until it does sound right. Finally after you have everything sounding right you release it into the wild.

Design Patterns

In programming we have design patterns that describe general, reusable solutions to a commonly occurring problems. There are also common reusable patterns in music that help us build songs. They are known as chord progressions. Chord progressions are a series of chords that are played in a specific order. Certain chord progressions sound very good to the human ear.

Probably one of the most common is the four chord progression I-V-vi-IV. There are countless popular songs using it. The numbers 1, 5, 6, and 4 are chord numbers in a key. In music theory there are seven primary chords in each key, each of which has a number associated with it. In the key of C, I-V-vi-IV translates to the chords C-G-Am-F. The reason numbers are used is so that you can easily move to a different key and have the exact same progression, just higher or lower in pitch.

Check out this mash up of songs all with that same I-V-vi-IV chord progression to see just how pervasive it is:
https://www.youtube.com/watch?v=oOlDewpCfZQ

Software Tools

In programming we have IDEs (integrated development environments) to help us write code. In music we have DAWs (digital audio workstations) to help us record and mix songs. Both make our lives so much easier. Writing code in notepad sucks. And having to record an entire song perfectly  is nearly impossible, at least for me. A DAW allows you to record sounds, add effects to them, cut and paste them and manipulate them in all sorts of ways.

Asynchronous

Plenty of languages support asynchronous coding so we can have multiple things going on at once without blocking. Music is massively asynchronous. You have a number of instruments or vocals all executing at the same time. Here's what playing a section of music might look like in C#.

async Task PlayVerseAsync(string lyrics)
{
    var tasks = new Task[] {
        PlayVocalsAsync(lyrics),
        PlayDrumsAsync(),
        PlayBassAsync(),
        PlayPianoAsync()
    };
    await Task.WhenAll(tasks);
}

Compilers

Music and code both compile down to binary. Your code compiles down to machine executable codes. Music compiles down to digital audio files such as WAV and MP3.

Input Devices

They both use keyboards ;)

Complex Notation

They both have strange and complex notation. If a musician were to look at some source code they would probably have no idea what it means.

function reduce(a: int[], reducer: (int, int)=>int): void {
  let sum: int = 0;
  for (let i = 0; i < a.length; i++) {
sum += reducer(sum, a[i]);
}
return sum;
}

On the other hand if a programmer were to look at some sheet music they would be equally confused. Here's particularly perplexing piece of music.

Bugs

Music and code can both be very frustrating to work on. Sometimes there's a bug in your code and you can't figure it out. Sometimes there's a bug in your song and you can't work it out either. But when you finally do figure it out you feel that rush of greatness!

Conclusion

I hope I have convinced you that writing music and writing code share some similarities. I enjoy doing both. Each gives me the same feelings of starting a project, doing some creative things and getting a sense of accomplishment at the end. Both are a creative process that requires deep concentration and thought. I guess that is the main similarity between the two is the creative process. But as I've shown above it doesn't stop there.

Wednesday, February 13, 2019

Polymer LitElement is Here!



I've been using Polymer to help me write web components for a couple months now. During that time I've been using Polymer's base class PolymerElement which among other things provides DOM templating and data binding.

Just the other day the Polymer team announced the official release of their new base class called LitElement. It is provides a more lightweight and simpler way to create web components as compared to the PolymerElement.

I decided to give it a try and this is what I learned.

First of all I really like the simplicity of the LitElement programming model. It's very lightweight and easier to understand than the old PolymerElement way of doing things. If you've ever used React you will find that using LitElement is almost exactly like creating components in React. In fact I think the Polymer team borrowed heavily from React (or maybe ripped them off depending on your point of view).

The two-way data binding of PolymerElement is gone and replaced by one-way data binding, a la React. The old two-way data binding felt more Angular, while the new on-way feels, as I said, more like React. You can't rely on changes to propagate up anymore. Now you need to use events to notify parent elements that something has changed. This is a little more work, but in the long term probably more simple and reliable.

PolymerElement's two-way data binding was sometimes complex to understand and required you to use all sorts of extra configuration to make it work. LitElement's one-way data binding is just simple and easy to understand. I'm not sure I would even call it data binding, really. Your element has properties and when they change your element is re-rendered.

There is the big difference, I think. In PolymerElement you had a static accessor where you defined your HTML template with data binding embedded into it. With LitElement you now have a render() method that gets called any time a property of your element changes. The render() method completely rebuilds the DOM structure of your element. Instead of embedded data binding you build a string that represents your DOM using template literals accessing your properties directly.

For example, here's what a data binding looks like in PolymerElement where "name" is a property of the element.

1
2
3
4
5
    static get template() {
        return html`
            <div>Hello, <span>[[name]]!</span></div>
        `;
    }

And here's what it looks like in LitElement.

1
2
3
4
5
    render() {
        return html`
            <div>Hello, <span>${this.name}!</span></div>
        `;
    }

Notice how we are building a string inserting "this.name" property as an embedded expression in the template literal rather than using a static binding "[[name]]".

This works because behind the scenes the LitElement creates get and set accessor methods for the properties of your element. Whenever a property changes it calls the render method so that the template string gets rebuilt. Then it figures out what changed and updates that portion of the light DOM on the page.

The great thing about using template literals is that you can now use any kind of JavaScript expression to build your DOM template, giving you a lot more power.

The consequence of this is that element properties must now be immutable. If you use React you are probably used to this. If one of your properties is an object or array you can't change an element in it and expect LitElement to notice that change and call render(). You will need to make a new copy of the object or array and change the value you want. If you want to know why this is better in the long run I suggest going through the React tutorial. They explain it in detail.

This also means that changes to properties in child elements will not automagically propagate up to the parent's properties. If you want to notify the parent of a change you will need to use custom events. Again, I suggest going through the React tutorial if you are not familiar with this way of doing things. (I told you they ripped off React :-p)

There is also a new way to bind properties to DOM element. For event handlers you use an @ before the event name and then an embedded expression using the name of the handler function. To define boolean attributes use a question mark. To bind to properties use a dot.


`<input type="text"
    @keyup="${this.keyPressed}"
    .value="${this.name}"
    ?hidden="${!this.isVisible}">`

In all cases you use embedded expressions for all of these bindings, even event handlers.

Using TypeScript

If you're like me and prefer using type annotations in your code, LitElement has support for TypeScript. It also allow you to use decorators to define your custom element and its properties. Use the customElement() decorator on your class and the property() decorator on properties. This will set up your element and properties for you making your code more terse.

1
2
3
@customElement('my-element')
export class MyElement extends LitElement {
  @property({type : String})  prop1 = 'Hello World';

I tried this but was having trouble getting it to work. In general I was having trouble getting the LitElement npm package to work nicely with TypeScript. The TS files in the npm package would not compile correctly because there was something missing that it relies on. This also affected the code completion in VS Code. [Edit] I did get type definitions and decorators to work correctly. Problem was that my compiler was not up to the version required for LitElement, which I think is 3.2. After installing latest everything worked fine. Also, you will need to set experimentalDecorators to true in your tsconfig file if you want to use decorators.

I'm really hoping TS support gets better over time. I didn't have these issues using PolymerElement.

Conclusion

In some ways LitElement feels like a step back because it's so much more primitive than PolymerElement was. But I feel like this is a good thing because it makes everything a whole lot simpler to understand and reduces complexity in your apps. I suggest you go ahead and start using LitElement now and hopefully TypeScript support will get better (or I will figure out what I'm doing wrong) in time.

Start learning LitElement here: https://lit-element.polymer-project.org/guide

Since LitElement is so much like React, and the documentation is limited for LitElement, I also suggest reading the React tutorial. https://reactjs.org/docs/hello-world.html