The Y Combinator in Arc and Java
arcfn.com
arcfn.com
So, rather than another "Lisp rocks, Java sucks" post, we get to read a intellectually sound argument. Refreshing.
>>> (lambda n: (lambda f, n: f(f, n))(
... lambda f, n: n*f(f, n-1) if n > 0 else 1,n)
... )(10)
3628800
http://stackoverflow.com/questions/481692/can-a-lambda-funct...public class Z {
public interface Function<In,Out> {
public Out apply(In param);
}
public interface RecFunction<In,Out>
extends Function<Function<In,Out>,Function<In,Out>> {
}
private interface FixBody<In,Out>
extends Function<FixBody<In,Out>,Function<In,Out>> {
}
public static <In,Out> Function<In,Out> fix(final RecFunction<In,Out> r) {
return (new Function<FixBody<In,Out>,Function<In,Out>>() {
public Function<In,Out> apply(FixBody<In,Out> f) {
return f.apply(f);
}
}).apply(new FixBody<In,Out>() {
public Function<In,Out> apply(final FixBody<In,Out> f) {
return r.apply(
new Function<In,Out>() {
public Out apply(In x) {
return f.apply(f).apply(x);
}
});
}
});
}
public static final RecFunction<Integer,Integer> fact =
new RecFunction<Integer,Integer>() {
public Function<Integer,Integer> apply(
final Function<Integer,Integer> self) {
return new Function<Integer,Integer>() {
public Integer apply(Integer n) {
if (n == 0)
return 1;
else
return n * self.apply(n-1);
}
};
}
};
public static void main(String[] args) {
Function<Integer,Integer> factorial = fix(fact);
for (int i = 0; i < 10; i++) {
System.out.println("Factorial " + i + ": " + factorial.apply(i));
}
}
}block(x, if(x == 0, 1, x * call activated call(x - 1)))
[let f nil (= f (_ [f _])) f]
-----------------
(defun Y (r) (funcall #'(lambda (f) (funcall f f)) #'(lambda (f) (funcall r #'(lambda (x) (funcall (funcall f f) x))))))
(defun fact-gen (fact-in) #'(lambda (n) (if (eq n 0) 1 (* n (funcall fact-in (- n 1))))))
(funcall (Y #'fact-gen) 1)
----------------- Any suggestions? Thanks!
And yeah... Lisp-2 is a stupid idea.
As to Lisp-2, dude that's a debate that I don't want to get into. :) I'm just happy I can use any kind of Lisp -- the rest is just details.
Yarek
• there are disadvantages as well as advantages to lisp-1; and
• there is nothing about lisp-2-ness itself that requires the verbosity of (funcall #'…)-ing in Common Lisp:
Firstly, even in Common Lisp, (funcall (lambda …) …) and (funcall 'car list) are valid. (And many implementations allow ((lambda …) …) — though I can't remember whether the standard defines this.)
Secondly, funcall can be renamed something shorter (e.g. fun).
And finally, for those lispers not against a little syntax, a lisp-2 could define some syntax so that one could write, e.g. (#f …) for (funcall f …) and (##f …) for (funcall 'f …).
Then the above code would be:
(defun Y (r)
((lambda (f) (#f f))
(lambda (f)
(#r (lambda (x)
(fun (#f f) x))))))
etc.. (And we can make it even shorter if we call lambda something shorter, e.g. fn.) function Y(X) {
var fn = function(procedure) {
return X(function(arg) {
return procedure(procedure)(arg);
});
};
return fn(fn);
}
Or am I missing something vital here about how it is all working? The shorter version seems clearer to me (not that any of this is clear to me), and functionally equivalent.If you are green, then you should think about effectiveness of your code. I mean, how much watts your code will use. Ideal program should produce result without using of any computation at all. Programs with lazy evaluation is very close to that ideal. Y Combinator is very green in such languages. But Y Combinator in call-by-value languages? Code, which produces code, to run code, which produces new code, to run code, which produces new code, ...? Author want to boil our planet?