0% found this document useful (0 votes)
102 views

Advanced Functional Programming in Industry

Advanced functional programming, including type-indexed data structures, type-level functions, kind polymorphism, and generic programming, is now commonplace in academia. In this experience report, I will explain why it's time to bring its advantages to industry too. Through my experience with Chordify, a web start-up that brings chord recognition to the masses, I have explored the benefits of exposing open-source, cutting-edge research to a wider audience. I will share several insights gained from my experience, namely with regards to: interaction between a functional backend and a PHP/JS frontend; handling millions of visits per month with minimal hassle; the importance of design and user-interface; and the logistics of an internet start-up.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
102 views

Advanced Functional Programming in Industry

Advanced functional programming, including type-indexed data structures, type-level functions, kind polymorphism, and generic programming, is now commonplace in academia. In this experience report, I will explain why it's time to bring its advantages to industry too. Through my experience with Chordify, a web start-up that brings chord recognition to the masses, I have explored the benefits of exposing open-source, cutting-edge research to a wider audience. I will share several insights gained from my experience, namely with regards to: interaction between a functional backend and a PHP/JS frontend; handling millions of visits per month with minimal hassle; the importance of design and user-interface; and the logistics of an internet start-up.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 84

Advanced Functional Programming in Industry

Jose Pedro Magalhaes

November 21, 2014


London, United Kingdom

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

1 / 46

Introduction

Haskell: a statically typed, lazy, purely functional language

Modelling musical harmony using Haskell


Applications of a model of harmony:

I
I
I
I
I

Jos
e Pedro Magalh
aes

Musical analysis
Finding cover songs
Generating chords and melodies
Correcting errors in chord extraction from audio sources
Chordifya web-based music player with chord recognition

Advanced Functional Programming in Industry, FP Days 2014

2 / 46

Demo: Chordify

Demo:

http://chordify.net

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

3 / 46

Table of Contents
Harmony
Haskell
Harmony analysis
Harmonic similarity
Music generation
Chord recognition: Chordify

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

4 / 46

What is harmony?
SDom

IV

Dom

Ton

Ton

V/V

D7

G7

Harmony arises when at least two notes sound at the same time

Harmony induces tension and release patterns, that can be described


by music theory and music cognition

The internal structure of the chord has a large influence on the


consonance or dissonance of a chord

The surrounding context also has a large influence

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

5 / 46

What is harmony?
SDom

IV

Dom

Ton

Ton

V/V

D7

G7

Harmony arises when at least two notes sound at the same time

Harmony induces tension and release patterns, that can be described


by music theory and music cognition

The internal structure of the chord has a large influence on the


consonance or dissonance of a chord

The surrounding context also has a large influence

Demo: how harmony affects melody

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

5 / 46

Simplified harmony theory I

A chord is a group of tones separated by intervals of roughly the


same size.

All music is made out of chords (whether explicitly or not).

There are 12 different notes. Instead of naming them, we number


them relative to the first and most important one, the tonic. So we
get I, II[, II . . . VI], VII.

A chord is built on a root note. So I also stands for the chord built
on the first degree, V for the chord built on the fifth degree, etc.
So the following is a chord sequence: I IV II7 V7 I.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

6 / 46

Simplified harmony theory II

Models for musical harmony explain the harmonic progression in music:


I

Everything works around the tonic (I).

The dominant (V) leads to the tonic.

The subdominant (IV) tends to lead to the dominant.

Therefore, the I IV V I progression is very common.

There are also secondary dominants, which lead to a relative tonic.


For instance, II7 is the secondary dominant of V, and I7 is the
secondary dominant of IV.

So you can start with I, add one note to get I7 , fall into IV, change
two notes to get to II7 , fall into V, and then finally back to I.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

7 / 46

An example harmonic analysis


SDom

IV

Dom

Ton

Ton

V/V

D7

G7

Piece
PT

PD

PT

IV

V/V

Jos
e Pedro Magalh
aes

II7

V7

D:7

G:7

Advanced Functional Programming in Industry, FP Days 2014

8 / 46

Why are harmony models useful?

Having a model for musical harmony allows us to automatically


determine the functional meaning of chords in the tonal context.
The model determines which chords fit on a particular moment in a
song.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

9 / 46

Why are harmony models useful?

Having a model for musical harmony allows us to automatically


determine the functional meaning of chords in the tonal context.
The model determines which chords fit on a particular moment in a
song. This is useful for:
I

Musical information retrieval (find songs similar to a given song)

Audio and score recognition (improving recognition by knowing


which chords are more likely to appear)

Music generation (create sequences of chords that conform to the


model)

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

9 / 46

Table of Contents
Harmony
Haskell
Harmony analysis
Harmonic similarity
Music generation
Chord recognition: Chordify

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

10 / 46

Why Haskell?

Haskell is a strongly-typed pure functional programming language:


Strongly-typed All values are classified by their type, and types are
known at compile time (statically). This gives us strong
guarantees about our code, avoiding many common
mistakes.
Pure There are no side-effects, so Haskell functions are like
mathematical functions.
Functional A Haskell program is an expression, not a sequence of
statements. Functions are first class citizens, and explicit
state is avoided.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

11 / 46

Notes

data Root = A | B | C | D | E | F | G
type Octave = Int
data Note = Note Root Octave

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

12 / 46

Notes

data Root = A | B | C | D | E | F | G
type Octave = Int
data Note = Note Root Octave
a4, b4, c4, d4, e4, f4, g4 :: Note
a4 = Note A 4
b4 = Note B 4
c4 = Note C 4
d4 = Note D 4
e4 = Note E 4
f4 = Note F 4
g4 = Note G 4

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

12 / 46

Melody
type Melody = [Note]
cMajScale :: Melody
cMajScale = [c4, d4, e4, f4, g4, a4, b4]

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

13 / 46

Melody
type Melody = [Note]
cMajScale :: Melody
cMajScale = [c4, d4, e4, f4, g4, a4, b4]
cMajScaleRev :: Melody
cMajScaleRev = reverse cMajScale

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

13 / 46

Melody
type Melody = [Note]
cMajScale :: Melody
cMajScale = [c4, d4, e4, f4, g4, a4, b4]
cMajScaleRev :: Melody
cMajScaleRev = reverse cMajScale
reverse :: [] []
reverse [ ]
= []
reverse (h : t) = reverse t +
+ [h]
(+
+) :: [] [] []
(+
+) = . . .

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

13 / 46

Transposition

Transposing a melody one octave higher:


octaveUp :: Octave Octave
octaveUp n = n + 1
noteOctaveUp :: Note Note
noteOctaveUp (Note r o) = Note r (octaveUp o)
melodyOctaveUp :: Melody Melody
melodyOctaveUp m = map noteOctaveUp m

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

14 / 46

Generation, analysis

Building a canon from a melody:


canon :: Melody Melody
canon m = m +
+ canon m

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

15 / 46

Generation, analysis

Building a canon from a melody:


canon :: Melody Melody
canon m = m +
+ canon m
Is a given melody in C major?
root :: Note Root
root (Note r o) = r
isCMaj :: Melody Bool
isCMaj = all ( cMajScale) map root

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

15 / 46

Details left out


We have seen only a glimpse of music representation in Haskell.
I

Rhythm

Accidentals

Intervals

Voicing

...

A good pedagogical reference on using Haskell to represent music:


http://di.uminho.pt/~jno/html/ipm-1011.html
A serious library for music manipulation:
http://www.haskell.org/haskellwiki/Haskore

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

16 / 46

Table of Contents
Harmony
Haskell
Harmony analysis
Harmonic similarity
Music generation
Chord recognition: Chordify

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

17 / 46

Application: harmony analysis


Parsing the sequence Gmin C7 Gmin C7 FMaj D7 G7 CMaj :
Piece
PD

PT

S
IV

V/IV
V/I

I7

Vmin

C:7

G:min

ins

S
V/IV
V/I

I7

Vmin

C:7

C:maj

IV

V/V

V7

F:maj

II7

G:7

D:7

G:min

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

18 / 46

Table of Contents
Harmony
Haskell
Harmony analysis
Harmonic similarity
Music generation
Chord recognition: Chordify

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

19 / 46

Application: harmonic similarity

A practical application of a harmony model is to estimate harmonic


similarity between songs

The more similar the trees, the more similar the harmony

We dont want to write a diff algorithm for our complicated model;


we get it automatically by using a generic diff

The generic diff is a type-safe tree-diff algorithm, part of a students


MSc work at Utrecht University

Generic, thus working for any model, and independent of changes to


the model

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

20 / 46

Table of Contents
Harmony
Haskell
Harmony analysis
Harmonic similarity
Music generation
Chord recognition: Chordify

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

21 / 46

Application: automatic harmonisation of melodies


Another practical application of a harmony model is to help selecting
good harmonisations (chord sequences) for a given melody:

# $ " "
%$ " "
"" ""

V III

" "
"" """
"

I III

" "

" "

"" ""
" "

"" ""
" "

II IV

III IV

!
!!!
V

We generate candidate chord sequences, parse them with the harmony


model, and select the one with the least errors.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

22 / 46

Visualising harmonic structure

Piece
Phrase
Ton
I: Maj

Dom
Sub

Ton
Dom

I: Maj

C: Maj III: Min IV: Maj II: Dom7 V: Dom7 C: Maj


E: Min

F: Maj D: Dom7 G: Dom7

You can see this tree as having been produced by taking the chords in
green as input. . .

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

23 / 46

Generating harmonic structure

Piece
Phrase
Ton
I: Maj

Dom
Sub

Ton
Dom

I: Maj

C: Maj III: Min IV: Maj II: Dom7 V: Dom7 C: Maj


E: Min

F: Maj D: Dom7 G: Dom7

You can see this tree as having been produced by taking the chords in
green as input. . . or the chords might have been dictated by the structure!

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

23 / 46

A functional model of harmony


PieceM [PhraseM ]

Jos
e Pedro Magalh
aes

(M {Maj, Min})

Advanced Functional Programming in Industry, FP Days 2014

24 / 46

A functional model of harmony


PieceM [PhraseM ]

(M {Maj, Min})

PhraseM TonM DomM TonM


|
DomM TonM

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

24 / 46

A functional model of harmony


PieceM [PhraseM ]

(M {Maj, Min})

PhraseM TonM DomM TonM


|
DomM TonM
TonMaj IMaj
TonMin Im
Min

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

24 / 46

A functional model of harmony


PieceM [PhraseM ]

(M {Maj, Min})

PhraseM TonM DomM TonM


|
DomM TonM
TonMaj IMaj
TonMin Im
Min
7
DomM VM
| VM
| VII0M
| SubM DomM
7
| II7M VM

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

24 / 46

A functional model of harmony


PieceM [PhraseM ]

(M {Maj, Min})

PhraseM TonM DomM TonM


|
DomM TonM
TonMaj IMaj
TonMin Im
Min
7
VM

DomM
| VM
| VII0M
| SubM DomM
7
| II7M VM

Jos
e Pedro Magalh
aes

SubMaj IIm
Maj
| IVMaj
| IIIm
Maj IVMaj
SubMin IVm
Min

Advanced Functional Programming in Industry, FP Days 2014

24 / 46

A functional model of harmony


PieceM [PhraseM ]

(M {Maj, Min})

PhraseM TonM DomM TonM


|
DomM TonM
TonMaj IMaj
TonMin Im
Min
7
VM

DomM
| VM
| VII0M
| SubM DomM
7
| II7M VM

SubMaj IIm
Maj
| IVMaj
| IIIm
Maj IVMaj
SubMin IVm
Min

Simple, but enough for now, and easy to extend.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

24 / 46

Now in HaskellI
A naive datatype encoding musical harmony:
data Piece = Piece [ Phrase ]
data Phrase where
PhraseIVI :: Ton Dom Ton Phrase
PhraseVI ::
Dom Ton Phrase

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

25 / 46

Now in HaskellI
A naive datatype encoding musical harmony:
data Piece = Piece [ Phrase ]
data Phrase where
PhraseIVI :: Ton Dom Ton Phrase
PhraseVI ::
Dom Ton Phrase
data Ton where
TonMaj :: Degree Ton
TonMin :: Degree Ton

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

25 / 46

Now in HaskellI
A naive datatype encoding musical harmony:
data Piece = Piece [ Phrase ]
data Phrase where
PhraseIVI :: Ton Dom Ton Phrase
PhraseVI ::
Dom Ton Phrase
data Ton where
TonMaj :: Degree Ton
TonMin :: Degree Ton
data Dom where
DomV7 :: Degree Dom
DomV
:: Degree Dom
DomVII0 :: Degree Dom
DomIVV :: SDom Dom Dom
DomIIV :: Degree Degree Dom

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

25 / 46

Now in HaskellI
A naive datatype encoding musical harmony:
data Piece = Piece [ Phrase ]
data Phrase where
PhraseIVI :: Ton Dom Ton Phrase
PhraseVI ::
Dom Ton Phrase
data Ton where
TonMaj :: Degree Ton
TonMin :: Degree Ton
data Dom where
DomV7 :: Degree Dom
DomV
:: Degree Dom
DomVII0 :: Degree Dom
DomIVV :: SDom Dom Dom
DomIIV :: Degree Degree Dom
data Degree = I | II | III . . .

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

25 / 46

Now in HaskellII
A GADT encoding musical harmony:
data Mode = MajMode | MinMode
data Piece ( :: Mode) where
Piece :: [ Phrase ] Piece

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

26 / 46

Now in HaskellII
A GADT encoding musical harmony:
data Mode = MajMode | MinMode
data Piece ( :: Mode) where
Piece :: [ Phrase ] Piece
data Phrase ( :: Mode) where
PhraseIVI :: Ton Dom Ton Phrase
PhraseVI ::
Dom Ton Phrase

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

26 / 46

Now in HaskellII
A GADT encoding musical harmony:
data Mode = MajMode | MinMode
data Piece ( :: Mode) where
Piece :: [ Phrase ] Piece
data Phrase ( :: Mode) where
PhraseIVI :: Ton Dom Ton Phrase
PhraseVI ::
Dom Ton Phrase
data Ton ( :: Mode) where
TonMaj :: SD I Maj Ton MajMode
TonMin :: SD I Min Ton MinMode

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

26 / 46

Now in HaskellII
A GADT encoding musical harmony:
data Mode = MajMode | MinMode
data Piece ( :: Mode) where
Piece :: [ Phrase ] Piece
data Phrase ( :: Mode) where
PhraseIVI :: Ton Dom Ton Phrase
PhraseVI ::
Dom Ton Phrase
data Ton ( :: Mode) where
TonMaj :: SD I Maj Ton MajMode
TonMin :: SD I Min Ton MinMode
data Dom ( :: Mode) where
DomV7 :: SD V Dom7 Dom
DomV
:: SD V Maj Dom
DomVII0 :: SD VII Dim Dom
DomIVV :: SDom Dom Dom
DomIIV :: SD II Dom7 SD V Dom7 Dom
Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

26 / 46

Now in HaskellIII

Scale degrees are the leaves of our hierarchical structure:


data DiatonicDegree = I | II | III | IV | V | VI | VII
data Quality
= Maj | Min | Dom7 | Dim
data SD ( :: DiatonicDegree) ( :: Quality) where
SurfaceChord :: ChordDegree SD

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

27 / 46

Now in HaskellIII

Scale degrees are the leaves of our hierarchical structure:


data DiatonicDegree = I | II | III | IV | V | VI | VII
data Quality
= Maj | Min | Dom7 | Dim
data SD ( :: DiatonicDegree) ( :: Quality) where
SurfaceChord :: ChordDegree SD

Now everything is properly indexed, and our GADT is effectively


constrained to allow only harmonically valid sequences!

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

27 / 46

Generating harmony

Now that we have a datatype representing harmony sequences, how do


we generate a sequence of chords?

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

28 / 46

Generating harmony

Now that we have a datatype representing harmony sequences, how do


we generate a sequence of chords?
QuickCheck! We give Arbitrary instances for each of the datatypes in our
model.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

28 / 46

Generating harmony

Now that we have a datatype representing harmony sequences, how do


we generate a sequence of chords?
QuickCheck! We give Arbitrary instances for each of the datatypes in our
model.
. . . but we dont want to do this by hand, for every datatype, and to have
to adapt the instances every time we change the model. . . so we use
generic programming:

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

28 / 46

Generating harmony
Now that we have a datatype representing harmony sequences, how do
we generate a sequence of chords?
QuickCheck! We give Arbitrary instances for each of the datatypes in our
model.
. . . but we dont want to do this by hand, for every datatype, and to have
to adapt the instances every time we change the model. . . so we use
generic programming:
gen :: .(Representable , Generate (Rep ))
Gen

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

28 / 46

Generating harmony
Now that we have a datatype representing harmony sequences, how do
we generate a sequence of chords?
QuickCheck! We give Arbitrary instances for each of the datatypes in our
model.
. . . but we dont want to do this by hand, for every datatype, and to have
to adapt the instances every time we change the model. . . so we use
generic programming:
gen :: .(Representable , Generate (Rep ))
[ (String,Int) ] Gen

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

28 / 46

Examples of harmony generation


testGen :: Gen (Phrase MajMode )
testGen = gen [("Dom_IV-V", 3), ("Dom_II-V", 4)]
example :: IO ()
example = let k = Key (Note \ C) MajMode
in sample0 testGen >
>= mapM (printOnKey k)

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

29 / 46

Examples of harmony generation


testGen :: Gen (Phrase MajMode )
testGen = gen [("Dom_IV-V", 3), ("Dom_II-V", 4)]
example :: IO ()
example = let k = Key (Note \ C) MajMode
in sample0 testGen >
>= mapM (printOnKey k)

> example
[C: Maj, D: Dom7 , G: Dom7 , C: Maj]
[C: Maj, G: Dom7 , C: Maj]
[C: Maj, E: Min, F: Maj, G: Maj, C: Maj]
[C: Maj, E: Min, F: Maj, D: Dom7 , G: Dom7 , C: Maj]
[C: Maj, D: Min, E: Min, F: Maj, D: Dom7 , G: Dom7 , C: Maj]

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

29 / 46

Generating a melody for a given harmony


We then generate a melody in 4 steps:
1. Generate a list of candidate melody notes per chord;
2. Refine the candidates by filtering out obviously bad candidates;
3. Pick one focal candidate melody note per chord;
4. Embellish the candidate notes to produce a final melody.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

30 / 46

Generating a melody for a given harmony


We then generate a melody in 4 steps:
1. Generate a list of candidate melody notes per chord;
2. Refine the candidates by filtering out obviously bad candidates;
3. Pick one focal candidate melody note per chord;
4. Embellish the candidate notes to produce a final melody.
These four steps combine naturally using plain monadic bind:
melody :: Key State MyState Song
melody k = genCandidates >
>= refine >
>= pickOne >
>= embellish
>
>= return Song k

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

30 / 46

Example I

&
n

?
#

Phrase
Ton
I: Maj

Ton

Dom
Sub

Dom

I: Maj

C: Maj III: Min IV: Maj II: Dom7 V: Dom7 C: Maj


E: Min

Jos
e Pedro Magalh
aes

F: Maj D: Dom7 G: Dom7

Advanced Functional Programming in Industry, FP Days 2014

31 / 46

Example II
&

? #

##

#n

Phrase
Ton
I: Min

Dom
Sub

Ton
Dom

E: Min IV: Min

Sub

I: Min
Dom

E: Min

A: Min IV: Min II: Dom7 V: Dom7


A: Min F] : Dom7 B: Dom7

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

32 / 46

Table of Contents
Harmony
Haskell
Harmony analysis
Harmonic similarity
Music generation
Chord recognition: Chordify

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

33 / 46

Back to Chordify: chord recognition

Yet another practical application of a harmony model is to improve chord


recognition from audio sources.
Chord candidates
Beat number

1.00 C
1

0.92 C
0.94 Gm
1.00 G
2

0.96 Em
0.97 C
1.00 Em
3

How to pick the right chord from the chord candidate list? Ask the
harmony model which one fits best.

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

34 / 46

Chordify: architecture

Frontend
I
I
I
I
I
I

Jos
e Pedro Magalh
aes

Reads user input, such as YouTube/Soundcloud/Deezer links, or files


Extracts audio
Calls the backend to obtain the chords for the audio
Displays the result to the user
Implements a queueing system, and library functionality
Uses PHP, JavaScript, MongoDB

Advanced Functional Programming in Industry, FP Days 2014

35 / 46

Chordify: architecture

Frontend
I
I
I
I
I
I

Reads user input, such as YouTube/Soundcloud/Deezer links, or files


Extracts audio
Calls the backend to obtain the chords for the audio
Displays the result to the user
Implements a queueing system, and library functionality
Uses PHP, JavaScript, MongoDB

Backend
I
I

I
I

Jos
e Pedro Magalh
aes

Takes an audio file as input, analyses it, extracts the chords


The chord extraction code uses GADTs, type families, generic
programming (see the HarmTrace package on Hackage)
Performs PDF and MIDI export (using LilyPond)
Uses Haskell, SoX, sonic annotator, and is mostly open source

Advanced Functional Programming in Industry, FP Days 2014

35 / 46

Chordify: numbers

Online since January 2013

Top countries: US, UK, Germany, Indonesia, Canada

Views: 3M+ (monthly)

Chordified songs: 1.5M+

Registered users: 200K

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

36 / 46

How do we handle these visitors?

Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB hard
drive

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

37 / 46

How do we handle these visitors?

Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB hard
drive

Single server hosts both the web and database servers

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

37 / 46

How do we handle these visitors?

Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB hard
drive

Single server hosts both the web and database servers


Can easily handle peaks of (at least) 700 visitors at a time

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

37 / 46

How do we handle these visitors?

Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB hard
drive

Single server hosts both the web and database servers


Can easily handle peaks of (at least) 700 visitors at a time

I
I

Chordifying new songs takes some computing power, but most songs
are in the database already

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

37 / 46

How do we handle these visitors?

Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB hard
drive

Single server hosts both the web and database servers


Can easily handle peaks of (at least) 700 visitors at a time

I
I

Chordifying new songs takes some computing power, but most songs
are in the database already

Queueing system for busy periods

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

37 / 46

How do we handle these visitors?

Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB hard
drive

Single server hosts both the web and database servers


Can easily handle peaks of (at least) 700 visitors at a time

I
I

Chordifying new songs takes some computing power, but most songs
are in the database already

Queueing system for busy periods

Infrastructure costs are minimal

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

37 / 46

Frontend (PHP/JS) and backend (Haskell) interaction

Frontend receives a music file, calls backend with it

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

38 / 46

Frontend (PHP/JS) and backend (Haskell) interaction

I
I

Frontend receives a music file, calls backend with it


Backend computes the chords, writes them to a file:

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

38 / 46

Frontend (PHP/JS) and backend (Haskell) interaction

I
I

Frontend receives a music file, calls backend with it


Backend computes the chords, writes them to a file:
I

Jos
e Pedro Magalh
aes

1;D:min;0.232199546;0.615328798
2;D:min;0.615328798;0.998458049
...

Advanced Functional Programming in Industry, FP Days 2014

38 / 46

Frontend (PHP/JS) and backend (Haskell) interaction

I
I

Frontend receives a music file, calls backend with it


Backend computes the chords, writes them to a file:
I

1;D:min;0.232199546;0.615328798
2;D:min;0.615328798;0.998458049
...

Frontend reads this file, updates the database if necessary, and


renders the result

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

38 / 46

Frontend (PHP/JS) and backend (Haskell) interaction

I
I

Frontend receives a music file, calls backend with it


Backend computes the chords, writes them to a file:
I

1;D:min;0.232199546;0.615328798
2;D:min;0.615328798;0.998458049
...

Frontend reads this file, updates the database if necessary, and


renders the result

Backend is open-source (and GPL3); only option is to run it as a


standalone executable

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

38 / 46

The importance of the UI

Lets have a look at four different online services giving you the chords
for a song (Radioheads Karma Police).

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

39 / 46

The importance of the UIChordie

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

40 / 46

The importance of the UIRiffstation

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

41 / 46

The importance of the UIYoutab.me

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

42 / 46

The importance of the UIChordify

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

43 / 46

Logistics of an internet start-up

Chordify is created and funded by 5 people

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

44 / 46

Logistics of an internet start-up

Chordify is created and funded by 5 people

If you can do without venture capital, do it!

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

44 / 46

Logistics of an internet start-up

Chordify is created and funded by 5 people

If you can do without venture capital, do it!


You might end up doing more than just functional programming,
though:

I
I

I
I

Jos
e Pedro Magalh
aes

Deciding on what features to implement next


Recruiting, interviewing, dealing with legal issues related to
employment
Taxation (complicated by the fact that we sell worldwide and support
multiple currencies)
User support
Outreach (pitching events, media, this talk, etc.)

Advanced Functional Programming in Industry, FP Days 2014

44 / 46

Logistics of an internet start-up

Chordify is created and funded by 5 people

If you can do without venture capital, do it!


You might end up doing more than just functional programming,
though:

I
I

I
I

Deciding on what features to implement next


Recruiting, interviewing, dealing with legal issues related to
employment
Taxation (complicated by the fact that we sell worldwide and support
multiple currencies)
User support
Outreach (pitching events, media, this talk, etc.)

But its fun, and you learn a lot!

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

44 / 46

Summary

Musical modelling with Haskell:


I

A model for musical harmony as a Haskell datatype

Makes use of several advanced functional programming techniques,


such as generic programming, GADTs, and type families

When chords do not fit the model: error correction

Harmonising melodies

Generating harmonies

Recognising harmony from audio sources

Transporting academic research into industry

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

45 / 46

Play with it!

http://chordify.net
http://hackage.haskell.org/package/HarmTrace
http://hackage.haskell.org/package/FComp

Jos
e Pedro Magalh
aes

Advanced Functional Programming in Industry, FP Days 2014

46 / 46

You might also like