I apologize in advance for asking this question again. I asked this question previously with respect to a Haskell implementation here, but I'm still having difficulty wrapping my head around how this works. Also, I find the concept of a minimalistic programming language absolutely fascinating and can't get away from it... anyways, this is no place to be nostalgic about the beauty of functional programming.
So! I found a website about esoteric programming languages and discovered Iota. Iota is arguably the smallest functional language. You can read more about it here: "Iota and Jot: the simplest languages?" Here is the reference implementation of Iota in Scheme:
(let iota ()
(if (eq? #\* (read-char)) ((iota)(iota))
(lambda (c) ((c (lambda (x) (lambda (y) (lambda (z) ((x z)(y z))))))
(lambda (x) (lambda (y) x))))))
But, when I try something equivalent in elegance to the Scheme implementation in Ruby it ends up spitting out a "bad proc". Can anyone help me understand why Ruby is behaving this way and how this can be implemented better. While trying to get this to work, I kept S
, K
, and BASIS
separate just for readability.
I included two tests at the bottom. The first should return I
(BASIS[BASIS]
), but instead it returns a proc that doesn't produce the same result as I
. The second test should return K
, but instead it returns an error.
S = lambda {|f| lambda {|g| lambda {|x| f[x][g[x]] }}}
K = lambda {|x| lambda {|y| x }}
BASIS = lambda {|c| c[S][K] }
iota = lambda{|s|
s = s.chars
i = lambda {
if s.next == '*'
i[i]
else
BASIS
end
}
}
p BASIS[BASIS][1] # => 1
p iota["*ii"][1] # => #<Proc:0x000000010016b290>
p K[1][2] # => 1
p iota["*i*i*ii"][1][2] # => line 3:in `[]': can't convert Proc into Integer (TypeError)