Diamond rock by Mark Seemann
A diamond kata implementation written in Rockstar
I've previously written about the diamond kata, which has become one of my favourite programming exercises. I wanted to take the Rockstar language out for a spin, and it seemed a good candidate problem.
If you're not aware of the Rockstar programming language, it started with a tweet from Paul Stovell:
This inspired Dylan Beattie to create the Rockstar programming language. The language's landing page already sports an idiomatic implementation of the FizzBuzz kata, so I had to pick another exercise. The diamond kata was a natural choice for me.
"To really confuse recruiters, someone should make a programming language called Rockstar."
I'll start with the final result. What follows here are the final lyrics to Diamond rock. As you'll see, it starts with a short prologue after which it settles into a repetitive pattern. I imagine that this might make it useful for audience participation, in the anthem rock style of e.g. We Will Rock You.
After 25 repetitions the lyrics change. I haven't written music to any of them, but I imagine that this essentially transitions into another song, just like We Will Rock You traditionally moves into We Are the Champions. The style of the remaining lyrics does, however, suggest something musically more complex than a rock anthem.
Your memory says The way says A Despair takes your hope The key is nothing Your courage is a tightrope Let it be without it If your hope is your courage Let the key be the way Build your courage up If your hope is your courage The key says B Build your courage up If your hope is your courage The key says C Build your courage up If your hope is your courage The key says D Build your courage up If your hope is your courage The key says E Build your courage up If your hope is your courage The key says F Build your courage up If your hope is your courage The key says G Build your courage up If your hope is your courage The key says H Build your courage up If your hope is your courage The key says I Build your courage up If your hope is your courage The key says J Build your courage up If your hope is your courage The key says K Build your courage up If your hope is your courage The key says L Build your courage up If your hope is your courage The key says M Build your courage up If your hope is your courage The key says N Build your courage up If your hope is your courage The key says O Build your courage up If your hope is your courage The key says P Build your courage up If your hope is your courage The key says Q Build your courage up If your hope is your courage The key says R Build your courage up If your hope is your courage The key says S Build your courage up If your hope is your courage The key says T Build your courage up If your hope is your courage The key says U Build your courage up If your hope is your courage The key says V Build your courage up If your hope is your courage The key says W Build your courage up If your hope is your courage The key says X Build your courage up If your hope is your courage The key says Y Build your courage up If your hope is your courage The key says Z Give back the key Dream takes a tightrope Your hope's start'n'stop While Despair taking your hope ain't a tightrope Build your hope up Give back your hope Raindrop is a wintercrop Light is a misanthrope Let it be without raindrop Darkness is a kaleidoscope Let it be without raindrop Diamond takes your hour, love, and your day If love is the way Let your sorrow be your hour without light Put your sorrow over darkness into flight Put your memory of flight into motion Put it with love, and motion into the ocean Whisper the ocean If love ain't the way Let ray be your day of darkness without light Let your courage be your hour without darkness, and ray Put your courage over darkness into the night Put your memory of ray into action Let satisfaction be your memory of the night Let alright be satisfaction with love, action, love, and satisfaction Shout alright Listen to the wind Let flight be the wind Let your heart be Dream taking flight Let your breath be your heart of darkness with light Your hope's stop'n'start While your hope is lower than your heart Let away be Despair taking your hope Diamond taking your breath, away, and your hope Build your hope up Renown is southbound While your hope is as high as renown Let away be Despair taking your hope Diamond taking your breath, away, and your hope Knock your hope down
Not only do these look like lyrics, but it's also an executable program!
If you want to run the program, you can copy the text and paste it into the web-based Rockstar interpreter; that's what I did.
When you Rock! the lyrics, the interpreter will prompt you for an input. There's no instructions or input validation, but the only valid input is the letters
Z, and only in upper case. If you type anything else, I don't know what'll happen, but most likely it'll just enter an infinite loop, and you'll have to reboot your computer.
If you input, say,
E, the output will be the expected diamond figure:
A B B C C D D E E D D C C B B A
When you paste the code, be sure to include everything. There's significant whitespace in those lyrics; I'll explain later.
Readable code #
As the Rockstar documentation strongly implies, singability is more important than readability. You can, however, write more readable Rockstar code, and that's what I started with:
Space says LetterA says A GetLetter takes index If index is 0 Give back LetterA If index is 1 retVal says B Give back retVal If index is 2 retVal says C Give back retVal GetIndex takes letter Index is 0 While GetLetter taking Index ain't letter Build Index up Give back Index PrintLine takes width, l, lidx If l is LetterA Let completeSpaceCount be width minus 1 Let paddingCount be completeSpaceCount over 2 Let padding be Space times paddingCount Let line be padding plus l plus padding Say line Else Let internalSpaceSize be lidx times 2 minus 1 Let filler be Space times internalSpaceSize Let totalOuterPaddingSize be width minus 2, internalSpaceSize Let paddingSize be totalOuterPaddingSize over 2 Let padding be Space times paddingSize Let line be padding plus l, filler, l, padding Say line Listen to input Let idx be GetIndex taking input Let width be idx times 2 plus 1 Let counter be 0 While counter is lower than idx Let l be GetLetter taking counter PrintLine taking width, l, counter Build counter up While counter is as high as 0 Let l be GetLetter taking counter PrintLine taking width, l, counter Knock counter down
This prototype only handled the input letters
C, but it was enough to verify that the algorithm worked. I've done the diamond kata several times before, so I only had to find the most imperative implementation on my hard drive. It wasn't too hard to translate to Rockstar.
Although Rockstar supports mainstream quoted strings like
"B", and so on, you can see that I went straight for poetic string literals. Before I started persisting Rockstar code to a file, I experimented with the language using the online interpreter. I wanted the program to look as much like rock lyrics as I could, so I didn't want to have too many statements like
Shout "FizzBuzz!" in my code.
Obscuring space #
My first concern was whether I could obscure the space character. Using a poetic string literal, I could:
The rules of poetic string literals is that everything between
says and the newline character becomes the value of the string variable. So there's an extra space after
After I renamed all the variables and functions, that line became:
Your memory says
Perhaps it isn't an unprintable character, but it is unsingable.
No else #
Else looks conspicuously like a programming construct, so I wanted to get rid of that as well. That was easy, because I could just invert the initial
If l ain't LetterA
This effectively switches between the two alternative code blocks.
Obscuring letter indices #
I also wanted to obscure the incrementing index values
3, etcetera. Since the indices are monotonically increasing, I realised that I could use a counter and increment it:
number is 0 If index is number Let retVal be LetterA Build number up If index is number retVal says B Build number up If index is number retVal says C
The function initialises
0 and assigns a value to
retVal if the input
index is also
If not, it increments the
number (so that it's now
1) and again compares it to
index. This sufficiently obscures the indices, but if there's a way to hide the letters of the alphabet, I'm not aware of it.
After I renamed the variables, the code became:
Your courage is a tightrope Let it be without it If your hope is your courage Let the key be the way Build your courage up If your hope is your courage The key says B Build your courage up If your hope is your courage The key says C
There's one more line of code in the final lyrics, compared to the above snippet. The line
Let it be without it has no corresponding line of code in the readable version. What's going on?
Obscuring numbers #
Like poetic string literals, Rockstar also supports poetic number literals. Due to its modulo-ten-based system, however, I found it difficult to come up with a good ten-letter word that fit the song's lyrical theme. I could have done something like this to produce the number
Your courage is barbershop
or some other ten-letter word. My problem was that regardless of what I chose, it didn't sound good. Some article like
the would sound better, but that would change the value of the poetic number literal.
a tightrope is the number 19, because
a has one letter, and
tightrope has nine.
There's a simple way to produce 0 from any number: just subtract the number from itself. That's what
Let it be without it does. I could also have written it as
Let your courage be without your courage, but I chose to take advantage of Rockstar's pronoun feature instead. I'd been looking for an opportunity to include the phrase Let It Be ever since I learned about the
Let x be y syntax.
The following code snippet initialises the variable
Your courage to
19, but on the next line subtracts 19 from 19 and updates the variable so that its value is now
Your courage is a tightrope Let it be without it
I had the same problem with initialising the numbers 1 and 2, so further down I resorted to similar tricks:
Raindrop is a wintercrop Light is a misanthrope Let it be without raindrop Darkness is a kaleidoscope Let it be without raindrop
Here I had the additional constraint that I wanted the words to rhyme. The rhymes are a continuation of the previous lines'
hope, so I struggled to come up with a ten-letter word that rhymes with
wintercrop was the best I could do.
a wintercrop is 10, and the strategy is to define
Darkness as 11 and 12, and then subtract 10 from both. At the first occurrence of
Let it be without raindrop,
it refers to
Light, whereas the second time
it refers to
Lyrical theme #
Once I had figured out how to obscure strings and numbers, it was time to rename all the readable variables and function names into idiomatic Rockstar.
At first, I thought that I'd pattern my lyrics after Shine On You Crazy Diamond, but I soon ran into problems with the keyword
taking. I found it difficult to find words that would naturally succeed
taking. Some options I thought of were:
- taking the bus
- taking a chance
- taking hold
- taking flight
- taking time
times is a keyword, and apparently
time is reserved as well. At least, the online interpreter choked on it.
Taking a chance sounded too much like ABBA.
Taking hold created the derived problem that I had to initialise and use a variable called
hold, and I couldn't make that work.
Taking flight, on the other hand, turned out to provide a fertile opening.
I soon realised, though, that my choice of words pulled the lyrical theme away from idiomatic Rockstar vocabulary. While I do get the Tommy and Gina references, I didn't feel at home in that poetic universe.
On the other hand, I thought that the words started to sound like Yes. I've listened to a lot of Yes. The lyrics are the same kind of lame and vapid as what was taking form in my editor. I decided to go in that direction.
Soon I also conceived of the extra ambition that I wanted the verses to rhyme. Here, it proved fortunate that the form
let x be y is interchangeable with the form
put y into x. Some words, like darkness, are difficult to rhyme with, so it helps that you can hide them within a
put y into x form.
Over the hours(!) I worked on this, a theme started to emerge. I'm particularly fond of the repeated motifs like:
Your hope's start'n'stop
which rhymes with
up, but then later it appears again as
Your hope's stop'n'start
which rhymes with
heart. Both words, by the way, represent the number 0, since there's ten letters when you ignore the single quotes.
I spent more time on this that I suppose I ought to, but once I got started, it was hard to stop. I found the translation from readable code into 'idiomatic' Rockstar at least as difficult as writing working software. There's a lesson there, I believe.
Rockstar is still a budding language, so I did miss a few features, chief among which would be arrays, but I'm not sure how one would make arrays sufficiently rock'n'roll.
A unit testing framework would also be nice.
If you liked this article, please endorse my Rockstar skills on LinkedIn so that we can "confuse recruiters."