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.