[erlang-questions] Pipe Operator in Erlang?
Dmitry Belyaev
be.dmitry@REDACTED
Thu Jul 9 23:26:56 CEST 2015
I'm surprised nobody mentioned erlando: https://github.com/rabbitmq/erlando
--
Best wishes,
Dmitry Belyaev
On 10 July 2015 3:44:55 AM AEST, Fred Hebert <mononcqc@REDACTED> wrote:
>On 07/09, José Valim wrote:
>>I agree with the general feelings of the thread. F# relies on
>currying.
>>Elixir relies on macros (it is actually closer to the thread operator
>found
>>in some lisps).
>>
>>Also F# has most of its standard library expecting the "subject" as
>last
>>argument (due to currying). Elixir defaults to the first argument.
>Erlang,
>>for better or worse, has them mixed (see binary and lists modules).
>>
>
>I agree with this. The only workable form I could imagine could go
>something like this with macros, without major changes to the language:
>
>pipe(Init, a(_, X), b(Y, _), c(_, _, 41.12)), where '_' gets replaced
>by
>the threaded in 'Init' state. The obvious problem is lack of
>composition:
>
>pipe(Init, pipe(Init2, a(_))) where you can't know if a(_) refers to
>Init or Init2 at a glance without knowing precise evaluation rules.
>
>Generally I haven't felt I missed this feature too much in Erlang. In
>the cases where it could really be nice, I resorted to using:
>
> pipe(Init, Funs) ->
> lists:foldl(fun(F, State) -> F(State) end, Init, Funs).
>
> pipe(Init,
> [fun(S) -> set(S, 230) end,
> fun(S) -> update(S) end,
> fun(S) -> output(S), S end]).
>
>Obviously, one could easily come and swoop in with a macro:
>
> pipe(Init, $$, % $$ is replaced by 'Init'
> set($$, 230),
> update($$),
> fun() -> output($$), $$ end)
>
>The problem is that composition is not obvious:
>
> pipe(Init, $$,
> pipe($$, $_,
> set($_, 230),
> update($_),
> fun() -> output($$), $_ end))
>
>In that case, the last 'output($$)' would try to print the literal '$$'
>
>value instead of the substituted one given underneath it all, it's
>equivalent to:
>
> pipe(Init, [fun(S) -> pipe(S, [...]) end]).
>
>Woops! But what's cool? Add in a maybe pipe!
>
> maybe_pipe(Init, Funs) ->
> %% use throws and catches if you wanna go faster
> lists:foldl(fun(F, {ok, State}) -> F(State)
> ; (F, {error, Err}) -> {error, Err} end,
> Init,
> Funs).
>
>And with the same set of parse transforms you can change:
>
> f(X0) ->
> case g(X0) of
> {ok, X1} ->
> case h(X1) of
> {ok, X2} -> {ok, X2};
> Err = {error, _} -> Err
> end;
> Err = {error, _} ->
> Err
> end.
>
>Into:
>
> f(X0) ->
> maybe_pipe(X0, $$, g($$), h($$)).
>
>Which translates to:
>
> f(X0) ->
> maybe_pipe(X0,
> [fun(X) -> g(X) end,
> fun(X) -> h(X) end]).
>
>And all of this is doable today in library code for or from anyone,
>doesn't fundamentally change the shape of Erlang, although it will
>definitely be more confusing for newcomers or people not familiar with
>the concept.
>
>All it needs is someone angry enough to do it. I don't believe (from
>doing experiments like Hubble[1]) that it's particularly hard.
>
>Regards,
>Fred.
>
>[1]: https://github.com/ferd/hubble
>
>_______________________________________________
>erlang-questions mailing list
>erlang-questions@REDACTED
>http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150710/d98a18c4/attachment.htm>
More information about the erlang-questions
mailing list