A lot of effort went into this post but the author didnt do enough preliminary explanation. I have some limited background in logic / FP but wasn't able to follow along.
Can someone explain the notation? Might be difficult without images
Combinatory logic, underneath being lambda calculus.
For a simple explanation: think of `SKI` etc. as functions or transformations which do what is described, how they are described mathematically is discussed later. They act on all values, including each other. For this reason, they are called combinators, as combining them can give rise to any computation. Why that is is also discussed a bit later. Combinatoric application is left-associative, meaning that `SK` is equivalent to `S(K)` in more conventional mathematical notation.
For an easy example, think about the equivalence of the W-combinator and the expression SS(SK). If we apply some abstract values, say a, b, and c to these, we can make sure that the result is `a b b c`, keeping in mind that other combinators are a valid value for a combinator to take in:
SS(SK) abc
→ S a (SK a) bc
→ a b (SK a b) c
→ a b (K b (a b)) c
→ a b (b) c = a b b c
Now if you want to read the definitions, you will need lambda calculus. It is basically an endless combination of two operations, one which is used to build and expression and one which is used to resolve it.
The most important is abstraction, which isn't explained in the post. You write a lambda (λ), the name of a bound variable (say, x), and then a full stop and the "body" of the abstraction. This can be thought of as a mathematical function definition, so that you can think of `f(x) = x` and `f := λx.x` as identical. Note, however, that the latter is anonymous and has to be assigned a name separately.
The second operation is application. This is left-associative, and we do not use parenthesis. `f x` is the same as `f(x)` in conventional notation. `(λx.x) y)` is then the application of `y` to `λx.x`. We replace the bound variable in the expression with the applied value: `(λx.x) y → y`.
We can create more complex multi-variable functions by nesting these:
(λx.(λy.x)) 0 1
→ (λy.0) 1
→ 0
The parentheses are redundant: `λx.λy.x`, and for notational sugar we contract the definition: `λxy.x`.
Armed with all of this, we can read the definitions of the "birds", or combinators:
S := λxyz.x z (y z)
K := λxyz.x z
I := λx.x
Now it's possible to read the previously nonsensical notation in the article, both intuitively and by thinking open the relationships promised:
W := SS(SK)
→ (λxyz.x z (y z)) S (SK)
→ λz.S z (SK z)
→ λz.(λxyz₂.x z₂ (y z₂)) z (SK z)
→ λzz₂.z z₂ (SK z z₂)
→ λzz₂.z z₂ ((λxyz₃.x z₃ (y z₃)) K z z₂)
→ λzz₂.z z₂ (K z₂ (z z₂)
→ λzz₂.z z₂ ((λxy.x) z₂ (z z₂))
→ λzz₂.z z₂ z₂
Now we can perform some tactical renaming (called α-conversion, we used this to avoid name collisions before):
W := λxy.x y y
This is the official definition of the W-combinator and nearly the definition given to us, that being `W := λxyz.x y y z`. However, we can see that in application there is no difference:
(λxy.x y y) a b c = (λxyz.x y y z) a b c
→ (a b b) c = a b b c
→ a b b c = a b b c
Hence, we consider these equivalent through something called η-reduction (`λx.E x = E` if `x` is not free in E). We can see, then, that each three of these systems can create any lambda expression, which are proven to be isomorphic to Turing machines. This is a powerful way to manipulate not only logic, but computation itself.
Not the best explanation, but I feel like introducing lambda calculus is necessary to truly intuitively understand how the operators manipulate each other.
OFF: I am so annoyed of some people spending hours of writing an answer that is not searchable, and will not be useful for anyone but one person (but could be useful for dozens of people if they could find it).
Can't you e.g. open a stackoverflow question with parents question, and answer it, then link it here?
Or any other method to make this answer to be available for the people that may need it in the future?
I don't really think it's a good enough answer to count for that. There are plenty of good answers for this already out there, I just happened to write out a more mediocre one as I'd have no clue of what to search for. The article sure doesn't make it easy to recognize this as combinatory logic nor the fact that this is common notation for combinatory logic.
Can someone explain the notation? Might be difficult without images