// the fixed-point combinator
func fix<T>(_ f: @escaping ((@escaping (T) -> T) -> (T) -> T)) -> (T) -> T {
return { (x: T) in (f(fix(f)))(x) }
}
// demo
let fact = fix { fact_ in { n in n == 1 ? 1 : n * fact_(n-1) } }
for i in 1..<10 {
print(fact(i))
}
that would be a serious crime against humanity if swift allows this type of code at all
the fixed-point combinator and Y combinator are pretty important in functional languages. And the above code works in Swift. The good thing is that you need to write `fix` only once and you can then use it for all closures that need to be recursive.
// the fixed-point combinator
func fix<T>(_ f: @escaping ((@escaping (T) -> T) -> (T) -> T)) -> (T) -> T {
return { (x: T) in (f(fix(f)))(x) }
}
// demo
let fact = fix { fact_ in { n in n == 1 ? 1 : n * fact_(n-1) } }
for i in 1..<10 {
print(fact(i))
}
that would be a serious crime against humanity if swift allows this type of code at all
the fixed-point combinator and Y combinator are pretty important in functional languages.
They're important in the theory of functional languages. Anyone seriously promoting using the Y combinator in actual programming instead of using the language's native recursive-binding features is, frankly, someone you should not being taking advice from.
And the above code works in Swift. The good thing is that you need to write `fix` only once and you can then use it for all closures that need to be recursive.
// the fixed-point combinator
func fix<T>(_ f: @escaping ((@escaping (T) -> T) -> (T) -> T)) -> (T) -> T {
return { (x: T) in (f(fix(f)))(x) }
}
// demo
let fact = fix { fact_ in { n in n == 1 ? 1 : n * fact_(n-1) } }
for i in 1..<10 {
print(fact(i))
}
that would be a serious crime against humanity if swift allows this type of code at all
the fixed-point combinator and Y combinator are pretty important in functional languages.
They're important in the theory of functional languages. Anyone seriously promoting using the Y combinator in actual programming instead of using the language's native recursive-binding features is, frankly, someone you should not being taking advice from.
Definitely not arguing with that. But there are (valid?) cases when you want a recursive closure which doesn’t have a native recursion mechanism and then `fix` can be useful I’d argue. I think more straightforward than
recursive.c = { x in
(x == 0) ? 1 : x * recursive.c(x - 1)
}
. But fortunately have local functions, I can only recall wanting a recursive closure once.
And the above code works in Swift. The good thing is that you need to write `fix` only once and you can then use it for all closures that need to be recursive.
following C tradition to have declarations mimicking usage, the
weak/unowned specifier shall be on the left to the name, as the "self"
itself is on the left: self.foo
maybe a too wild idea, but how about this:
weak func foo() {
...
}
as a special case of "weak self" specifier. instead of:
func foo() { [weak self] in
...
}
of course it doesn't address everything that can be achieved by general
capture list specifiers.
Definitely not arguing with that. But there are (valid?) cases when you
want a recursive closure which doesn’t have a native recursion mechanism
and then `fix` can be useful I’d argue. I think more straightforward than
recursive.c = { x in
(x == 0) ? 1 : x * recursive.c(x - 1)
}
you can do without "recursive.c":
var factorial: ((Int) -> Int)!
factorial = { n in
n == 0 ? 1 : n * factorial(n - 1)
}
factorial(5) // 120
. But fortunately have local functions, I can only recall wanting a
recursive closure once.
in down to earth practical programming even if i didn't have local
functions i probably wouldn't bother abusing closures to implement
recursion, would just used what's available: methods. and if there is some
extra state to pass from the outer scopes, well, so be it, either via
parameters of via some instance variables, etc. wasn't too much of a
problem in good old C/C++. in a way, knowing exact state you want to pass
and passing it explicitly organises the code and the reasoning about it.
Definitely not arguing with that. But there are (valid?) cases when you want a recursive closure which doesn’t have a native recursion mechanism and then `fix` can be useful I’d argue. I think more straightforward than
recursive.c = { x in
(x == 0) ? 1 : x * recursive.c(x - 1)
}
you can do without "recursive.c":
var factorial: ((Int) -> Int)!
factorial = { n in
n == 0 ? 1 : n * factorial(n - 1)
}
. But fortunately have local functions, I can only recall wanting a recursive closure once.
in down to earth practical programming even if i didn't have local functions i probably wouldn't bother abusing closures to implement recursion, would just used what's available: methods. and if there is some extra state to pass from the outer scopes, well, so be it, either via parameters of via some instance variables, etc. wasn't too much of a problem in good old C/C++. in a way, knowing exact state you want to pass and passing it explicitly organises the code and the reasoning about it.