My favorite explanation of the Y-combinator is the one I did in
JavaScript. See
http://www.mail-archive.com/bost...@mail.pm.org/msg02716.html for
details.
> It's more about CS theory and torturing your language's type system
> than having any practical value,
> but still, it would be interesting to see if one can implement Y
> combinator in Go.
I started this post planning to say, "Of course you can, here is how
you do it." I quickly moved to saying, "The type system causes
serious pain but here is how to do it." And then I wound up at, "You
can't do it."
If I'm right that you can't do it, then I learned something and I'm
quite surprised. I thought that anonymous functions and closures is
enough to do the Y-combinator and apparently it isn't.
The problem is that the Y-combinator requires you to have a function
that can accept itself as an argument. But what type will that
function have? The type signature has to include itself in the type
signature, but there is no way that I know of to define a recursive
type.
Illustrating it with a simpler case, one of the intermediate forms
that I showed on the way to the Y-combinator is
// No assignment this time.
function (builder, n) {
return builder(builder, n);
}(
function (recurse, n) {
if (0 == n)
return 1;
else
return n * recurse(recurse, n - 1);
},
5
);
Let's focus on this piece of the JavaScript:
function (recurse, n) {
if (0 == n)
return 1;
else
return n * recurse(recurse, n - 1);
}
Now try to write it in Go:
func (recurse ..., n int) int {
if 0 == n {
return 1;
}
else {
return recurse(recurse, n - 1);
}
}
But here is the challenge. The ... bit has to wind up being the type
signature for the overall function! So if we expand that type
definition we get
func (recurse ..., n int) int
func (recurse func (..., int) int, n int) int
func (recurse func (func (..., int) int, int) int, n int) int
.
.
.
and we can never write out the recursive type definition.
There may be a way around this with the reflect package. But even if
there is the pain of putting types on higher order functions is enough
that I don't expect those techniques to ever be popular in Go.
Cheers,
Ben