then/2 is a macro and the emitted code should be optimized from Erlang/OTP
24+.

On Mon, Jan 3, 2022 at 4:28 PM w...@resilia.nl <w...@resilia.nl> wrote:

> Since v1.12 we have the macro `Kernel.then(value, function)` which expects
> an arity-1 function and will call it with the given value.
>
> This makes code which used to be written as follows:
>
> ```
> def update(params, socket) do
>   socket =
>     socket
>     |> assign(:myvar, params["myvar"])
>     |> assign_new(:some_default, fn -> 42 end)
>
>   {:noreply, socket}
> end
> ```
>
> more readable, by allowing it to be written as:
>
> ```
> def update(params, socket) do
>     socket
>     |> assign(:myvar, params["myvar"])
>     |> assign_new(:some_default, fn -> 42 end)
>     |> then(&{:noreply, &1})
> end
> ```
>
> This pattern seems to be common in codebases using Elixir 1.12 and up (At
> least according to anecdotal evidence).
>
> All is well. Except there is a little snag: The new code does not have the
> same runtime characteristics (both in performance and in memory usage) as
> `then`desugars to `(function).(value)`: An anonymous function is created
> and immediately run (and then garbage collected soon after).
>
> The Erlang compiler is clever enough to optimize these immediately-called
> anonymous functions away, but it will only do so when `@compile :inline` is
> set in the given module, to not mess with the call stack that might be
> returned when an exception is thrown.
>
> Now `@compile :inline` is quite the sledgehammer, as it will inline *all*
> functions in the current module (as long as they are not 'too big', which
> can also be configured, and only in the places where they are called
> statically).
> But since we're dealing with anonymous functions here which do not have
> clear names, there is no way to predict the name one should pass to the
> `@compile` option.
>
>
> It seems like this situation could be improved, although I am not sure how.
>
> Is there a way to mark these anonymous functions in some kind of way, to
> allow only them to be inlined?
> Or is there maybe a way to have the Elixir-compiler already inline common
> patterns like a capture with a datatype, rather than relying on the Erlang
> compiler for this?
> Your input is greatly appreciated.
>
> ~Marten/Qqwy
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/f0da2df2-432e-423c-a02b-27d8b916a0ecn%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/f0da2df2-432e-423c-a02b-27d8b916a0ecn%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2Bu8RTb8sMAJyGiuw6%2BgGgyuVZVxjpFad9M%2BbEgYrwkbg%40mail.gmail.com.

Reply via email to