Created
November 22, 2013 00:28
-
-
Save syntacticsugar/7592537 to your computer and use it in GitHub Desktop.
"Let there be light." Thus spoke Alonzothrustra.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# proccc | |
def one proccc, x | |
proccc.(x) | |
end | |
def two proccc, x | |
proccc.(proccc.(x)) | |
end | |
def three proccc,x | |
proccc[proccc[proccc[x]]] | |
end | |
def zero proccc, x | |
x | |
end | |
ZERO = ->(p) { ->(x) { x }} | |
ONE = ->(p) { ->(x) { p[x] }} | |
TWO = ->(p) { ->(x) { p[p[x]] }} | |
THREE = ->(p) { ->(x) { p[p[p[x]]] }} | |
FOUR = ->(p) { ->(x) { p[p[p[p[x]]]] }} | |
def to_integer proccc | |
proccc[->(n) { n + 1 }][0] | |
end | |
TRUE = ->(x) { ->(y) { x } } | |
FALSE = ->(x) { ->(y) { y } } | |
def to_boolean proccc | |
proccc[true][false] | |
end | |
def ifff proccc,x,y | |
proccc[x][y] | |
end | |
# now, as a sexy proccc!!!!!1 :P :P | |
IF = | |
->(proccc) { | |
->(x) { | |
->(y) { | |
proccc[x][y] | |
} | |
} | |
} | |
# >> IF[TRUE][:foo][:bar] | |
# => :foo | |
# if we call an unknown number with TRUE as its second argument, | |
# it’ll return TRUE immediately if the number is ZERO. | |
# | |
# If it’s not ZERO then it’ll return whatever calling "p" returns, | |
# so if we make "p" a proc which always returns FALSE, we’ll get the behaviour we want: | |
def zzzero? proccc | |
proc[ ->(x) { FALSE }][TRUE] | |
end | |
# Here's the basic idea behind decrementing a Church numeral. In lambda calculus, | |
# all you can do with a function is call it -- just like in pure object-oriented | |
# programming, all you can do with an object is send it a message. | |
# So to decrement a numeral, you have to call it with something. | |
# The numeral takes an 'f' and and 'x' and calls 'f' n times, starting with 'x'. | |
# | |
# The strategy that worked out was to make 'x' a pair like (true, 0), make 'f' a function | |
# that takes a pair like (initial?, count) and returns (false, (0 if initial? else count+1)). | |
# Then when we have a final result (initial?, count), just return the count. | |
# Rerepresent that in lambda calculus and simplify it, and you end up with something incomprehensible | |
# when written out in detail, just like DECREMENT. | |
# | |
# so the step go like 0: (true, 0), 1: (false, 0), 2: (false, 1), 3: (false, 2), ... | |
DECREMENT = -> n { -> f { -> x { n[-> g { -> h { h[g[f]] } }] | |
[-> y { x }][-> y { y }] } } | |
INCREMENT = ->(n) { ->(p) { ->(x) { p[n[p][x]] } } } | |
ADD = ->(m) { ->(n) { n[INCREMENT][m] } } | |
MULTIPLY = ->(m) { ->(n) { n[ADD[m]][ZERO] } } | |
POWER = ->(m) { ->(n) { n[MULTIPLY[m]][ONE] } } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment