Poetry for programmers, an experimental workshop
Poetry and programming might seem like an unlikely match for a conference workshop, but I’m happy to report that it works.
Click to see my workshop abstract for Booster 2023
Poetry for programmers #
What are poems, if not elegantly encoded experiences captured in compact text?
Unlike A.I. systems, we humans can take fuzzy knowledge from wholly different fields and apply them elsewhere. In this workshop I’ll introduce you to the field of poetry with the goal of yielding some fresh perspectives on both writing and programming.
Maybe the worlds of code and poems lie too far afield to inspire each other, or maybe there’s something there that can spark better, clearer, more succinct writing? In this workshop we’ll play with this idea.
Workshop contents:
- An introduction to poetry.
- Hands-on exercises on poetry within the context of code.
- Summary.
Important notes:
- This workshop is open to all interested people. You don’t have to be a programmer to attend. You don’t need to consider yourself good at writing (nor programming). Feel free to write in Norwegian and/or English. You just need to be curious and be willing to try new things.
- You’ll need a laptop with git installed and a code editor. If in doubt I can recommend the VS Code editor.
- I will not make you recite poetry out loud. This will be a safe space for personal text exploration.
Hope to see you in my workshop!
Link to the Booster Conference 2023 workshop description.
Researching a brand new workshop #
My motivation for creating this workshop is that I wanted to share my love for text in both code and poetical forms.
When I originally pitched this workshop it didn’t exist. And once I had accepted the conference invitation to hold the workshop I went straight into research mode to surface all useful resources for a workshop such as this. For me that meant revisiting some books I had in my small library and ordering some new one’s.
Over a number of early mornings and evenings I eventually formed a formula for a workshop which I thought had a decent chance at entertaining people. I had a hunch it would do well, but I was still a bit on edge as to how participants would actually react.
How it went down #
It was a bit far out, but a good kind of far out. (Workshop participant).
After welcoming everyone to the workshop I went straight to reading a classic poem as well as a couple of my own poems.
I then gave a brief introduction to poetry, which was distilled from this amazing little book called A Poetry Handbook by Mary Oliver. After the introduction we spent five minutes writing freely.
Following the text warmup I made us take a short detour to read some select programmers’ writings. What I wanted to show was that a lot of programmers write inspiringly well.
Then we came to the meat and potatoes of the workshop where I introduced them to the story of a student programmer who got themselves entangled into a weird summer job.
This scenario was crafted such that the conference participants had no other option but to write poems within the code. And to help them do that I gave them a list of randomness as well as a cheat sheet of writing devices to employ. Haha, looking back I think I was quite inspired by my past experiences with running RPGs and LARPs.
To my relief, no one contested the believability of the story, instead they dove into it and wrote and wrote. I walked around and helped.
Finally I concluded the workshop by reciting a poem. You might think it was weird to not have everyone read out their writing but that was a feature and not a bug of this workshop. I instead invited everyone to share poems over email if they wanted to.
Poems from the workshop #
A huge thanks to everyone who participated and a big thank you to the one’s who shared their poems with me over email afterwards.
Poetry by dvberkel
/*
* Randomness
*
* vf guvf enaqbzarff?
*
* Is this randomness?
* Or
* a message
* vealed by obfuscation
*
* How would one know
*/
Poetry by snorremd
/**
* CallCenter
*
* A darkness deeply dwells
* in the depths of this place
*
* Of cubicles, queues, callers calling
*
* No escape for receptionists
* receptive receptionists, callers deceptive
* no end in sight
*
* Emptying the queue,
* call count close to zero
* Wait,
* new callous calls coming in
*
* Is it lunch soon?
* No end in sight
*
* Receptionist reassuredly resigned, signing off.
*/
Poetry by Djamel Adjou
/**
* his hands are sweaty, knees weak already, nowhere to hide, its showtime!
* Pulsing in your ears as you drown in fear,
* staring menacingly at the handle.
* Buzz it goes, and you writhe in woe as you pick up and say "hello"!
*/
callerCalling(caller) {
...
}
Poetry by sindrekjr
Let's just try to make the text flow. Okay.
...
That's hard. Never managed it before, can't manage it now. Warming up the writing muscles is like baking a cake - something I could never do on the spot.
I wonder what it's like for all those spontaneous writers, spinning words and rhyme with nary a thought in the world.
Do they ponder and do they strive?
Do they long for a way to thrive?
I do. Sometimes.
If poetry is about expression, then poetry is for me.
But if poetry is like a river, then I still sit there like a stone.
What do you do when poetry doesn't flow, and the urge to express is trapped?
# from here on out, GitHub Copilot takes over
What do you do when you're not sure what to say, but you know you have to say something?
I don't know. I don't know. I don't know.
I don't know. I don't know. I don't know.
I don't know. I don't know. I don't know.
Poetry by Elisabeth Marie
export class CallCenter {
/*
A queue with many
many objects
containing any
kind of types
*/
queue = [];
receptionists = [];
/*
Push a caller
in to a call list.
A queue with callers
caller callings.
Why does the caller
call these callings?
What is these callings
really about?
*/
callerCalling(caller) {
this.queue.push(caller);
}
receptionistSigningIn(receptionist) {
this.receptionists.push(receptionist);
}
receptionistSigningOff(receptionist) {
this.receptionists = this.receptionists.filter(
(item) => item !== receptionist
);
}
/*
Is the caller
really a caller?
Is the caller
inside the queue?
Get the caller
find the caller
Is the caller?
return true.
*/
isQueued(caller) {
return !!this.queue.find((item) => item === caller);
}
/*
A caller handler
handles caller calls.
Finds a receptionist
within the reception walls.
Is it really talking
or is it truly free?
A free receptionist
is what the caller needs.
Talk to caller,
and shift the queue.
The caller handled,
return handled true.
*/
handleCaller() {
const receptionist = this.receptionists.find((r) => r.talkingTo === null);
if (!receptionist) {
return false;
}
const caller = this.queue.shift();
receptionist.talkTo(caller);
return true;
}
/*
Lunch is more important.
Lunch is what I need.
With out it I am grumpy.
Hang up, I want to leave.
*/
lunchbreak() {
this.receptionists.forEach((r) => {
if (r.talkingTo === null) {
return;
}
this.queue.push(r.talkingTo);
r.hangup();
});
}
}
Poetry by Sigbjørn Hovland
call-center.mjs
export class CallCenter {
queue = []
receptionists = []
/*
Why is this person calling me?
Why does he or she not see?
That I'm a newbe...
*/
callerCalling(caller) {
this.queue.push(caller)
}
/*
Oh, my god. There she is
My favourite person, the one I miss
Now, I'm about to blush
Yes, for certain this is a crush...
*/
receptionistSigningIn(receptionist) {
this.receptionists.push(receptionist)
}
/*
Then I'm left here all alone
With myself, my thoughts and a small stone
In my shoe
Reminding me of you
*/
receptionistSigningOff(receptionist) {
this.receptionists = this.receptionists.filter(
(item) => item !== receptionist
)
}
/*
Please wait, you are next in line
Don't panic, everything will be fine
I just have a tiny little need to see
That people are waiting in line for me...
*/
isQueued(caller) {
return !!this.queue.find((item) => item === caller)
}
/*
There you go, I'm your friend
I look forward to the time we'll spend
Together, you and I
Feel free, don't be shy
*/
handleCaller() {
const receptionist = this.receptionists.find((r) => r.talkingTo === null)
if (!receptionist) {
return false
}
const caller = this.queue.shift()
receptionist.talkTo(caller)
return true
}
/*
Today I'll give it a chance
I'll buy her lunch, and ask her to dance
At least in my thoughts, you want the same
My favourite receptionist, this is not just a game
*/
lunchbreak() {
this.receptionists.forEach((r) => {
if (r.talkingTo === null) {
return
}
this.queue.push(r.talkingTo)
r.hangup()
})
}
}
caller.mjs
/*
I hate this phone call, I would rather die...
...than begging for help, all these questions of why.
Please take the phone, don't leave me in the deep
Remember: it's your system that are the creep
*/
export class Caller {
#srcNumber = null
constructor(srcNumber) {
this.#srcNumber = srcNumber
}
}
index.mjs
/*
They are like fire and water
Explode if they meet
The feelings are hidden
No toes on their feet
A absolute perfect mismatch
of thoughts and wishes
like a handful of broken dishes
*/
export * from './caller.mjs'
export * from './call-center.mjs'
export * from './receptionist.mjs'
receptionist.mjs
import { randomUUID } from 'node:crypto'
/*
OK, I'm both the he and she in this context
Not aware of the mixed roles in the code base
The classes, the functions, the scope
It's like connecting the dots with a rope
This does not reflect to reality
Rather end up like insanity
In my own head, like diverged "mees"
With no plan of someone to please
*/
export class Receptionist {
talkingTo = null
/*
Welcome,
you're next in line, haha
No, wait - it's a random queue
your number in line is like a sha
You'l never know, when to sue
Goodbye, and have a nice day!
*/
constructor(callSign = randomUUID()) {
this.callSign = callSign
}
/*
Hi, it's me again, the one you think you spoke to
Or, am I? As mentioned I end up both as me and you
It's frustrating
It's amazing
Both bad and good
Both sad, and good
Is it? Really?
There is noone here
No mather how hard you try,
This line is handled by AI.
*/
talkTo(caller) {
this.talkingTo = caller
}
/*
Bye
Nice try!
*/
hangup() {
this.talkingTo = null
}
}
Poetry by me
export class CallCenter {
queue = []
receptionists = []
/**
* callerCalling
*
* but which bear is best?
* I ponder from my window
* looking down at the beast
* rummaging through the leaves
*/
callerCalling(caller) {
this.queue.push(caller)
}
/**
* receptionistSigningIn
*
* the sound of money tumbling
* down on the pavement echoes
* in my mind as people starts
* popping up in today's Teams
* meeting.
*
* This is a meeting about a meeting
*
*/
receptionistSigningIn(receptionist) {
this.receptionists.push(receptionist)
}
/**
* receptionistSigningOff
*
* What a great Monday!
* My colleague uttered this sentence
* a bit too loud
* a bit too cheery
* sinking the sentence
* like a spear into us
* who had worked
* the night shift
*
* @param {*} receptionist
*/
receptionistSigningOff(receptionist) {
this.receptionists = this.receptionists.filter(
(item) => item !== receptionist
)
}
/**
* isQueued
*
* the furniture in my home
* is out to get me
*
* I swear
*
* when I throw myself down on the sofa
* it throws me
* into a headlock
*/
isQueued(caller) {
return !!this.queue.find((item) => item === caller)
}
/**
* handleCaller
*
* The walls of my cubicle trembled
* and a floppy disk fell out
* a tiny post-it was hanging on to its back
*
* clinging on
*
* this parchment looked ancient
* like a dead-sea scroll
* on further inspection
* it was my cubicle's former inhabitant
* chronicling his most prized code
*/
handleCaller() {
const receptionist = this.receptionists.find((r) => r.talkingTo === null)
if (!receptionist) {
return false
}
const caller = this.queue.shift()
receptionist.talkTo(caller)
return true
}
lunchbreak() {
this.receptionists.forEach((r) => {
if (r.talkingTo === null) {
return
}
this.queue.push(r.talkingTo)
r.hangup()
})
}
}
Moving forward #
I have made my workshop available under a permissive Creative Commons license. This way both me and others can develop this workshop concept further and introduce even more programmers to the joy of writing poetry and how it can inspire better writing.