ЗАДАЧА
Поиск удобных способов организации кода. Реализация оператора |>. Частичная аппликация.
РЕШЕНИЕ
Интересное наблюдение - в R аргументы передаются фактически в виде ассоциативного списка, а значит, можно было бы реализовать 'каррирование по ключу'. Что это значит?
># в псевдокоде:
>paste_dot_sep <- paste((collapse='.'))
># Это тоже, что paste_dot_sep <- function(x) paste(x, collapse='.')
># Допустим и другой синтаксис.
>paste_dot_sep(c(1,2,3))
[1] "1,2,3"
Зачем это нужно?
Для удобства кодирования. Например,
># в псевдокоде:
> aff <- function(k, x, b) k*x + b
> scale10 <- aff((k=10)) # 10*x + b
> bias10 <- aff((b=10)) # k*x + 10
Язык не поддерживает и просто частичную аппликацию, поэтому будем эмулировать нужную функциональность с помощью:
> fn_ <- function(fun, ...) (function(x) fun(x, ...))
Из F# позаимствуем оператор |>.
> '|>' <- function(dat, ...) {
res <- dat
funs <- list(...)
for (f in funs) res <- f(res)
res
}
Вот как можно использовать:
>'|>'(69, as.character, fn_(strsplit, ''), unlist, rev, fn_(paste, collapse=''), as.numeric)
[1] 96
> # или
> dat.str <-'1 2 3
+ 4 5 6
+ 7 8 9'
> '|>'(dat.str, fn_(strsplit, ' |\n'), unlist, as.numeric, fn_(matrix, nrow=3))
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> # 'корявая' альтернатива: '|>'(dat.str, fn_(strsplit, ' |\n'), fn_(get('[['),1), as.numeric, fn_(matrix, nrow=3))
Учитывая, что часто приходится преобразовывать данные, такой подход представляется полезным.
Да, есть некоторые сложности с ..., но они разрешаются с помощью необходимых проверок в fn_.
ВЫВОД
В R не реализовано каррирование функций. Упрощает или, наоборот, усложняет это жизнь пользователям - спорный вопрос. На мой взгляд, разработчики должны в большей степени ориентироваться на "функционализацию" языка, чем на историческую совместимость с S и бесполезные игры с quote, eval, expression и пр. По большому счёту, есть HOF, функции - first class citizens, что мешает добавить каррирование? Аргументы по умолчанию - это лишь шаг в правильном направлении.
БОНУС
По наводке palm_mute узнал, что ocaml поддерживает подобную фунциональность с помошью labels.
четверг, 14 февраля 2008 г.
День седьмой (Pipe operator)
на
20:34
Подписаться на:
Комментарии к сообщению (Atom)

Комментариев нет:
Отправить комментарий