22nd
Янв

Функциональное программирование в Ява

Posted by Chas under Java

Писал раньше, по моему, но тут начал учить Scala. Все понравилось, супер, но для Android я проигрываю в скорости сборки проекта, это очень важно когда тестируешь UI. Как то не склеилось у меня со Scala под Android, может в будущем. Но после возвращения в Java, как то захотелось функциональной состовляющей, поэтому набросал парочку классов для помощи с этим делом. Примеры:

package com.fjava;

public interface F {

A invoke();
}

package com.fjava;

public interface F1 {

A invoke(B b);
}

package com.fjava;

public class Lazy {

private T value;
private F f;

public Lazy(F f) {
this.f = f;
}

public T invoke() {
if (value == null) {
value = f.invoke();
f = null;
}
return value;
}
}

При использовании этих классов можно выполнять действия как в чисто функциональном языке, т.е. 2 типа closures и один lazy инициализация. Код будет выглядить как то так:

package com.fjava.test;

import com.fjava.*;

public class Test {
static class A {
public final String value;

public A(F1 f) {
value = f.invoke(4);
}

public A(F f) {
value = f.invoke();
}
}

public static void main(String[] args) {
Lazy s = new Lazy(new F() {
@Override
public String invoke() {
return "Lazy String value.";
}
});
System.out.println(s.invoke());
F f = new F() {
@Override
public Void invoke() {
System.out.println("Closure without arguments.");
return null;
}
};
f.invoke();
F1 fi2 = new F1() {
@Override
public Integer invoke(final Integer i) {
return i * 2;
}
};
System.out.println("Closure with Integer: 3 * 2 = " + fi2.invoke(3));
System.out.println("Apply closure: " + new A(new F1() {
@Override
public String invoke(final Integer value) {
return String.valueOf(value + 6);
}
}).value);
System.out.println("Apply closure 2: " + new A(new F() {
@Override
public String invoke() {
return "2";
}
}).value);
}

Как то не круто смотриться, не так ли? И тут пришла ко мне идея, в идеале, сделать плагин для Eclipse с подстветкой синтаксиса и встроить транслятор в очередь сборки перед Java компилятором. Теперь как это (уже работает) и смотрится, обозвал просто FJava (functional java), файлы с расширением .fjava. И теперь, как выше программу можно «сжать»:

package com.fjava.test;

public class Test {

static class A {

public final String value;

public A((String, Integer) => f) {
value = f.invoke(4);
}

public A((String) => f) {
value = f.invoke();
}
}

public static void main(String[] args) {
lazy String s = "Lazy String value.";
System.out.println(s.invoke());

f = (Void) => {
System.out.println("Closure without arguments.");
};
f.invoke();

fi2 = (Integer, Integer i) => {
return i * 2;
};
System.out.println("Closure with Integer: 3 * 2 = " + fi2.invoke(3));

System.out.println("Apply closure: " + new A((String, Integer value) => {
return String.valueOf(value + 6);
}).value);

System.out.println("Apply closure 2: " + new A((String) => {
return "2";
}).value);
}
}

тема на форуме

Похожие статьи