Hi all! I decided to play around with SKI combinators today, defined thusly: (define s
(curry (lambda (f g x)
(f x (g x)))))
(define k
(curry (lambda (x y)
x)))
(define i
(lambda (x) x))
I came up with this way to “invert” K (const) so as to return the second argument instead of the first: (((k i) x) y)
this worked fine. However, I decided not to test this way of calling it: ((ki) x y)
as I assumed the currying would take care of it. However, after attempting to use it to define regular function application (which was my real intention) in conjunction with the S combinator, it just wouldn’t work: (s (k i) f x)
after trying a few different ways, I was about to give up when I tried it in Haskell and, lo and behold, it worked: Prelude> s f g x = f x (g x)
Prelude> k x y = x
Prelude> i x = x
Prelude> (s (k i) (+ 1) 6)
7
any idea how best to remedy this? I think what’s happening is: (((k i) 4) 5) =>
(((lambda (y) i) 4) 5) => ((k i 4) 5)
(i 5)
works fine, as it’s just applying id to 5. However: ((k i) 4 5) =>
((lambda (y) i) 4 5)
tries to apply that lambda of one argument (returned by (k i)) to two arguments, instead of first applying 4 to it, returning the identity function, and only then applying it to 5. This does actually make sense if you think about it this way, but this wasn’t how I expected it to work when I came up with the solution, and in that sense Haskell just seemed to do “the right thing”. Sorry if this is a bit of a weird question. I’d rather do this sort of stuff in Racket as it’s my preferred language, is all, and it makes things a whole lot less cumbersome if you have that sort of freedom in applying arguments. Cheers :slightly_smiling_face: Edit: other than just being careful with paren placement/argument application, of course!
Also, I imagine you’ve probably already seen this @soegaard2, but regarding self-evaluating-evaluators: λf.(λx.f(xx))(λx.f(xx)))(λem.m(λx.x)(λmn.em(en))(λmv.e(mv)))
I just so happened to come across this one researching those same SKI combinators.
@sydney.lambda basically, you need to decide if you’re passing arguments 1 at a time or multiple at a time
while it’s possible to write a function F such that both ((F x) y) and (F x y) work and do the same thing, I don’t recommend it
Ah, I figured this was a bit of round-peg/square-hole situation, cheers. I guess I should bite the bullet and create a little SKI interpreter/language or something.
The cool thing to do with SKI is to create a compiler from the lambda calculus.