The Programs of the Week We Lost David Bowie
This Week’s Program: Jan 11 - Jan 15
Alan Rickman, too. With the passing of such creative forces, what more can we do than ensure our own creative energies don’t go to waste?
8aba22f47c2fbd28001cb165f60d70438732bf4e
On Monday, on my personal website, I added a lightning bolt in the style of Aladdin Sane. I reverted this commit on Tuesday
1ce5a19da695ee08d36831a46b2b45ea404dac64
Last week, I wrote a fair bit about asynchrony in this program, and the need to provide an imperative, linear sequences at the edges. Gary Bernhardt describes this kind of ethos as Functional Core, Imperative Shell. I also wrote about CSP (Communicating sequential processes) and how channels and queues are effective at coordinating concurrent execution.
This week, I brought in core.async
to see how this would work in
practice. It turns out it doesn’t do much different. This program is
almost the exact same as using the promise
based implementation. I
cleaned up some of this code in the next commit.
In the 2-arity play
function we create a channel that is passed into
the temporal recursive arity (same as the promise). When the melody
has completed, the tail call writes to the channel. This is a blocking
operation if there is nothing reading from the channel, but because
Overtone’s scheduling happens off the main thread, that doesn’t
matter. We just need a way to signal back up to the caller that the
song has completed playing. Back in the 2-arity function, we read from
that channel in the context of a go
block: an inversion of control
thread. The go
block returns a channel of its own that holds the
value of its computation. So calling play
in its 2-arity form is
asynchronous and returns a channel. When you read that channel, it
blocks until the song has completed playing. Exactly like the promise
implementation.
The thought occurs to me that I might be doing it wrong. I think core.async is still rad, though, and I’m going to keep it around to experiment on.
8e909868dd25dadf89ebd563da769f5ea23a6ac0
Instead of writing my recording to the same file every time I run the program, I record to a tempfile. This file will be cleaned up whenever tempfiles on the system get cleaned up. I think this is the first bit of Java interop I’ve done in this program so far.
3aaee1faa4714ff42bb5c542ecac44de0971f12e
My first macro! I’ve been
scared of macros for a long time and have been actively avoiding their
creation. Now I see that they’re not that bad. Here, I make a macro
to make a recording of a song to a path. The song argument is called
“out” assuming that it’s a core.async channel and performs a blocking
read within the returned form. I made this a macro, and not a normal
function, because I wanted to pass in the call to the play
function
without it being evaluated immediately. It’s Lisp! Code is data! The
little sigils and reader sugar that you see in macros is for quoting
forms and generating symbols.
a2722b9599feda4303743fb4a9dd4ed253393ed2
Here, I am preparing for next week. Guess what I’ll be doing.
He’s told us not to blow it
Cause he knows it’s all worthwhile
– Mark