Pull to refresh

Comments 19

очень не советую использовать. насколько мне не изменяет память, эту возможность собираются выпилить в R16
На сколько я понял это не совсем то.
tuple fun это как-то так:
F = {lists,seq},
F(1,10).

Это уже интереснее: могут выпилить, но могут таки и оставить, слегка улучшив :)
Не знаю как к этому относиться: с одно стороны не хочется чтобы Erlang потерял свою лаконичность из-за введения новых фич; с другой-же, складывается ощущение, что в нем чего-то таки не хватает. Какой-то мелочи, которая сделала бы его идеальным, по крайне мере для меня.
Но с тем что record не самое лучшее решение (особенно, из-за того что его структура теряется в runtime, что особенно критично когда State хранится в record и при добавлении нового поля при hot code reload все летит к чертям ) и его надо чем-то заменить, я полностью согласен.
Специально для вас в OTP есть хуки на смену кода. Там можно делать миграцию рекордов (правда, придется тащить за собой предыдущие версии).
что в нем чего-то таки не хватает.

Статической типизации, каррирования, монад)) Но как это обойти во общем-то понятно. Но это тоже «черная магия».
State хранится в record

А чем Вам proplists не угодили? Они конечно медленее, но тут применимы.
Тут применимы, я имею в виду более сложные случаи, в которых производительность — ключевой фактор.
+proplist нельзя match-ить
it depends в обоих случаях.

А потом, по сути все равно будет О(1), ибо ««вряд ли придет в голову динамически создавать десятки сотни, тысячи полей.
Проплисты — можно матчить как обычные списки, возможно придется учитывать порядок следования, но если производительность важнее, то можно и потерпеть такие неудобства.

В глубине души я с Вами согласен. Но хочется иметь возможность обойти такие неудобства без недокументированных возможностей языка.
А если использовать параметризованные модули, то лучше это делать явно.
Тогда появляется возможность использовать extend. Тоже спорная, но иногда удобная вещь.
каррирования, монад)) Но как это обойти во общем-то понятно. Но это тоже «черная магия».

Erlando наше все :)
Кстати, даже если удалят, то эту идею можно применить немного по-другому. Если состояние хранится в картеже где первый элемент имя модуля, то можно будет код модифицировать как-то так :)

to_json(Resource) ->
  ResModule = element(1),
  Proplist = ResModule:proplist(Resource),
  Json = mochijson2_fork:encode({struct,[Proplist]}),
  {ok,Json}.

to_xml(Resource) ->
  ResModule = element(1),
  Proplist = ResModule:proplist(Resource),
  XML = SomeProplistToXmlGenerator(Proplist),
  {ok,XML}.
erlang:element(1, Resource). 
?

Имхо, не очевидные вещи. + Закладка на порядок. Это, таки, эффективно, но совсем не расширяемо.
Еще раз объясните, пожалуйста, зачем все это нужно и что мы с этого имеем? Почему нельзя просто вызвать модуль статические, или например передать его вторым параметром?
прошу прощения… описался.
На самом деле это не более чем синтакчический сахар, чтобы не светить явно меркер пренадлежности структуры модулю.
Т.е. если мы знаем, что в функцию бедет передаваться структура данных, модуль отвечающей за котороую поддерживает функцию some_function можно писать так
my_fun(Data) ->
   Res = Data:some_function(),
   % process data 
   ...

вместо
my_fun({Module,Data}) ->
   Res = Module:some_function(Data),
   % process data 
   ...

Иногда это просто удобнее…

Я придумал, как всех помирить при помощи лямбды.

-module(no_par_mod).
-compile(export_all).

-spec make_caller(Module::atom(), Data::any()) -> fun((Function::atom(), Args::[any()]) -> any()).
make_caller(Module, Data) ->
   fun(Function, Args) ->
      erlang:apply(Module, Function, [Data|Args])
   end.

hello(Instance, X, Y) ->
   io:format("Hello, ~s, take these ~w and ~w!~n", [Instance, X, Y]).

caller_demo() ->
   Instance = "Kitty",
   Caller = make_caller(?MODULE, Instance),
   Caller(hello, [apple, orange]).
Так немного красивее:
caller_demo() ->
   Kitty = make_caller(?MODULE, "Kitty"),
   Kitty(hello, [apple, orange]).
Sign up to leave a comment.

Articles