Есть в Groovy такая возможность, как currying (каррирование что-ли?) замыканий.
Само понятие прийшло из функционального программирования и означает преобразование функции с один количеством агрументов, в функцию меньшего количества путем "фиксации" значений некоторых аргументов.
Например есть функция f(x,y,z), тогда её каррированием по фиксированному значению арргумента x=10 будет функция Λ(f)=f(10, y, z).
Термин currying прозшел от имени известного математика Хаскеля Карри, и ещё иногда называется Шейнфинкелизацией (от имени Украинского математика Моисея Шейфинкля, который изобрел это понятие)
Покажу небольшой пример того, как можно использовать каррирование замыканий в Groovy.
Предположим есть обычные POGO класс:
String name
String emailAddress
Date dateOfBirth
int weight
String toString() {
name
}
}
И стоит задача реализовать сортировку списка обьектов этого класса по каждому из свойств (name, emailAddress, dateOfBirth, weight).
Для выполнения сортировки списка можно использовать метод sort(), в какой необходимо передать свой экземпляр Comparator-а.
Решением задачи "в лоб" будет реализация для каждого из сортируемых свойств отдельного Comparator-а.
Например для свойства name он будет выглядеть приблизительно так:
public int compare(User a, User b) {
def aValue = a.getName();
def bValue = b.getName();
if (!aValue && !bValue)
return 0;
else if (!aValue)
return -1;
else if (!bValue)
return 1;
else
return aValue.compareTo(bValue);
}
}
И так 4 раза (с)... Не много ли кода для такой мелочи как сортировка?
Теперь же попробуем реализовать подобный функционал с помощью замыканий Groovy.
Создаем такое вот универсальное замыкание-компаратор (а может функцию 3х аргументов?):
def aValue = a.getProperty(attribute)
def bValue = b.getProperty(attribute)
if (!aValue && !bValue)
return 0
else if (!aValue)
return -1
else if (!bValue)
return 1
else
return aValue.compareTo(bValue)
}
Теперь для сортировки по каждому свойствую обьекта User используем каррирование замыкания с фиксированием имени свойства:
usersList.sort( comparator.curry("emailAddress") )
usersList.sort( comparator.curry("dateOfBirth") )
usersList.sort( comparator.curry("weight") )
Вот так все просто и элегантно - немного функционального программирования, немного meta-программирования, немного duck typing-а.
Ссылки:
О понятии Currying в Wikipedia.
Англоязычная версия этой заметки в блоге MustardGrain
Большинство языков программирования которые поддерживают замыкания поддерживают и каррирование:
Currying в Scala (функциональном языке для JVM), Currying в Python, Currying в Ruby.
Источник: http://voituk.kiev.ua/2008/05/12/comparator-closure-currying...