Birb is an advanced programming language that only consists of bird emojis 🐣. Each emoji gets substituted by a combinator bird of pure lambda calculus.
Unfortunately, the Unicode standard does not yet have many (single-character) birds. These are the ones currently mapped/supported:
emoji | animal | combinator | term |
---|---|---|---|
🦉 | owl | owl | |
🦅 | eagle | eagle | |
🪽 | wing | phoenix | |
🕊️ | dove | dove | |
🦜 | parrot | mockingbird | |
🦆 | duck | quacky | |
🐤 | touring chick | turing | |
🐥 | kool chick | kestrel | |
🐣 | hatching chick | quirky | |
🐦 | simple bird | identity | |
🦚 | peacock | queer | |
🦤 | dodo | sage | |
🐧 | penguin | blackbird | |
🦢 | swan | substitution | |
🦩 | flamingo | cardinal |
Lonely/unmatched birbs: 🐔🦃🐓🪿
[birb]+
: Birb- everything else: Comment
Syntax errors are impossible as long as you use at least one birb.
Birbs stagger as they walk: they are reduced in alternating associative
order, starting with left associativity at birb index
🐦🐦 -> (🐦🐦)
🐦🐦🐦 -> ((🐦🐦)🐦)
🐦🐦🐦🐦 -> (🐦((🐦🐦)🐦))
🐦🐦🐦🐦🐦 -> ((🐦((🐦🐦)🐦))🐦)
🐦🐦🐦🐦🐦🐦 -> (🐦((🐦((🐦🐦)🐦))🐦))
🐦🐦🐦🐦🐦🐦🐦 -> ((🐦((🐦((🐦🐦)🐦))🐦))🐦)
...
You can find more examples (with comments) in the samples/
directory.
- 🪽🐦
$\rightsquigarrow$ 🦢 - 🦢🐦
$\rightsquigarrow$ 🦉 - 🦉🐦
$\rightsquigarrow$ 🦜 - 🕊️🐦
$\rightsquigarrow$ 🐧 - 🐧🐧
$\rightsquigarrow$ 🕊️ - 🦩🐧
$\rightsquigarrow$ 🦚 - 🦩🦚
$\rightsquigarrow$ 🐧 - 🦩🦆
$\rightsquigarrow$ 🐣
One can only imagine what happens if two parrots talk to each other:
🦜🦜
For this example I use the Church numerals. Zero would then be encoded as 🐥🐦. The successor function can be written as 🦢🐧:
- 🐦🐧🐦🦢🐧🐥🐦
$\rightsquigarrow\lambda\lambda(10)$ – (Church numeral 1) - 🐦🐧🐦🐧🕊️🦢🐧🦢🐧🐥🐦
$\rightsquigarrow\lambda\lambda(1(10))$ – (Church numeral 2)
Similarly, one can very obviously translate the Church addition function
to 🪽🐧. Now, to calculate
- 🐦🐦🕊️🐧🕊️🐧🐦🐧🕊️🐧🕊️🪽🐧🦢🐧🦢🐧🐥🐦🦢🐧🐥🐦
$\rightsquigarrow\lambda\lambda(1(1(10)))$ – (Church numeral 3)
Also: 🐧 is
Note that there exist many alternative ways to do arithmetic. Try writing the functions above with other birbs!
You can create a pair 🦩🦩🦩YX
.
Typically, one would now construct a list using repeated application of pairs (Boehm-Berarducci/Church encoding). However, due to the reversed application and alternating associativity, the Mogensen-Scott encoding is more suitable:
List [🦩]ⁿ🦩X2X1...XN
.
See this excellent codegolf stackexchange answer.
Contestants:
-
The touring eagle:
[🐦]ⁿ[🦅🐤]ⁿ
($n=3$ : 9 birbs, ~20M BLC bits) - better? PR!
I created a lambda calculus to Birb transpiler. It works by converting binary lambda calculus to SKI combinators, which then get converted to Jot and back to SKI combinators. The resulting SKI combinators then get converted to Birbs.
The reason I convert to Jot first is that Birbs semantics don’t allow
trivial transpilation from arbitrary SKI expressions. With Jot however,
applications with non-associative expressions like ((s k) (k s))
are
impossible, as only a single non-associative application exists (the
innermost/deepest expression).
With all these conversions, the resulting transpiled Birb code is big, ugly and slow. There should be a way to optimize the transpilation process, but it’s probably a bit more complicated.
Install Haskell’s stack. Then,
-
stack run -- reduce file.birb
orstack run -- reduce <(echo 🐧🐧)
-
stack run -- transpile <(echo 01000110100000011100111001110011100111010)
to generate a birb program that calculates$5^5$ -
stack install
so you can enjoybirb
from anywhere
If the output cannot be translated to birbs, the raw lambda calculus term (with De Bruijn indices) is printed. For the examples above I sometimes manually converted the term back to birbs.
Birb is Turing complete, since one can construct any term of the
Jot variant of Iota. A Jot term
((X s) k)
is equivalent to 🐦🐦X🦢🐥
. Similarly, (s (k X))
is
equivalent to 🐦🦆X🐥🦢
.
The idea of the language was originally proposed in 2021 by @SCKelement on Esolang.