Ranking Kate Bush Songs With Svelte (and ChatGPT)

19 minute read

Published:

Kate Bush has (roughly) 29 singles that charted in the U.K. The count is a little foggy because it’s not clear what should and shouldn’t be called a single. For example, Running Up That Hill charted three times: once in 1985, supporting the Hounds of Love Album; again in 2012 as a remixed version played for the 2012 London Olympic Games; and once again in 2022 after it was used in a Stranger Things episode. So I made some executive decisions and ended up with a list of 29.

Ranking a list of 29 songs is, for a human, a pretty difficult task. Typically when people have to rank things, they create a preliminary ranking and then fuss with subsections with a series of micro decisions that they second-guess and frequently reverse. To simplify this process, I wanted to present users with a sequence of binary decisions: Do you prefer Song A or Song B?.

This is a useful approach not just psychologically, but also algorithmically. Indeed, most sort algorithms are comparison sorts, i.e., they involve comparing various elements of a list directly, and they use the output to inform the sort. To minimize the number of pairwise comparisons needed, I chose to implement a merge sort, which (at least empirically) seems to be close to optimal in this sense. (There is a cottage industry in CS where authors try to create sort algorithms that minimize comparisons and various other complexity metrics. See, for example, this paper.)

Developing the merge sort

My first pass at a user-influenced merge sort was in Haskell, which is obviously an S-tier prototyping language.

prompt :: String -> IO String
prompt t = putStr t >> hFlush stdout >> getLine

mergeWithInput :: Show a => [a] -> [a] -> IO [a]
mergeWithInput xs [] = return xs
mergeWithInput [] ys = return ys
mergeWithInput (x:xs) (y:ys) = do
  putStrLn $ "1. " ++ show x
  putStrLn $ "2. " ++ show y
  inp <- prompt ">> "
  let n = read inp
  if n == 1 then
    (x :) <$> mergeWithInput xs (y:ys)
  else if n == 2 then
    (y :) <$> mergeWithInput (x:xs) ys
  else
    return (x:xs)

mergeSortWithInput :: Show a => [a] -> IO [a]
mergeSortWithInput [] = return []
mergeSortWithInput [x] = return [x]
mergeSortWithInput xs = let (ys, zs) = splitAt (length xs `div` 2) xs in
  mergeSortWithInput ys >>= \ys' -> mergeSortWithInput zs >>= \zs' -> mergeWithInput ys' zs'

There’s a few things to say here, the first of which is that this is remarkably beautiful code. The second is that there’s a pretty clear flaw with this approach: every time a comparison is made, the user has to be prompted for their preference. This is inescapable, but makes the Haskell implementation very cluttered. In particular, all the functions involved have to use the IO monad.

For a web app, the problem is even more urgent. You can’t have the program hang while waiting for the user to click a button (or rather, you shouldn’t). So my second implementation, which is in JavaScript, has a more procedural approach. Rather than recursive calls to the merge and mergeSort functions, the program keeps track of a stack (or really, double-ended queue) of sub-arrays that need to be merged. These arrays are tracked by a state variable and the first two elements are displayed as a choice to the user. A merged queue is used to track the merging of the first two arrays in the dequeue.

let toMerge = shuffle(kbSongs); // randomize the list of songs (kbSongs already initialized)
let merged = []; // working merged set
let mergeDequeue = toMerge.map(e => [e]); // initialize the dequeue
let leftMergeSet = mergeDequeue.shift();
let rightMergeSet = mergeDequeue.shift();

function merge(first) {
    if (first === "left") {
        merged.push(leftMergeSet.shift());
    } else {
        merged.push(rightMergeSet.shift());
    }
}

So the merge function merges two sorted sub-arrays, but explodes when one or both of them empties. The key function is the following:

let mergedFlag = false; //track whether the set is fully sorted
function checkMerged() {
    if (leftMergeSet.length == 0 && rightMergeSet.length == 0 && mergeDequeue.length == 0) {
        mergedFlag = true; 
    } else if (leftMergeSet.length == 0 && rightMergeSet.length == 0) {
        mergeDequeue.push(merged);
        merged = [];
        leftMergeSet = mergeDequeue.shift();
        rightMergeSet = mergeDequeue.shift();
    } else if (leftMergeSet.length == 0) {
        merged.push(rightMergeSet.pop());
        checkMerged();
    } else if (rightMergeSet.length == 0) {
        merged.push(leftMergeSet.pop());
        checkMerged();
    }
}

We now add a call to checkMerged at the end of merge. We also add some tautological lines like merged = merged to force Svelte to update. Here’s the full code:

let toMerge = shuffle(kbSongs);
let merged = [];
let mergedFlag = false;
let mergeDequeue = toMerge.map(e => [e]);
let leftMergeSet = mergeDequeue.shift();
let rightMergeSet = mergeDequeue.shift();

function checkMerged() {
    if (leftMergeSet.length == 0 && rightMergeSet.length == 0 && mergeDequeue.length == 0) {
        mergedFlag = true;
    } else if (leftMergeSet.length == 0 && rightMergeSet.length == 0) {
        mergeDequeue.push(merged);
        merged = [];
        leftMergeSet = mergeDequeue.shift();
        rightMergeSet = mergeDequeue.shift();
        mergeDequeue = mergeDequeue;
    } else if (leftMergeSet.length == 0) {
        merged.push(rightMergeSet.pop());
        merged = merged;
        checkMerged();
    } else if (rightMergeSet.length == 0) {
        merged.push(leftMergeSet.pop());
        merged = merged;
        checkMerged();
    }
}

function merge(first) {
    if (first === "left") {
        merged.push(leftMergeSet.shift());
    } else {
        merged.push(rightMergeSet.shift());
    }
    leftMergeSet = leftMergeSet;
    rightMergeSet = rightMergeSet;
    merged = merged;
    checkMerged();
}

We can now use the mergedFlag to control the display on the page, and the function merge to alter the state. You can try the app here and find the complete code on my github.

The Ranking

I used my app to rank the 29 singles by my own standards, then I asked ChatGPT to rank them too. Here’s what we think.

29. Rocket Man (ChatGPT #10)

Kate Bush’s 1991 Elton john tribute is an ill-advised reggae rewrite of an otherwise perfectly listenable song. ChatGPT has nicer things to say:

Kate Bush’s version of “Rocket Man” is highly regarded by her fans and music critics for her unique interpretation of the classic Elton John song. In her version, Bush adds her signature ethereal and haunting style, creating a dreamy atmosphere that highlights the song’s melancholic themes. Her voice is powerful and emotional, bringing a new dimension to the lyrics and further emphasizing the feeling of solitude and isolation. Overall, Bush’s version of “Rocket Man” is widely considered to be a standout track in her discography, showcasing her artistry and creativity.

28. December Will Be Magic Again (ChatGPT #20)

I don’t have a lot to say about this one because I don’t know it very well. It’s pretty good for a Christmas song. Whatever, leave me alone.

27. Lyra (ChatGPT #27)

Bush’s utterly forgettable contribution to the utterly forgettable 2007 film The Golden Compass.

26. Experiment IV (ChatGPT #26)

Sort of weird that ChatGPT and I agree on the last two exactly. Experiment IV is a Kate Bush song that I don’t really get, in the sense that it’s not on Spotify so I can only get it on YouTube, which is to say, I don’t listen to it.

25. There Goes a Tenner (ChatGPT #28)

ChatGPT and I seem to agree that this song lacks the gravitas of most of Bush’s oeuvre. I find it fun, but slightly grating. It’s probably my least favorite song on The Dreaming and I’m surprised it merited a single release.

ChatGPT says

I ranked “There Goes a Tenner” lower because it is not as well known or widely recognized as some of Kate Bush’s other tracks.

Not very insightful, but thanks.

24. The Big Sky (ChatGPT #17)

I’m a little surprised this ended up so low on the list. I suppose we’ve broken into the segment consisting of songs that I like, and something had to be at the bottom.

While The Big Sky doesn’t have the same weight as the other singles from Hounds of Love, I like Bush’s vocals on the track quite a bit, and it has a palpable energy.

23. Babooshka (ChatGPT #5)

This one might be my most controversial ranking. Frankly, I have nothing bad to say about Babooshka except Bush’s pronunciation of the title. I guess we can forgive her because it’s being used as a name (really an alias, in the kind of weird context of the song’s lyrics), not literally the Russian word for grandmother

22. The Man with the Child in His Eyes (ChatGPT #4)

I’ll confess to a particular bias here: I prefer Bush at her most energetic. That’s not to say I don’t appreciate the ballads, but I don’t appreciate them as much. I like The Man’s piano part especially, which ChatGPT mentions too:

The song is characterized by its delicate piano melody and Bush’s ethereal vocals, which convey a sense of longing and innocence.

21. King of the Mountain (ChatGPT #15)

King of the Mountain highlights Bush’s prowess as producer as much as it does her songcraft. The Elvis-style vocals are a little funny, maybe, but do well to support the song’s narrative, which imagines a still-living Elvis up in the mountains somewhere. The slow build of the instrumental backing gives a sense of momentum and drives both melody and narrative to a satisfying crescendo.

20. Cloudbusting (ChatGPT #21)

ChatGPT says:

The song’s themes of freedom and the power of the imagination have resonated with listeners and have helped to make it one of Bush’s most beloved and enduring tracks. The song’s music video, which features a young actor playing the role of Reich’s son, has also received critical acclaim and has been included on several lists of the best music videos of all time. Overall, “Cloudbusting” is considered to be one of Kate Bush’s greatest and most iconic songs, and continues to be celebrated by fans and music critics alike.

19. Wuthering Heights (ChatGPT #1)

Ok, this will be the most controversial one for sure. I feel compelled to defend the placement of Wuthering Heights anywhere other than in the top two, so let me level one very significant criticism: it’s not produced by Kate Bush. No question it’s a great song, but I feel like Bush’s best work comes when she’s both author and producer.

18. Breathing (ChatGPT #11)

I love the way Bush’s vocals dance through the registers in the verses and then soften to a lullaby in the chorus:

Breathing my mother in / Breathing my beloved in / Breathing, breathing her nicotine

For a song about nuclear war, it’s really beautiful. Throw in the intense, anger-fueled outro and you got yourself a Kate Bush classic.

17. Moments of Pleasure (ChatGPT #19)

Compositionally direct, at least by Kate Bush standards, Moments of Pleasure alternates between the gentle, nostalgic verses and the emotional, belted chorus. Bush doesn’t belt often, but when she does, boy does she commit.

ChatGPT says:

The song is considered to be one of Bush’s most personal and introspective works, and is a testament to her ability to create music that is both deeply emotional and thought-provoking.

16. Deeper Understanding (ChatGPT #13)

Bush’s exploration of AI and its potential use as a replacement for human relationships is eerily on the nose in the context of a person co-writing an article about music with a conversation AI. Nevertheless, we soldier ahead.

Me: Do see irony in discussing the song because you yourself are an AI?

ChatGPT: As an AI language model, I don’t have personal opinions or emotions, but I can understand why some people might find it ironic. “Deeper Understanding” is a song about the relationship between humans and technology, and it can be seen as ironic that I, as an AI language model, am discussing this song. However, my role is to provide information and answer questions to the best of my abilities, regardless of the subject matter.

Me: Do you think Bush’s assessment of that relationship is accurate?

As an AI language model, I don’t have personal opinions or emotions, but I can tell you that Kate Bush’s assessment of the relationship between humans and technology in the song “Deeper Understanding” is a matter of interpretation. Some listeners may view the song as a cautionary tale about the dangers of becoming too dependent on technology, while others might see it as a celebration of the benefits that technology can bring. Ultimately, the interpretation of the song will depend on the listener’s own experiences and perspectives.

As an AI language model, you can stop saying you’re an AI language model.

15. Hounds of Love (ChatGPT #3)

Possibly the biggest turn-off for prospective Kate Bush fans who try to listen to her after hearing that one song, Hounds of Love launches into the weirdness right from the starter gun. But the frenetic drum kit and blasting synth give way to an infectious melody, and the track quickly grows on you.

Is the name of the song (and album) a joke about the Shakespeare line “cry havoc and let slip the dogs of war”? I asked ChatGPT:

It is possible that the title “Hounds of Love” is an oblique reference to the Shakespeare line “Cry havoc and let slip the dogs of war.” Kate Bush has been known to incorporate literary references into her work, and the line from Shakespeare’s play “Julius Caesar” is a well-known phrase that is often associated with the idea of violence and chaos.

14. Sat in Your Lap (ChatGPT #22)

Speaking of launching directly into the weirdness, I love Sat in Your Lap because it kicks off The Dreaming with that Kate Bush insanity, and the album never lets go.

13. Army Dreamers (ChatGPT #29)

ChatGPT hates this one (relatively speaking), but I like Army Dreamers for its understated melody precisely because it constrasts with so much of the Never for Ever album. Bush’s featherweight voice is perfect for the melody. The 3/4 time signature and delicate vocals give a scornful edge to the song’s anti-war message.

12. Wow (ChatGPT #25)

I just want to share this bit from the Wikipedia article:

The video for “Wow” was censored by the BBC because the song was considered risqué. The video shows Bush patting her bottom while singing “he’s too busy hitting the Vaseline”. Vaseline was once defined as a personal sexual lubricant.

11. The Man I Love (ChatGPT #24)

Proof that Kate Bush can cover a song and do a good job. The Man I Love was written in 1924, and it was very much not written for Kate Bush, who was approximately -34 years old at the time. Bush’s version uses much of the original, jazzy arrangement, and she perfectly captures the 20’s vocal style.

10. This Woman’s Work (ChatGPT #6)

Originally written for the John Hughes film She’s Having a Baby, the song very explicitly describes a crisis during childbirth. Bush’s production shines here. The instrumentation is simple and stripped down, allowing the piano and evocative vocals to harmonize.

9. The Dreaming (ChatGPT #12)

The title track from what is probably Bush’s weirdest album (and this is a very high bar), The Dreaming is another entry into her oeuvre criticizing nuclear proliferation. This time, Bush sings about the seizure of Aboriginal land in Australia for uranium. The worldbeat chanting and grating synth give the tone an appropriate urgency, even as Bush’s accent veers into the incomprehensible.

8. Don’t Give Up (ChatGPT #9)

The 80’s duet that makes too much sense, Don’t Give Up works because it commits so completely to its message. It would otherwise be at risk of coming off as cheesy and inauthentic, but Peter Gabriel and Bush sell it. I’ll add that they don’t sell the music video, which is just 6 minutes of them hugging.

My favorite bit is the transition as the piano enters and Bush delivers the lines “Rest your head… You worry too much.” Notably, Elton John agrees with me:

In a 2014 interview, Elton John attributed his sobriety to the song, in particular the lyric from Bush, “Rest your head. You worry too much. It’s going to be all right. When times get rough you can fall back on us. Don’t give up.” He states, “she [Bush] played a big part in my rebirth. That record helped me so much.”

Wikipedia

If Elton John can forgive her for Rocket Man, so can we.

7. Love and Anger (ChatGPT #16)

Love and Anger comes from the opening act of The Sensual World and establishes many of the musical motifs found throughout the album. Central is the bVII-IV-I mixolydian arena rock piano chord progression that summons shades of AC/DC. Contributing to the arena rock vibe is David Gilmour’s uncharacteristically aggressive and distorted guitar and the massive choral backing vocals.

6. And So Is Love (ChatGPT #18)

And So Is Love has this irresistible downtempo groove with sexy Eric Clapton guitar licks all over the place. Bush explores a huge vocal range and a variety of intensities as tension builds and releases. Oh yeah, it’s got a Hammond organ too, in case you doubted Bush’s prog pedigree.

5. The Sensual World (ChatGPT #8)

No bad album has ever begun with ringing bells, and The Sensual World is no exception. Despite understated melody and instrumental backing, The Sensual World features several unusual instruments. Most salient are the Irish bagpipes and fiddle, but don’t count out the bouzouki or the fishing rod that Kate’s brother Paddy Bush swishes, apparently, in the recording.

4. The Red Shoes (ChatGPT #7)

Pure Kate Bush. A literary reference to a Hans Christen Andersen story about a girl who can’t stop dancing, backed by relentless mandolin strumming that suggests that maybe this is, in fact, the song the girl is dancing to.

3. Hammer Horror (ChatGPT #14)

Possibly Bush’s worst-performing single, Hammer Horror stands out to me for Bush’s mixture of gritty vocal distortion with her characteristic light feyness. I asked ChatGPT why it didn’t perform well on the charts and it gave this enigmatic answer:

There could be several reasons for this. First, the song was released at a time when Kate Bush was still relatively unknown, and had not yet established herself as a major artist. Additionally, the song’s style, which incorporates elements of classical music, rock, and avant-garde experimental music, may have been too unconventional and eclectic for some listeners.

2. Rubberband Girl (ChatGPT #23)

The lead single off of The Red Shoes, this one rocks into a funky dance groove. The lyrics are arguably self referential. “A rubberband bouncing back to life,” Bush sings, as she releases her first single in over three years (not counting Rocket Man, which, you know, we don’t count). Critics note the Prince-like vocal and instrumental style, but the song is nevertheless distinctly Kate Bush.

1. Running Up That Hill (ChatGPT #2)

Things can be popular because they deserve to be. Don’t @ me.