Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,4 +1,5 @@
In strict [[wp:Functional programming|functional programming]] and the [[wp:lambda calculus|lambda calculus]], functions (lambda expressions) don't have state and are only allowed to refer to arguments of enclosing functions. This rules out the usual definition of a recursive function wherein a function is associated with the state of a variable and this variable's state is used in the body of the function.
In strict [[wp:Functional programming|functional programming]] and the [[wp:lambda calculus|lambda calculus]], functions (lambda expressions) don't have state and are only allowed to refer to arguments of enclosing functions.
This rules out the usual definition of a recursive function wherein a function is associated with the state of a variable and this variable's state is used in the body of the function.
The [http://mvanier.livejournal.com/2897.html Y combinator] is itself a stateless function that, when applied to another stateless function, returns a recursive version of the function. The Y combinator is the simplest of the class of such functions, called [[wp:Fixed-point combinator|fixed-point combinators]].

View file

@ -7,7 +7,7 @@ struct RecursiveFunc {
};
template <typename A, typename B>
std::function<B(A)> fix (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
RecursiveFunc<std::function<B(A)>> r = {
std::function<std::function<B(A)>(RecursiveFunc<std::function<B(A)>>)>([f](RecursiveFunc<std::function<B(A)>> w) {
return f(std::function<B(A)>([w](A x) {
@ -35,8 +35,8 @@ FuncFunc almost_fib = [](Func f) {
};
int main() {
auto fib = fix(almost_fib);
auto fac = fix(almost_fac);
auto fib = Y(almost_fib);
auto fac = Y(almost_fac);
std::cout << "fib(10) = " << fib(10) << std::endl;
std::cout << "fac(10) = " << fac(10) << std::endl;
return 0;

View file

@ -0,0 +1,6 @@
template <typename A, typename B>
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
return [f](A x) {
return f(Y(f))(x);
};
}

View file

@ -18,8 +18,8 @@
(otherwise (+ (funcall f (- n 1))
(funcall f (- n 2)))))))
? ((mapcar (y #'fac) '(1 2 3 4 5 6 7 8 9 10))
? (mapcar (Y #'fac) '(1 2 3 4 5 6 7 8 9 10))
(1 2 6 24 120 720 5040 40320 362880 3628800))
? (mapcar (y #'fib) '(1 2 3 4 5 6 7 8 9 10))
? (mapcar (Y #'fib) '(1 2 3 4 5 6 7 8 9 10))
(1 1 2 3 5 8 13 21 34 55)

View file

@ -7,13 +7,13 @@ type FuncFunc func(Func) Func
type RecursiveFunc func (RecursiveFunc) Func
func main() {
fac := fix(almost_fac)
fib := fix(almost_fib)
fac := Y(almost_fac)
fib := Y(almost_fib)
fmt.Println("fac(10) = ", fac(10))
fmt.Println("fib(10) = ", fib(10))
}
func fix(f FuncFunc) Func {
func Y(f FuncFunc) Func {
g := func(r RecursiveFunc) Func {
return f(func(x int) int {
return r(r)(x)

View file

@ -0,0 +1,5 @@
func Y(f FuncFunc) Func {
return func(x int) int {
return f(Y(f))(x)
}
}

View file

@ -1,25 +1,25 @@
fix :: (a -> a) -> a
fix f = f (fix f)
fix f = f (fix f) -- _not_ the {fix f = x where x = f x}
fac :: Integer -> Integer
fac' f n | n <= 0 = 1
fac_ f n | n <= 0 = 1
| otherwise = n * f (n-1)
fac = fix fac'
fac = fix fac_ -- fac_ (fac_ . fac_ . fac_ . fac_ . ...)
-- a simple but wasteful exponential time definition:
fib :: Integer -> Integer
fib' f 0 = 0
fib' f 1 = 1
fib' f n = f (n-1) + f (n-2)
fib = fix fib'
fib_ f 0 = 0
fib_ f 1 = 1
fib_ f n = f (n-1) + f (n-2)
fib = fix fib_
-- Or for far more efficiency, compute a lazy infinite list. This is
-- a Y-combinator version of: fibs = 0:1:zipWith (+) fibs (tail fibs)
fibs :: [Integer]
fibs' a = 0:1:(fix zipP a (tail a))
fibs_ a = 0:1:(fix zipP a (tail a))
where
zipP f (x:xs) (y:ys) = x+y : f xs ys
fibs = fix fibs'
fibs = fix fibs_
-- This code shows how the functions can be used:
main = do

View file

@ -1,53 +1,25 @@
interface Function<A, B> {
public B call(A x);
}
public class YCombinator {
interface RecursiveFunc<F> extends Function<RecursiveFunc<F>, F> { }
public static <A,B> Function<A,B> fix(final Function<Function<A,B>, Function<A,B>> f) {
RecursiveFunc<Function<A,B>> r =
new RecursiveFunc<Function<A,B>>() {
public Function<A,B> call(final RecursiveFunc<Function<A,B>> w) {
return f.call(new Function<A,B>() {
public B call(A x) {
return w.call(w).call(x);
}
});
}
};
return r.call(r);
}
public static void main(String[] args) {
Function<Function<Integer,Integer>, Function<Integer,Integer>> almost_fib =
new Function<Function<Integer,Integer>, Function<Integer,Integer>>() {
public Function<Integer,Integer> call(final Function<Integer,Integer> f) {
return new Function<Integer,Integer>() {
public Integer call(Integer n) {
if (n <= 2) return 1;
return f.call(n - 1) + f.call(n - 2);
}
};
}
};
Function<Function<Integer,Integer>, Function<Integer,Integer>> almost_fac =
new Function<Function<Integer,Integer>, Function<Integer,Integer>>() {
public Function<Integer,Integer> call(final Function<Integer,Integer> f) {
return new Function<Integer,Integer>() {
public Integer call(Integer n) {
if (n <= 1) return 1;
return n * f.call(n - 1);
}
};
}
};
Function<Integer,Integer> fib = fix(almost_fib);
Function<Integer,Integer> fac = fix(almost_fac);
System.out.println("fib(10) = " + fib.call(10));
System.out.println("fac(10) = " + fac.call(10));
}
import java.util.function.Function;
public interface YCombinator {
interface RecursiveFunction<F> extends Function<RecursiveFunction<F>, F> { }
public static <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
RecursiveFunction<Function<A,B>> r = w -> f.apply(x -> w.apply(w).apply(x));
return r.apply(r);
}
public static void main(String... arguments) {
Function<Integer,Integer> fib = Y(f -> n ->
(n <= 2)
? 1
: (f.apply(n - 1) + f.apply(n - 2))
);
Function<Integer,Integer> fac = Y(f -> n ->
(n <= 1)
? 1
: (n * f.apply(n - 1));
);
System.out.println("fib(10) = " + fib.apply(10));
System.out.println("fac(10) = " + fac.apply(10));
}
}

View file

@ -1,23 +1,3 @@
import java.util.function.Function;
public class YCombinator {
interface RecursiveFunc<F> extends Function<RecursiveFunc<F>, F> { }
public static <A,B> Function<A,B> fix(Function<Function<A,B>, Function<A,B>> f) {
RecursiveFunc<Function<A,B>> r = w -> f.apply(x -> w.apply(w).apply(x));
return r.apply(r);
public static <A,B> Function<A,B> Y(Function<Function<A,B>, Function<A,B>> f) {
return x -> f.apply(Y(f)).apply(x);
}
public static void main(String[] args) {
Function<Integer,Integer> fib = fix(f -> n -> {
if (n <= 2) return 1;
return f.apply(n - 1) + f.apply(n - 2);
});
Function<Integer,Integer> fac = fix(f -> n -> {
if (n <= 1) return 1;
return n * f.apply(n - 1);
});
System.out.println("fib(10) = " + fib.apply(10));
System.out.println("fac(10) = " + fac.apply(10));
}
}

View file

@ -1,8 +1,53 @@
import java.util.function.Function;
@FunctionalInterface
public interface SelfApplicable<OUTPUT> extends Function<SelfApplicable<OUTPUT>, OUTPUT> {
public default OUTPUT selfApply() {
return apply(this);
}
interface Function<A, B> {
public B call(A x);
}
public class YCombinator {
interface RecursiveFunc<F> extends Function<RecursiveFunc<F>, F> { }
public static <A,B> Function<A,B> fix(final Function<Function<A,B>, Function<A,B>> f) {
RecursiveFunc<Function<A,B>> r =
new RecursiveFunc<Function<A,B>>() {
public Function<A,B> call(final RecursiveFunc<Function<A,B>> w) {
return f.call(new Function<A,B>() {
public B call(A x) {
return w.call(w).call(x);
}
});
}
};
return r.call(r);
}
public static void main(String[] args) {
Function<Function<Integer,Integer>, Function<Integer,Integer>> almost_fib =
new Function<Function<Integer,Integer>, Function<Integer,Integer>>() {
public Function<Integer,Integer> call(final Function<Integer,Integer> f) {
return new Function<Integer,Integer>() {
public Integer call(Integer n) {
if (n <= 2) return 1;
return f.call(n - 1) + f.call(n - 2);
}
};
}
};
Function<Function<Integer,Integer>, Function<Integer,Integer>> almost_fac =
new Function<Function<Integer,Integer>, Function<Integer,Integer>>() {
public Function<Integer,Integer> call(final Function<Integer,Integer> f) {
return new Function<Integer,Integer>() {
public Integer call(Integer n) {
if (n <= 1) return 1;
return n * f.call(n - 1);
}
};
}
};
Function<Integer,Integer> fib = fix(almost_fib);
Function<Integer,Integer> fac = fix(almost_fac);
System.out.println("fib(10) = " + fib.call(10));
System.out.println("fac(10) = " + fac.call(10));
}
}

View file

@ -1,5 +1,8 @@
import java.util.function.Function;
import java.util.function.UnaryOperator;
@FunctionalInterface
public interface FixedPoint<FUNCTION> extends Function<UnaryOperator<FUNCTION>, FUNCTION> {}
public interface SelfApplicable<OUTPUT> extends Function<SelfApplicable<OUTPUT>, OUTPUT> {
public default OUTPUT selfApply() {
return apply(this);
}
}

View file

@ -1,43 +1,5 @@
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.BiFunction;
import java.util.function.UnaryOperator;
@FunctionalInterface
public interface VarargsFunction<INPUTS, OUTPUT> extends Function<INPUTS[], OUTPUT> {
@SuppressWarnings("unchecked")
public OUTPUT apply(INPUTS... inputs);
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> from(Function<INPUTS[], OUTPUT> function) {
return function::apply;
}
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> upgrade(Function<INPUTS, OUTPUT> function) {
return inputs -> function.apply(inputs[0]);
}
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> upgrade(BiFunction<INPUTS, INPUTS, OUTPUT> function) {
return inputs -> function.apply(inputs[0], inputs[1]);
}
@SuppressWarnings("unchecked")
public default <POST_OUTPUT> VarargsFunction<INPUTS, POST_OUTPUT> andThen(
VarargsFunction<OUTPUT, POST_OUTPUT> after) {
return inputs -> after.apply(apply(inputs));
}
@SuppressWarnings("unchecked")
public default Function<INPUTS, OUTPUT> toFunction() {
return input -> apply(input);
}
@SuppressWarnings("unchecked")
public default BiFunction<INPUTS, INPUTS, OUTPUT> toBiFunction() {
return (input, input2) -> apply(input, input2);
}
@SuppressWarnings("unchecked")
public default <PRE_INPUTS> VarargsFunction<PRE_INPUTS, OUTPUT> transformArguments(Function<PRE_INPUTS, INPUTS> transformer) {
return inputs -> apply((INPUTS[]) Arrays.stream(inputs).parallel().map(transformer).toArray());
}
}
public interface FixedPoint<FUNCTION> extends Function<UnaryOperator<FUNCTION>, FUNCTION> {}

View file

@ -1,74 +1,43 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import java.util.function.BiFunction;
@FunctionalInterface
public interface Y<FUNCTION> extends SelfApplicable<FixedPoint<FUNCTION>> {
public static void main(String... arguments) {
BigInteger TWO = BigInteger.ONE.add(BigInteger.ONE);
public interface VarargsFunction<INPUTS, OUTPUT> extends Function<INPUTS[], OUTPUT> {
@SuppressWarnings("unchecked")
public OUTPUT apply(INPUTS... inputs);
Function<Number, Long> toLong = Number::longValue;
Function<Number, BigInteger> toBigInteger = toLong.andThen(BigInteger::valueOf);
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> from(Function<INPUTS[], OUTPUT> function) {
return function::apply;
}
/* Based on https://gist.github.com/aruld/3965968/#comment-604392 */
Y<VarargsFunction<Number, Number>> combinator = y -> f -> x -> f.apply(y.selfApply().apply(f)).apply(x);
FixedPoint<VarargsFunction<Number, Number>> fixedPoint = combinator.selfApply();
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> upgrade(Function<INPUTS, OUTPUT> function) {
return inputs -> function.apply(inputs[0]);
}
VarargsFunction<Number, Number> fibonacci = fixedPoint.apply(
f -> VarargsFunction.upgrade(
toBigInteger.andThen(
n -> (n.compareTo(TWO) <= 0)
? 1
: new BigInteger(f.apply(n.subtract(BigInteger.ONE)).toString())
.add(new BigInteger(f.apply(n.subtract(TWO)).toString()))
)
)
);
public static <INPUTS, OUTPUT> VarargsFunction<INPUTS, OUTPUT> upgrade(BiFunction<INPUTS, INPUTS, OUTPUT> function) {
return inputs -> function.apply(inputs[0], inputs[1]);
}
VarargsFunction<Number, Number> factorial = fixedPoint.apply(
f -> VarargsFunction.upgrade(
toBigInteger.andThen(
n -> (n.compareTo(BigInteger.ONE) <= 0)
? 1
: n.multiply(new BigInteger(f.apply(n.subtract(BigInteger.ONE)).toString()))
)
)
);
@SuppressWarnings("unchecked")
public default <POST_OUTPUT> VarargsFunction<INPUTS, POST_OUTPUT> andThen(
VarargsFunction<OUTPUT, POST_OUTPUT> after) {
return inputs -> after.apply(apply(inputs));
}
VarargsFunction<Number, Number> ackermann = fixedPoint.apply(
f -> VarargsFunction.upgrade(
(BigInteger m, BigInteger n) -> m.equals(BigInteger.ZERO)
? n.add(BigInteger.ONE)
: f.apply(
m.subtract(BigInteger.ONE),
n.equals(BigInteger.ZERO)
? BigInteger.ONE
: f.apply(m, n.subtract(BigInteger.ONE))
)
).transformArguments(toBigInteger)
);
@SuppressWarnings("unchecked")
public default Function<INPUTS, OUTPUT> toFunction() {
return input -> apply(input);
}
Map<String, VarargsFunction<Number, Number>> functions = new HashMap<>();
functions.put("fibonacci", fibonacci);
functions.put("factorial", factorial);
functions.put("ackermann", ackermann);
@SuppressWarnings("unchecked")
public default BiFunction<INPUTS, INPUTS, OUTPUT> toBiFunction() {
return (input, input2) -> apply(input, input2);
}
Map<VarargsFunction<Number, Number>, Number[]> parameters = new HashMap<>();
parameters.put(functions.get("fibonacci"), new Number[]{20});
parameters.put(functions.get("factorial"), new Number[]{10});
parameters.put(functions.get("ackermann"), new Number[]{3, 2});
functions.entrySet().stream().parallel().map(
entry -> entry.getKey()
+ Arrays.toString(parameters.get(entry.getValue()))
+ " = "
+ entry.getValue().apply(parameters.get(entry.getValue()))
).forEach(System.out::println);
@SuppressWarnings("unchecked")
public default <PRE_INPUTS> VarargsFunction<PRE_INPUTS, OUTPUT> transformArguments(Function<PRE_INPUTS, INPUTS> transformer) {
return inputs -> apply((INPUTS[]) Arrays.stream(inputs).parallel().map(transformer).toArray());
}
}

View file

@ -1,3 +1,74 @@
factorial[10] = 3628800
ackermann[3, 2] = 29
fibonacci[20] = 6765
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
@FunctionalInterface
public interface Y<FUNCTION> extends SelfApplicable<FixedPoint<FUNCTION>> {
public static void main(String... arguments) {
BigInteger TWO = BigInteger.ONE.add(BigInteger.ONE);
Function<Number, Long> toLong = Number::longValue;
Function<Number, BigInteger> toBigInteger = toLong.andThen(BigInteger::valueOf);
/* Based on https://gist.github.com/aruld/3965968/#comment-604392 */
Y<VarargsFunction<Number, Number>> combinator = y -> f -> x -> f.apply(y.selfApply().apply(f)).apply(x);
FixedPoint<VarargsFunction<Number, Number>> fixedPoint = combinator.selfApply();
VarargsFunction<Number, Number> fibonacci = fixedPoint.apply(
f -> VarargsFunction.upgrade(
toBigInteger.andThen(
n -> (n.compareTo(TWO) <= 0)
? 1
: new BigInteger(f.apply(n.subtract(BigInteger.ONE)).toString())
.add(new BigInteger(f.apply(n.subtract(TWO)).toString()))
)
)
);
VarargsFunction<Number, Number> factorial = fixedPoint.apply(
f -> VarargsFunction.upgrade(
toBigInteger.andThen(
n -> (n.compareTo(BigInteger.ONE) <= 0)
? 1
: n.multiply(new BigInteger(f.apply(n.subtract(BigInteger.ONE)).toString()))
)
)
);
VarargsFunction<Number, Number> ackermann = fixedPoint.apply(
f -> VarargsFunction.upgrade(
(BigInteger m, BigInteger n) -> m.equals(BigInteger.ZERO)
? n.add(BigInteger.ONE)
: f.apply(
m.subtract(BigInteger.ONE),
n.equals(BigInteger.ZERO)
? BigInteger.ONE
: f.apply(m, n.subtract(BigInteger.ONE))
)
).transformArguments(toBigInteger)
);
Map<String, VarargsFunction<Number, Number>> functions = new HashMap<>();
functions.put("fibonacci", fibonacci);
functions.put("factorial", factorial);
functions.put("ackermann", ackermann);
Map<VarargsFunction<Number, Number>, Number[]> parameters = new HashMap<>();
parameters.put(functions.get("fibonacci"), new Number[]{20});
parameters.put(functions.get("factorial"), new Number[]{10});
parameters.put(functions.get("ackermann"), new Number[]{3, 2});
functions.entrySet().stream().parallel().map(
entry -> entry.getKey()
+ Arrays.toString(parameters.get(entry.getValue()))
+ " = "
+ entry.getValue().apply(parameters.get(entry.getValue()))
).forEach(System.out::println);
}
}

View file

@ -0,0 +1,3 @@
factorial[10] = 3628800
ackermann[3, 2] = 29
fibonacci[20] = 6765

View file

@ -1,18 +1,14 @@
function Y(f) {
var g = f(function() {
return g.apply(this, arguments);
});
var g = f((function(h) {
return function() {
var g = f(h(h));
return g.apply(this, arguments);
}
})(function(h) {
return function() {
var g = f(h(h));
return g.apply(this, arguments);
}
}));
return g;
}
var fac = Y(function(f) {
return function(n) {
return n > 1 ? n * f(n - 1) : 1;
};
});
var fib = Y(function(f) {
return function(n) {
return n > 1 ? f(n - 1) + f(n - 2) : n;
};
});

View file

@ -1,14 +1,9 @@
function Y(f) {
var g = f((function(h) {
return function() {
var g = f(h(h));
return g.apply(this, arguments);
}
return (function(h) {
return h(h);
})(function(h) {
return function() {
var g = f(h(h));
return g.apply(this, arguments);
}
}));
return g;
return f(function() {
return h(h).apply(this, arguments);
});
});
}

View file

@ -1,9 +1,17 @@
function Y(f) {
function pseudoY(f) {
return (function(h) {
return h(h);
})(function(h) {
return f(function() {
return h(h).apply(this, arguments);
return f.bind(function() {
return h(h).apply(null, arguments);
});
});
}
var fac = pseudoY(function(n) {
return n > 1 ? n * this(n - 1) : 1;
});
var fib = pseudoY(function(n) {
return n > 1 ? this(n - 1) + this(n - 2) : n;
});

View file

@ -1,17 +1,5 @@
function pseudoY(f) {
return (function(h) {
return h(h);
})(function(h) {
return f.bind(function() {
return h(h).apply(null, arguments);
});
});
function Y(f) {
return function() {
return f(Y(f)).apply(this, arguments);
};
}
var fac = pseudoY(function(n) {
return n > 1 ? n * this(n - 1) : 1;
});
var fib = pseudoY(function(n) {
return n > 1 ? this(n - 1) + this(n - 2) : n;
});

View file

@ -0,0 +1 @@
Y = f -> (x -> x(x))(y -> f((args...) -> y(y)(args...)))

View file

@ -0,0 +1,2 @@
fac = f -> (n -> if n<2 1 else n*f(n-1) end)
Y(fac)(3)

View file

@ -4,33 +4,32 @@ typedef int (^Func)(int);
typedef Func (^FuncFunc)(Func);
typedef Func (^RecursiveFunc)(id); // hide recursive typing behind dynamic typing
Func fix (FuncFunc f) {
Func Y(FuncFunc f) {
RecursiveFunc r =
^(id y) {
RecursiveFunc w = y; // cast value back into desired type
return f(^(int x) {
return w(w)(x);
});
};
^(id y) {
RecursiveFunc w = y; // cast value back into desired type
return f(^(int x) {
return w(w)(x);
});
};
return r(r);
}
int main (int argc, const char *argv[]) {
@autoreleasepool {
FuncFunc almost_fac = ^Func(Func f) {
return ^(int n) {
if (n <= 1) return 1;
return n * f(n - 1);
};
};
FuncFunc almost_fib = ^Func(Func f) {
Func fib = Y(^Func(Func f) {
return ^(int n) {
if (n <= 2) return 1;
return f(n - 1) + f(n - 2);
};
};
});
Func fac = Y(^Func(Func f) {
return ^(int n) {
if (n <= 1) return 1;
return n * f(n - 1);
};
});
Func fib = fix(almost_fib);
Func fac = fix(almost_fac);

View file

@ -0,0 +1,5 @@
Func Y(FuncFunc f) {
return ^(int x) {
return f(Y(f))(x);
};
}

View file

@ -0,0 +1,5 @@
Y(f)=x->f(f,x);
fact=Y((f,n)->if(n,n*f(f,n-1),1));
fib=Y((f,n)->if(n>1,f(f,n-1)+f(f,n-2),n));
apply(fact, [1..10])
apply(fib, [1..10])

View file

@ -1,26 +1,5 @@
<?php
function Y($f) {
$g = create_function('$w', '$f = '.var_export($f,true).';
return $f(create_function(\'\', \'$w = \'.var_export($w,true).\';
return call_user_func_array($w($w), func_get_args());
\'));
');
return $g($g);
return function() use($f) {
return call_user_func_array($f(Y($f)), func_get_args());
};
}
function almost_fib($f) {
return create_function('$i', '$f = '.var_export($f,true).';
return ($i <= 1) ? $i : ($f($i-1) + $f($i-2));
');
};
$fibonacci = Y('almost_fib');
echo $fibonacci(10), "\n";
function almost_fac($f) {
return create_function('$i', '$f = '.var_export($f,true).';
return ($i <= 1) ? 1 : ($f($i - 1) * $i);
');
};
$factorial = Y('almost_fac');
echo $factorial(10), "\n";
?>

View file

@ -1,20 +1,26 @@
<?php
function pseudoY($f) {
$g = function($w) use ($f) {
return $f->bindTo(function() use ($w) {
return call_user_func_array($w($w), func_get_args());
});
};
return $g($g);
function Y($f) {
$g = create_function('$w', '$f = '.var_export($f,true).';
return $f(create_function(\'\', \'$w = \'.var_export($w,true).\';
return call_user_func_array($w($w), func_get_args());
\'));
');
return $g($g);
}
$factorial = pseudoY(function($n) {
return $n > 1 ? $n * $this($n - 1) : 1;
});
echo $factorial(10), "\n";
$fibonacci = pseudoY(function($n) {
return $n > 1 ? $this($n - 1) + $this($n - 2) : $n;
});
function almost_fib($f) {
return create_function('$i', '$f = '.var_export($f,true).';
return ($i <= 1) ? $i : ($f($i-1) + $f($i-2));
');
};
$fibonacci = Y('almost_fib');
echo $fibonacci(10), "\n";
function almost_fac($f) {
return create_function('$i', '$f = '.var_export($f,true).';
return ($i <= 1) ? 1 : ($f($i - 1) * $i);
');
};
$factorial = Y('almost_fac');
echo $factorial(10), "\n";
?>

View file

@ -0,0 +1,20 @@
<?php
function pseudoY($f) {
$g = function($w) use ($f) {
return $f->bindTo(function() use ($w) {
return call_user_func_array($w($w), func_get_args());
});
};
return $g($g);
}
$factorial = pseudoY(function($n) {
return $n > 1 ? $n * $this($n - 1) : 1;
});
echo $factorial(10), "\n";
$fibonacci = pseudoY(function($n) {
return $n > 1 ? $this($n - 1) + $this($n - 2) : $n;
});
echo $fibonacci(10), "\n";
?>

View file

@ -1,4 +1,4 @@
sub Y ($f) { { .($_) }( -> $y { $f({ $y($y)($^arg) }) } ) }
sub fac ($f) { sub ($n) { $n < 2 ?? 1 !! $n * $f($n - 1) } }
sub fib ($f) { sub ($n) { $n < 2 ?? $n !! $f($n - 1) + $f($n - 2) } }
sub Y (&f) { { .($_) }( -> &y { f({ y(&y)(&^arg) }) } ) }
sub fac (&f) { sub ($n) { $n < 2 ?? 1 !! $n * f($n - 1) } }
sub fib (&f) { sub ($n) { $n < 2 ?? $n !! f($n - 1) + f($n - 2) } }
say map Y($_), ^10 for &fac, &fib;

View file

@ -0,0 +1,3 @@
sub Y { my $f = shift;
sub {$f->(Y($f))->(@_)}
}

View file

@ -0,0 +1 @@
Y = lambda f: lambda *args: f(Y(f))(*args)

View file

@ -1,13 +1,9 @@
def y(&f)
lambda do |g|
f.call {|*args| g[g][*args]}
end.tap {|g| break g[g]}
end
y = ->(f) {->(g) {g.(g)}.(->(g) { f.(->(*args) {g.(g).(*args)})})}
fac = y {|&f| lambda {|n| n < 2 ? 1 : n * f[n - 1]}}
fib = y {|&f| lambda {|n| n < 2 ? n : f[n - 1] + f[n - 2]}}
fac = ->(f) { ->(n) { n < 2 ? 1 : n * f.(n-1) } }
p Array.new(10) {|i| fac[i]}
# => [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
p Array.new(10) {|i| fib[i]}
# => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
p 10.times.map {|i| y.(fac).(i)}
fib = ->(f) { ->(n) { n < 2 ? n : f.(n-2) + f.(n-1) } }
p 10.times.map {|i| y.(fib).(i)}

View file

@ -0,0 +1,13 @@
def y(&f)
lambda do |g|
f.call {|*args| g[g][*args]}
end.tap {|g| break g[g]}
end
fac = y {|&f| lambda {|n| n < 2 ? 1 : n * f[n - 1]}}
fib = y {|&f| lambda {|n| n < 2 ? n : f[n - 1] + f[n - 2]}}
p Array.new(10) {|i| fac[i]}
# => [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
p Array.new(10) {|i| fib[i]}
# => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

View file

@ -0,0 +1,3 @@
y = lambda do |f|
lambda {|*args| f[y[f]][*args]}
end

View file

@ -1,8 +1,8 @@
(define Y
(lambda (f)
(lambda (h)
((lambda (x) (x x))
(lambda (g)
(f (lambda args (apply (g g) args)))))))
(h (lambda args (apply (g g) args)))))))
(define fac
(Y

View file

@ -0,0 +1,3 @@
(define Y
(lambda (h)
(lambda args (apply (h (Y h)) args))))

View file

@ -0,0 +1 @@
Y := [:f| [:x| (f value: (Y value: f)) value: x] ].

View file

@ -0,0 +1 @@
fun fix f x = f (fix f) x