Advertisement
Guest User

Untitled

a guest
Dec 10th, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.92 KB | None | 0 0
  1. Contains paren expressions for several useful functions
  2.  
  3. # Church numerals
  4.  
  5. zero [\f.\x.x]
  6. succ [\n.\f.\x.f (n f x)]
  7.  
  8. one [succ zero]
  9. two [succ one]
  10. three [succ two]
  11. four [succ three]
  12.  
  13. iszero [\n.n (\f.F) T]
  14.  
  15. add [\m.m succ]
  16. mul [\m.\n.\f.m (n f)]
  17. exp [\m.\n.n m]
  18. pred [\n.\f.\x.n (\g.\h.h (g f)) (\a.x) (\b.b)]
  19. sub [\m.\n. n pred m]
  20.  
  21. # Booleans
  22.  
  23. true [\a.\b.a]
  24. false [\a.\b.b]
  25. if [\c.c]
  26.  
  27. # Y Combinator
  28. selfcaller [\gen.gen gen]
  29. improved-gen-maker [\improver.\gen.improver (gen gen)]
  30. y [\improver.selfcaller (improved-gen-maker improver)]
  31. y [\improver.(\gen.gen gen) (\gen.improver (gen gen))]
  32. y [\improver.(\gen.improver (gen gen)) (\gen.improver (gen gen))]
  33.  
  34. # Cons-Lists
  35.  
  36. cons-c [\1.\2.\getter.getter \1 \2]
  37. left-c-g [\1.\2.\1]
  38. right-c-g [\1.\2.\2]
  39. left-c [\l.l left-g]
  40. right-c [\l.l right-g]
  41.  
  42. # Lists (paren style)
  43.  
  44. cons [\isempty.\first.\rest.\getter.getter isempty first rest]
  45. empty [cons true zero zero]
  46. isempty-g [\isempty.\first.\rest.isempty]
  47. first-g [\isempty.\first.\rest.first]
  48. rest-g [\isempty.\first.\rest.rest]
  49. isempty [\l.l isempty-g]
  50. first [\l.l left-g]
  51. rest [\l.l rest-g]
  52.  
  53. push [\l.\x.cons false x l]
  54.  
  55. # f takes two arguments, an item of the list, and its previous state.
  56. fold [\l.\f.]
  57.  
  58. zero( (((lam))) arg1(() ()) ( (((lam))) arg2(() (())) result arg2(() (())) ) zero)
  59. succ( (((lam))) arg1(() ()) ( (((lam))) arg2(() (())) ( (((lam))) arg3(() ((()))) result( arg2(() (())) nfx( arg1(() ()) arg2(() (())) arg3(() ((()))) nfx) result)))succ)
  60.  
  61. one( (((lam))) arg1(() ()) ( (((lam))) arg2(() (())) result( arg1(() ()) arg2(() (())) result) ) one)
  62.  
  63.  
  64. ====
  65.  
  66. notes on the y combinator
  67. -------------------------
  68.  
  69. selfcaller [\gen.gen gen]
  70. improved-gen-maker [\improver.\gen.improver (gen gen)]
  71. y [\improver.selfcaller (improved-gen-maker improver)]
  72. y [\improver.(\gen.gen gen) (\gen.improver (gen gen))]
  73. y [\improver.(\gen.improver (gen gen)) (\gen.improver (gen gen))]
  74.  
  75. First, we introduce a core concept that I'm going to call a `gen`.
  76.  
  77. A gen is a function that accepts a function of a `similar` type, and is
  78. able to perform some sort of recursion on that function. Below is an example of
  79. a gen.
  80.  
  81. (selfcaller gen) == (gen gen)
  82.  
  83. The simplest gen is the selfcaller. It calls the function provided with the
  84. function provided. However if you just run the selfcaller with the selfcaller,
  85. you just get infinite selfcalling.
  86.  
  87. (selfcaller selfcaller) == (selfcaller selfcaller) == ...
  88.  
  89. This is where we want to create a `gen` that somehow "does something" before
  90. doing the selfcalling. In comes improved-gen-maker!
  91.  
  92. (improved-gen-maker improver) --> improved-gen
  93. (improved-gen gen) == (improver (gen gen)) == (improver (selfcaller gen))
  94.  
  95. The improved-gen-maker makes an improved-gen, by accepting a function that
  96. improves a function similar to itself. The improved-gen then accepts a gen
  97. function, uses the improver function by calling it on the selfcaller in its
  98. core.
  99.  
  100. Here's an example of an improver, the factorial function.
  101.  
  102. (fact-improver lesser-fact n) == if n == 0 then 1 else n * lesser-fact n-1))
  103.  
  104. Here, we see that if fact-improver is given a lesser-fact which is capable of
  105. doing what fact-improver does, just only being able to do it up to n-1, then
  106. fact-improver improves on that by allowing you to call it on n. Thus fact-
  107. improver 'improves' lesser-fact by one step.
  108.  
  109. We can see this in action, but first, we define a function that just errors so
  110. we can see what a function that can't do anything (is completely un-improved)
  111. looks like:
  112.  
  113. (badfact lesser-fact n) == 0
  114.  
  115. We expect fact-improver to always return 1 or greater! So if we ever get
  116. badfact, we end up multiplying the result by 0 and getting... 0. That way we'll
  117. know something went wrong. Let's try improving badfact to get a factorial
  118. function that works on n=0.
  119.  
  120. factorial0 = (fact-improver badfact) == \n.(if n == 0 then 1 else n * (badfact n-1))
  121.  
  122. Let's try running it.
  123.  
  124. (factorial0 0) == (if 0 == 0 then 1 else 0 * (badfact 0-1))
  125. == 1
  126.  
  127. What if we try some other number?
  128.  
  129. (factorial0 1) == (if 1 == 0 then 1 else 1 * (badfact 1-1))
  130. == 1 * (badfact 1-1)
  131. == 1 * 0
  132. == 0
  133.  
  134. Woops! We wound up calling badfact and that caused our whole expression to
  135. become 0. What if we improve it again?
  136.  
  137. factorial1 = (fact-improver factorial0) == \n.(if n == 0 then 1 else n * (factorial0 n-1))
  138.  
  139. Now we can use factorial1 on 0 and 1, but not 2.
  140.  
  141. (factorial1 0) == (if 0 == 0 then 1 else 0 * (factorial0 0-1)) == 1
  142. (factorial1 1) == (if 1 == 0 then 1 else 1 * (factorial0 1-1)) == 1 * (factorial0 0) == 1
  143. (factorial1 2) == (if 2 == 0 then 1 else 2 * (factorial0 2-1)) == 2 * (factorial0 1) == 2 * 0 == 0
  144.  
  145. We can simply call fact-improver on factorialn forever to keep improving it.
  146. Eventually we should get the actual factorial function!
  147.  
  148. Now what happens if we pass improved-gen into the selfcaller?
  149.  
  150. (selfcaller (improved-gen-maker improver))
  151. == original-expression # This is the original expression, using parts we know of above
  152. # This expression's purpose is to evaluate improver and return its result.
  153. # However it must also call improver on its result... (recursion)
  154. == (selfcaller improved-gen) # Make the gen
  155. == (improved-gen improved-gen) # Selfcall it
  156. == ((\gen.improver (gen gen)) improved-gen) # Replace the first improved-gen abbreviation with its full name.
  157. # Note that improver corresponds to the function we passed into the maker
  158. == (improver (selfcaller improved-gen)) # Pass improved-gen into the improved-gen...
  159. == result-of-improver # Clearly, we just called improver, so this is its result.
  160. # Therefore, original-expression == result-of-improver
  161. == (improver original-expression) #
  162. == (improver result-of-improver) # We have just managed to pass improver a copy of its result!
  163.  
  164. With all this, we can write the y combinator with only selfcaller and improved-gen-maker
  165.  
  166. y [\improver.selfcaller (improved-gen-maker improver)]
  167.  
  168. Un-abbreviating improved-gen-maker we get
  169.  
  170. y [\improver.selfcaller (\gen.improver (gen gen))]
  171.  
  172. Un-abbeviating selfcaller, we get
  173.  
  174. y [\improver.(\gen.gen gen) (\gen.improver (gen gen))]
  175.  
  176. And this is the shortest form without any abbreviations. However, we note that
  177. the selfcaller does in fact do selfcalling. What happens if we try that right
  178. now?
  179.  
  180. y [\improver.(\gen.improver (gen gen)) (\gen.improver (gen gen))]
  181.  
  182. And we get a nice "symmetrical" y combinator, whose core is a function that is
  183. called on an exact copy of itself (really it's nothing special, since we just
  184. ran selfcaller!)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement