# lambda calculus beep boop

recursion: https://beep-boop-bap.glitch.me/

# soundtest

Sounds.playStuff([{ beops: "beep beep boop boop pling bap".split(" ")}])

# commands for slides

 Exp u ::= x variable λx.u abstraction u1 u2 application
this is mostly about syntax really
also it's like stupid I guess

# semantics though

replace references to parameter with argument

(λa.λb.λc.c a b) foo bar quux
(λb.λc.c foo b) bar quux
(λc.c foo bar) quux
quux foo bar

this slide is wide :)

(λa.λb.λc.c a b) foo bar quux
(λb.λc.c foo b) bar quux
(λc.c foo bar) quux
quux foo bar

# some lambdas

0 is λf.λx.x
1 is λf.λx.f x
2 is λf.λx.f (f x)
3 is λf.λx.f (f (f x))
5 is λf.λx.f (f (f (f (f x))))
and so on

# some lambdas

+ is λa.λb.λf.λx.a f (b f x)
(f applied a times to f applied b times to x)

* is λa.λb.λf.λx.a (b f) x
(f applied b times a times to x)

# can try

• possibly shoutability concerns
• variables can be named almost anything
• is the untyped lambda calculus sound?
• has greek letters in it (hci?)
• parentheses)))
• variable capture thing

λy.(λx.λy.x) y

λy.(λx.λy.x) y

λy.λy.y

oh no

# variable capture thing

λy.(λx.λy.x) y

rename inner y before reducing

# de bruijn index

 Exp u ::= n variable λu abstraction u1 u2 application

λz.(λy.y (λx. x)) (λx.z x)

# some lambdas

0 is λλ1
1 is λλ2 1
2 is λλ2 (2 1)
3 is λλ2 (2 (2 1))
5 is λλ2 (2 (2 (2 (2 1))))
and so on

# some lambdas

+ is λλλλ4 2 (3 2 1)
(um)

* is λλλλ4 (3 2) 1
(uh)

# some lambdas

+ is λa.λb.λf.λx.a f (b f x)
(f applied a times to f applied b times to x)

* is λa.λb.λf.λx.a (b f) x
(f applied b times a times to x)

λa.λb.λf.λx.a f (b f x)
λa.λb.λf.λx.a f (b f x)

# 2 + 3

(λλλλ4 2 (3 2 1)) (λλ2 (2 1)) (λλ2 (2 (2 1)))
(λλλ(λλ2 (2 1)) 2 (3 2 1)) (λλ2 (2 (2 1)))
λλ(λλ2 (2 1)) 2 ((λλ2 (2 (2 1))) 2 1)
λλ(λ3 (3 1)) ((λλ2 (2 (2 1))) 2 1)
λλ2 (2 ((λλ2 (2 (2 1))) 2 1))
λλ2 (2 ((λ3 (3 (3 1))) 1))
λλ2 (2 (2 (2 (2 1))))

# 2 * 3

(λλλλ4 (3 2) 1) (λλ2 (2 1)) (λλ2 (2 (2 1)))
(λλλ(λλ2 (2 1)) (3 2) 1) (λλ2 (2 (2 1)))
λλ(λλ2 (2 1)) ((λλ2 (2 (2 1))) 2) 1
λλ(λ(λλ2 (2 (2 1))) 3 ((λλ2 (2 (2 1))) 3 1)) 1
λλ(λλ2 (2 (2 1))) 2 ((λλ2 (2 (2 1))) 2 1)
λλ(λ3 (3 (3 1))) ((λλ2 (2 (2 1))) 2 1)
λλ2 (2 (2 ((λλ2 (2 (2 1))) 2 1)))
λλ2 (2 (2 ((λ3 (3 (3 1))) 1)))
λλ2 (2 (2 (2 (2 (2 1)))))

λy.(λx.λy.x) y

λ(λλ2) 1

# variable capture thing

λ(λλ2) 1

λλ2

λy.(λx.λy.x) y
λy2.(λx.λy.x) y2
λy2.λy.y2
λy2.(λx.λy.x) y2
λy2.λy.y2
λy2.(λx.λy.x (λy.x)) y2
λy2.λy.y2 (λy.y2)

# anyway

• arithmetic instead of variable capture
• subtract 1 from free variables in the function
• number of parameter-variable in function increases with depth in syntax tree
• add depth to free variables in argument when replacing
• fewer possible variable names
• still uses greek letters
• also still parentheses
• maths

# beep boop

 Exp u ::= boop b variable beep u abstraction pling u1 u2 application

 Boops b ::= bap bap boop b boop

nice

λx.x
λx.x

# some beep boops

0 is beep beep boop bap
1 is beep beep pling boop boop bap boop bap
2 is beep beep pling boop boop bap pling boop boop bap boop bap
3 is beep beep pling boop boop bap pling boop boop bap pling boop boop bap boop bap
5 is beep beep pling boop boop bap pling boop boop bap pling boop boop bap pling boop boop bap pling boop boop bap boop bap
and so on

# some beep boops

+ is beep beep beep beep pling pling boop boop boop boop bap boop boop bap pling pling boop boop boop bap boop boop bap boop bap
* is beep beep beep beep pling pling boop boop boop boop bap pling boop boop boop bap boop boop bap boop bap

# 2 + 3

pling pling beep beep beep beep pling pling boop boop boop boop bap boop boop bap pling pling boop boop boop bap boop boop bap boop bap beep beep pling boop boop bap pling boop boop bap boop bap beep beep pling boop boop bap pling boop boop bap pling boop boop bap boop bap

we can try

for keyboard: a = beep, s = boop d = bap, f = pling, backspace = undo, space = "next"

with tree

lambdatree!

more lambdaer

# also actual sounds

• no parentheses
• a small set of not very difficult words
• solves hci issues by being intuitive for both humans and computers

# cannot syntax error

so uh what else?

I mean, there's fish?

Einar always has some fish

Svg.create( 600, 600, Mirror.mirrorShapes( 600, Picture.squareLimitColor( 4, Magic.createPicture(Fish.fancy())) (Lens.create( Box.create( Vector.create(100, 100), Vector.create(400, 0), Vector.create(0, 400)), Hue.create("black")))).map(r => r.shape.toSvgElement(r.style)))

# some other picture combinator thing

maybe more legible

# can make it sound different

const supersaw = (freq, vol, sawNumber, detune) => { let g = Sounds.audioContext().createGain(); g.gain.setValueAtTime(0, Sounds.audioContext().currentTime); for (let i = 0; i < sawNumber; i++) { let saw = Sounds.audioContext().createOscillator(); saw.type = 'sawtooth'; saw.frequency.setValueAtTime(freq, Sounds.audioContext().currentTime); saw.detune.value = -detune + i * 2 * (detune / (sawNumber - 1)); saw.start(); saw.connect(g); } let dur = 0; for (let i = 0; i < vol.length; i++) { dur = dur + vol[i].time; } dur = dur * 0.5; g.connect(Sounds.audioContext().destination); return Sounds.note(dur, [{ dial: g.gain, vts: vol }]); } const sawVol = [ { val: 0.13, time: 0.1 }, { val: 0.1, time: 0.2 }, { val: 0.1, time: 0.5 }, { val: 0, time: 0.3 }]; const saw = (freq) => supersaw(freq, sawVol, 7, 10); Sounds.setNotes(new Map( [ ["beep", saw(440)], ["boop", saw(493.88)], ["bap", saw(523.25)], ["pling", saw(587.33)], ["undo", saw(800)], ["next", saw(250)] ]));

(supersaw stolen from @mollerse. code.)

# forever

omega!

const f = (x) => [{ val: x * 1.2, time: 0.7 }, { val: x, time: 0.3 }]; const vol = [ { val: 0.13, time: 0.1 }, { val: 0.1, time: 0.2 }, { val: 0.1, time: 0.5 }, { val: 0, time: 0.3 } ]; const newNotes = new Map([ ["beep", Sounds.makeNote(f(400), vol)], ["boop", Sounds.makeNote(f(460), vol)], ["bap", Sounds.makeNote(f(515), vol)], ["pling", Sounds.makeNote(f(550), vol)], ["undo", Sounds.makeNote(f(800), vol)], ["next", Sounds.makeNote(f(250), vol)] ]); Sounds.setNotes(newNotes);

# conclusion

• you totally can use numbers instead of variable names
• if you use a symbol for function application you can drop the parentheses
• it's like reverse reverse polish notation
• I mean polish notation
• do you just call it notation here?
• and I mean why would/wouldn't you do none/some/all of those things?
• for some things, numbers and that is a good starting point