Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.01.2012, 09:38   #1
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию Functional Java?

Привет всем.

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

public interface F<A> {

	A invoke();
}
Код:
package com.fjava;

public interface F1<A, B> {

	A invoke(B b);
}
Код:
package com.fjava;

public class Lazy<T> {

	private T value;
	private F<T> f;

	public Lazy(F<T> 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<String, Integer> f) {
			value = f.invoke(4);
		}

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

	public static void main(String[] args) {
		Lazy<String> s = new Lazy<String>(new F<String>() {
			@Override
			public String invoke() {
				return "Lazy String value.";
			}
		});
		System.out.println(s.invoke());
		F<Void> f = new F<Void>() {
			@Override
			public Void invoke() {
				System.out.println("Closure without arguments.");
				return null;
			}
		};
		f.invoke();
		F1<Integer, Integer> fi2 = new F1<Integer, Integer>() {
			@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<String, Integer>() {
			@Override
			public String invoke(final Integer value) {
				return String.valueOf(value + 6);
			}
		}).value);
		System.out.println("Apply closure 2: " + new A(new F<String>() {
			@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);
	}
}
Будет время, доведу хоть чуток до ума и открою проект на github. Помоему классная идея.

Последний раз редактировалось BOBAH13; 22.01.2012 в 11:51.
BOBAH13 вне форума Ответить с цитированием
Старый 22.01.2012, 21:13   #2
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Может быть Вам будет интересно: http://functionaljava.org/
И http://kotlin-demo.jetbrains.com
Последний ещё не вышел, правда, но обещает быть интересной альтернативой Scala, тем более учитывая скорость компиляции.
netrino вне форума Ответить с цитированием
Старый 22.01.2012, 22:50   #3
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от netrino Посмотреть сообщение
Может быть Вам будет интересно: http://functionaljava.org/
И http://kotlin-demo.jetbrains.com
Последний ещё не вышел, правда, но обещает быть интересной альтернативой Scala, тем более учитывая скорость компиляции.
Ну дело в том, что я ушел со скалы, только из-за того, что она под Android не сильно удобна. А так Java хороший язык, и тут у меня идея просто немного расширить его, по сути просто свернуть некторый boilerplate code в подобие функциональных элементов Scala, к примеру. Т.е. в итоге мы всеравно имеем Java код. Кстати если кто-то заинтересован, прошу, пишите может поговорить и вместе мудрить. Сейчас работает много чего, но всеравно стоит еще, а может даж и переписать, токенайзер - парсер кода на токены для последлующего парсинга и замены на основе регулярных выражений.
BOBAH13 вне форума Ответить с цитированием
Старый 22.01.2012, 23:15   #4
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Мне кажется, что если интересует синтаксический сахар, то имеет смысл взглянуть на Eclipse Xtend, а если функциональщина со стороны библиотеки, то можно использовать functionaljava.
В чём преимущество Вашего подхода?
netrino вне форума Ответить с цитированием
Старый 23.01.2012, 00:08   #5
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Я не шарю в Яве, но ничего необычного не увидел Проясните вкратце?
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 23.01.2012, 00:35   #6
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от Utkin Посмотреть сообщение
Я не шарю в Яве, но ничего необычного не увидел Проясните вкратце?
В текущей версии Java (седьмой) до сих пор нет анонимных функций (планируются к включению в восьмой версии) и стандартная библиотека никак не располагает к программированию в функциональном стиле. BOBAH13 предлагает решение этих проблем в виде препроцессора кода на Java и небольшой библиотеки
netrino вне форума Ответить с цитированием
Старый 23.01.2012, 09:06   #7
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Цитата:
Сообщение от netrino Посмотреть сообщение
В текущей версии Java (седьмой) до сих пор нет анонимных функций (планируются к включению в восьмой версии) и стандартная библиотека никак не располагает к программированию в функциональном стиле. BOBAH13 предлагает решение этих проблем в виде препроцессора кода на Java и небольшой библиотеки
Верно. Только что закончил токенайзер (парсер) основанный на грамматике Java. Теперь только разбирать токены и писать что угодно. Смысл в том, чтобы просто превратить один раз перед компиляцией код в рельный код на Java. В Java есть лозейка (мост) к функциональному подходу - анонимные классы/интерфейсы. Благодаря этому мосту есть возможность создавать где и когда угодно классы и реализовывать (перегружать) их методы. Вот это дело выглядит не сильно круто, для этого можно обвернуть как я и делаю сейчас.

Почему для меня это актуально? Я в основном пишу на Android, там до сих пор 6 версия Java. Кложеры собираются только к 8 дай бог, но я не думаю что Android переедет в ближайшем будущем даже на 7ю версию.

На счет библиотек. Почему это плохо? Ну сразу простой ответ, дополнительный вес какого-то кода. В нашем же случае будут компилироваться и импортироваться совершенно маловесящие и только нужные (используемые) классы/интерфейсы. Конечно это не сильный аргумент. Сильная стороная это - синтаксис "реально" может быть красочным и + никакого рантайма (reflection) кода Java, напрямую вызываем методы анонимных классов.

Ну а дальше пошло поехало, так же можно реализовывать любые примочки. Думаю это классная идея. Я уже разобрал и изучил: Scala, библиотеки для Java, и кучу приемов как дать Java функционального стиля. Лучшее из этого я думаю именно препроцессор, некий транслятор в Java код для компилятора, не для человека (не могу нормально форматировать, да и зачем).

Если интересно буду держать в курсе дела, может потом сделаю еще и для андроид темплейты. Думаю это очень хорошая идея.
BOBAH13 вне форума Ответить с цитированием
Старый 27.01.2012, 09:21   #8
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Просто не могу не похвастаться https://github.com/vladlichonos/FJava
BOBAH13 вне форума Ответить с цитированием
Старый 27.01.2012, 11:28   #9
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Здорово, поздравляю с первыми успехами)
Слегка смутило, что всё на регулярках. И кстати, у Вас опечатка: Translateable должно быть Translatable)
Но от сего творения в таком виде я не вижу много смысла: нет возможности использовать с существующими библиотеками, и не предоставляется своя взамен. Было бы здорово, если бы была реализована хотя бы возможность передавать анонимную функцию в методы, принимающие интерфейс с единственным нереализованным членом, как Comparator, например.
Код:
Arrays.sort (array, (Integer x, Integer y) => { return x - y; });
Ну и, конечно, избавление от return и фигурных скобок в простых выражениях
Код:
Arrays.sort (array, (Integer x, Integery) => x - y);
netrino вне форума Ответить с цитированием
Старый 27.01.2012, 19:04   #10
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Спасибо. Ну на регулярках только токенайзер, а на счет функций, я думаю сделать как в Scala, типа если нужен на пример
Код:
some(new Runnable() {
@Override public void run() { ... } });
чтобы не писать создание инстанца, пишем где-то
Код:
implicit def function2Runnable(f: () => Unit) = new Runnable() { @Override public void run() { f }})
Но это Scala, как мне это сделать пока не знаю, т.к. я не пишу компилятор, это по сути простой заменитель текста, т.е. я не знаю какие типы аргументов принимают функции и т.п.
Сейчас можно передавать функцию как аргумент, но только для ваших новых классов в которых функции принимают аргументы. Собственно, я еще собираюсь писать List, Array - ну как обычно так что думаю все будет нормально, врапперами обойдемся.
BOBAH13 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
чтение файла в массив строк java (Перенесено из Java SE) Sasha9132 Помощь студентам 0 18.11.2010 22:57
Помогите справиться с java.lang.OutOfMemoryError: Java heap space Levilaulada Помощь студентам 1 17.05.2009 10:59