Iteration: an Opera

Malorie Casimir
5 min readMay 29, 2018

--

In opera and classical music we have this song structure called the da capo aria. Da capo means “at the head”- it’ll make sense later. Basically, in this structure, the aria is split into two sections: the A section and the B section. If the A section is fast, the B section will be slower and vice versa. What makes da capo arias so special is that you can make them completely your own. After singing the A and B sections through once, you sing the A section again with ornaments, which are extra added notes that you can compose yourself or borrow from other singers.

Let’s think about the da capo aria within the context of iteration in Ruby.

Singing through the aria once is represented by defining the variable that I called “da_capo_aria”. It contains an array with strings that represent the A and B sections. After, I defined a method called “da_capo_aria_performance” that uses the map iterator. It takes us through our da capo aria but “adds ornamentation” by shoveling it into a variable set to an empty array named “da_capo_aria_finale”. Naturally we need a separate data structure for our grand finale. Because the ornamentation of the A section is the finale of our aria, this method returns that array with our statement “We’re ornamenting the a section!”

Easy right? Let’s look at the iteration that exists within the context of composing a song and throw in another data structure: a hash. For our example, we’ll look at the first song from Robert Schumann’s song cycle Dichterliebe**.

First step in many a composer’s composition process: be touched, moved and inspired beyond all reason by ink on a page. For this song, Schumann chose Heinrich Heine’s “Im Wunderschoenen Monat Mai”***.

Im Wunderschoenen Monat Mai libretto

Let’s use a hash to represent Schumann’s Dichterliebe. The key of this hash will be the number 1 to signify that this is the first song in the cycle and its value will be an empty hash. This empty hash will eventually hold different parts of the song.

dichterliebe = {1 => {}}

Most songs, from classical to pop, have some sort of introduction or prelude. In the case of the song in our example, the prelude is just a few measures:

Prelude to Im Wunderschoenen Monat Mai

In our code, let’s add the intro to dichterliebe[1].

dichterliebe[1][:prelude] = "3 bars of a nostalgic introduction with     a certain je ne sais quoi"

Now we get:

=> {1=>{:prelude=>"3 bars of a nostaligic introduction with a               certain je ne sais quoi"}}

We’re ready to add poetry to the music! Thanks to Schumann, we get to sing:

Verse 1 of Im Wunderschoenen Monat Mai

Let’s add this to our code:

dichterliebe[1][:verse_1] = "Im wunderschönen Monat Mai,\nAls alle Knospen sprangen,\nDa ist in meinem Herzen\nDie Liebe aufgegangen"

I added new lines, (“\n”), because the spacing would be very awkward when it outputs to our console.

This might be enough music for some but some Schumann purists will wonder who gave us the right to cut one of Schumann’s masterpieces. Let’s complete the hash by adding the interlude, verse 2 and the postlude.

dichterliebe[1][:interlude] = "2 bars seamlessly carrying us to verse 2"dichterliebe[1][:verse_2] = "Im wunderschönen Monat Mai,\nAls alle Vögel sangen,\nDa hab ich ihr gestanden\nMein Sehnen und Verlangen."dichterliebe[1][:postlude] = "3 bars of depth and longing that leads us tactfully into the next song in the cycle..."

We have a song! Well, we have a hash that contains elements of our song, but it’s a start! I’ll use the “.each” iterator to bring it all together. Before I do that, I’ll set a variable called “performance” to an empty array. We can think of this empty array as the concert hall that holds our data in a way that’s more presentational and easy to read.

First, I iterated down to the first song in Dichterliebe or the hash with a key of 1 whose value is the hash of song components. Then, using the “.each” method, we take each “section” of the song as outlined within the pipes and “shovel” it into our performance array.

Now, we’re ready to present this composition to the world via defining a method. Below we see the method called “im_wunderschoenen_monat_mai” with our “dichterliebe” hash, “performance” array, and iteration via the “.each” method. In the end, we “puts” our “performance” array.

In order to fit the code into the snippet below, I indented after lines 9 and 14. If you end up copying and pasting this, don’t include those indentations because it will effect the final output!

This outputs:

3 bars of a nostaligic introduction with a certain je ne sais quoi
Im wunderschönen Monat Mai,
Als alle Knospen sprangen,
Da ist in meinem Herzen
Die Liebe aufgegangen
2 bars seamlessly carrying us to verse 2
Im wunderschönen Monat Mai,
Als alle Vögel sangen,
Da hab ich ihr gestanden
Mein Sehnen und Verlangen.
3 bars of depth and longing that leads us tactfully into the next song in the cycle...
=> nil

We ultimately got “nil” because we used “puts” as a means of outputting our data to the console. We can think of that “nil” as everyone leaving the theater at the end of the night to grab drinks across the street.

Our favorite “opera singer” from HP3

*Baroque opera is one of the key characteristics of the baroque period in music which lasted from 1600–1750. For context, Mozart didn’t come around until 1756.

**Translates to: A Poet’s Love

***Translates to: In the Wonderful Month of May

--

--