Skip to content

Instantly share code, notes, and snippets.

@syntacticsugar
Created November 22, 2013 00:28
Show Gist options
  • Save syntacticsugar/7592537 to your computer and use it in GitHub Desktop.
Save syntacticsugar/7592537 to your computer and use it in GitHub Desktop.
"Let there be light." Thus spoke Alonzothrustra.
# 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