Comments 11
Недоделанный перевод (моего авторства) оригинальной статьи
gist.github.com/2919244
Таки так и не осмелился опубликовать таки, ибо все таки не уверен, что будет полезно в серьезных проектах.
gist.github.com/2919244
Таки так и не осмелился опубликовать таки, ибо все таки не уверен, что будет полезно в серьезных проектах.
0
На тему генерации кода, у автора англоязычной статьи есть несколько не очень удачных моментов.
В частности, не очень удобно задавать модуль, а намного приятнее описать саму рабочую функцию декоратора через fun. Но обработка такого варианта этого «несколько» сложнее.
В частности, не очень удобно задавать модуль, а намного приятнее описать саму рабочую функцию декоратора через fun. Но обработка такого варианта этого «несколько» сложнее.
0
Дополнение: «обработка такого варианта» впринципе невозможна. Проблема в том, что аргументом декоратора может быть только литеральный терм. Т.е. fun там запрещен. До нашего parse_transform дело даже не найдет.
Код типа
или
будет отвергнут парсером еще до применения parse_transform.
Код типа
-d(fun(Fun, Fargs)-> apply(Fun, Fargs) end).
function(X)->
X.
или
-d(fun Mod:Fun/2).
function(X)->
X.
будет отвергнут парсером еще до применения parse_transform.
0
На тему мемоизации, то, что вы реализовали, это скорее безвременное кеширование.
Интереснее было бы через декораторы реализовать настоящую мемоизацию.
что-то типа
gist.github.com/2875252
Через Y-комбинатор. Но не сильно понятно, как на это можно навесить декораторы, так чтобы не пришлось описыватьуродским не очень удобным образом функции.
Интереснее было бы через декораторы реализовать настоящую мемоизацию.
что-то типа
gist.github.com/2875252
Через Y-комбинатор. Но не сильно понятно, как на это можно навесить декораторы, так чтобы не пришлось описывать
fibimpl(Self) ->
fun
(0) -> 1;
(1) -> 1;
(N) when N > 1 ->
((Self)(N - 1)) + ((Self)(N - 2))
end.
0
Согласен. Это скорее кэширование результата.
Но смысл статьи просто продемонстрировать декораторы, а пример — первое что пришло в голову.
Вообще в своем коде я декораторы применяю только для отладки участков кода, а в production они и вовсе отключены.
Но смысл статьи просто продемонстрировать декораторы, а пример — первое что пришло в голову.
Вообще в своем коде я декораторы применяю только для отладки участков кода, а в production они и вовсе отключены.
+1
Кстати, еще одна проблема с parse_transform, в том, что ее можно отключить. Приходится быть внимательнее.
Аналогичный вашему модуль удобно было бы использовать еще для рендеринга страниц и проверки прав доступа.
В вашем случае каскад декораторов отработает корректно?
Аналогичный вашему модуль удобно было бы использовать еще для рендеринга страниц и проверки прав доступа.
В вашем случае каскад декораторов отработает корректно?
0
Да… И порядок имеет значение.
Я, кстати, реализовывал loginRequired декоратор, когда писал проект под Cowboy.
Я, кстати, реализовывал loginRequired декоратор, когда писал проект под Cowboy.
+1
Оно github.com/Egobrain/oauth_cowboy/blob/master/src/oauth_to_functions.erl?
На самом деле Вы классно сделали. Таки, довели до конца задумку Ники.
Единственное, сразу возникает желание завести что-то типа generic decorator
и потом от него наследоваться. Вы об этом думали?
На самом деле Вы классно сделали. Таки, довели до конца задумку Ники.
Единственное, сразу возникает желание завести что-то типа generic decorator
и потом от него наследоваться. Вы об этом думали?
0
Разобравшись с инфой по ссылке не совсем понял какой профит принесет такой код относительно моего в том случае если декоратор поставить на рекурсивную функцию.
fact(N) when is_integer(N) andalso N>=1 ->
fact(N,1).
?MEMOIZE. % now decorator is here
fact(1,Acc) -> Acc;
fact(N,Acc) -> fact(N-1,Acc*N).
0
В таком случае да. Только это не математическое определение. Эффективно, но неудобно.
Хочется писать что-то в духе (хотя это и будет дорого по памяти):
Но в этом случае, бессмысленно запоминать промежуточные результаты.
Тут это ничего не даст. Для более «сложных» примеров ваши декораторы тоже выглядят правдоподобно.
Ключевой момент тут, что fib(N — 2) должна использовать результаты промежуточных вычислений fib(N — 1). После вычисления целевой функции хранить промежуточные результаты смысла особого не имеет, только конечный. Во общем на то и нацелен каскад непонятных функций в примере. Если их удаться удачно убрать в декоратор, то будет здорово.
Хочется писать что-то в духе (хотя это и будет дорого по памяти):
?MEMOIZE.
fact(1) -> 1;
fact(N) when N > 1 ->
N * fact(N - 1)
Но в этом случае, бессмысленно запоминать промежуточные результаты.
Тут это ничего не даст. Для более «сложных» примеров ваши декораторы тоже выглядят правдоподобно.
?MEMOIZE.
fib(0) -> 1;
fib(1) -> 1;
fib(N) when N > 1 ->
fib(N - 1) + fib(N - 2)
Ключевой момент тут, что fib(N — 2) должна использовать результаты промежуточных вычислений fib(N — 1). После вычисления целевой функции хранить промежуточные результаты смысла особого не имеет, только конечный. Во общем на то и нацелен каскад непонятных функций в примере. Если их удаться удачно убрать в декоратор, то будет здорово.
0
Ключевой момент. В вашей реализации декоратор возвращает значение. Но должен функцию. Это позволит комбинировать декораторы в рантайме.
0
Sign up to leave a comment.
Erlang декораторы