Recently, I have been really interested in the question what programming really is, and how we can practice getting better at it. I explored many weird things, like the relationship between code and painting. I gave a workshop in Cambridge where people got artwork styles, like Rococo, Graffiti and Expressionism, and they had to create an algorithm in that style. It was really cool and fun, but I was not sure where the learning was.
More recently, I have been thinking about what we can learn from seeing art a writing, especially poetry. At the awesome conference BoosterConf*, they let me do a workshop on Code and Poetry, and it was really insightful.
If you missed it, but you still want to explore this lovely ideas, here are the 5 exercises we did. We did it in pairs, which I can really recommend, but alone should be possible too.
Assignment 1: Rhyme
The first ingredient of a poem, of course, is rhyme. Pick an algorithm and observe just the sounds of the lines of code. In the examples, I use sorting, as they are well known and short, but you may of course also dive into your own code base!
if len(m) <= 1: #one return m #em else: middle = len(m)) // 2 #two left = m[:middle] #mid-dle right = m[middle:] #mid-dle left = merge_sort(left) #left right = merge_sort(right) #right result = list(merge(left, right)) #right return #right
What happened here in the workshop, by the way, is that some people interpreted rhyme differently. They said the sound of a line is it’s most important operation, like this:
return sort(less)+sort(equal)+sort(greater) # lists
It sounds like “lists” since you merge two lists. Lovely!
Assignment 2: Change the rhyme
Now, play with your algorithm. Can you make it rhyme more? Think of renaming variables, rearranging lines of code or adapting expressions:
def merge_sort(m): #em if len(m) <= 1: return m #em else: middle = 0.5 * (len(m))) // 2 #em left = m[:middle] #mid-dle right = m[middle:] #mid-dle left = merge_sort(left) #eft right = merge_sort(right) #right daft = list(merge(left, right)) #eft return daft #eft
Assignment 3: Rhythm
The second ingredient of a poem is of course, rhythm. Pick another (or the same) algorithm and count the syllables of each line, and write them in comments behind the line, like this:
upper = len(alist) - 1 #9 for passnum in range(upper,0,-1): #12 for i in range(passnum): #6 if alist[i] > alist[i+1]: #12 temp = alist[i] #5 alist[i] = alist[i+1] #9 alist[i+1] = temp #7
You will see soon that this is more tricky that you think, as you will have to vocalize symbols like =. Is this “is”? Is it “e-quals”? Or “be-comes”? My choice is “stores”.
This type of reflection will help you think about what the code means too!
Assignment 4: Change the rhythm
Now, play with your algorithm again. Can you make the “beat” of your algorithm nicer? You can use tricks like changing variable names, and extracting expressions into variables, or even adding non-useful variables or lines:
x, y = 0, 1 #6 upper = len(list) - 1 #8 r = range(upper,0,x) #8 for passnum in r: #5 for i in range(passnum): #6 list[i + x] = min(list[i], list[i + 1]) #12 list[i + 1] = max(list[i], list[i + 1]) #12
I found that this type of manipulation helped me to really understand what variables were used where. If I make this name shorter, what lines will be affected?
Assignment 5: Make a real poem
A haiku, a limerick or a sonnet! Abandon any notion of clean code and go crazy!
This one of the poems in the workshop:
int quicksort_partition(int[] from, int below, int above) { var prince = from[above]; // There once was a prince from above var pauper = below - dove; // And a pauper from below with no dove make(ref pauper, from, prince); // The pauper got princed swap(from, above, pauper + hints); // And after he traded hints return pauper + love; // The pauper came back with some love }
Enjoy!
* I can seriously recommend it to everyone. Amazing food, great workshops, lovely city and venue and the best conference wifi I HAVE EVER SEEN!
Is this real programmimg? ?. Very Nice last speak on booster listening to this now
Cool!