[Proposal] Make Kernel.tap/2 and Kernel.then/2 macros

272 views
Skip to first unread message

sabi...@gmail.com

unread,
Jan 13, 2021, 6:58:58 PM1/13/21
to elixir-lang-core
Hi all!

I saw the recent additions of tap/2 and then/2 to the Kernel and I was wondering, would it make sense to make them macros rather than functions?

Since this is pure syntactic sugar for control flow, like `if` or the pipe operator itself, I thought it could be nice to just generate the desired AST instead of adding the runtime overhead of a function call.
But maybe I missed some implication of such a change, and a function is better in this case?


Looking forward to hearing your thoughts!

José Valim

unread,
Jan 14, 2021, 3:56:02 AM1/14/21
to elixir-l...@googlegroups.com
Thanks for the proposal!

I am honestly a bit torn. The current implementation is definitely more idiomatic and while there is a cost associated with it, the cost is extremely low. :) I am worried making it a macro will signal to developers they need to worry about these kinds of low-level optimizations, which is not generally true!

--
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-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/39ffaaed-e880-4ead-87a9-83a210639969n%40googlegroups.com.

Christopher Keele

unread,
Jan 14, 2021, 3:21:33 PM1/14/21
to elixir-lang-core
> I am worried making it a macro will signal to developers they need to worry about these kinds of low-level optimizations, which is not generally true!

Devil's advocate, one (of many) reasons why dev's shouldn't need to worry about these kinds of optimizations is because the language is conscientious about doing them for devs!

sabi...@gmail.com

unread,
Jan 14, 2021, 6:50:02 PM1/14/21
to elixir-lang-core
Thanks Jose and Christopher for your replies!

> I am worried making it a macro will signal to developers they need to worry about these kinds of low-level optimizations, which is not generally true!

I agree this is a legitimate concern and I totally understand if you prefer to keep this a function.
I'm a bit biased because I spent some time lately on some low-level optimizations, which are indeed not very representative of the typical use cases.

I probably wouldn't even have thought about it if these functions weren't part of Kernel, which seems to be made of many macros already (searching for (macro) in the Kernel docs yield 58 results!).
So it might not be such a strong signal in this particular case?

> Devil's advocate, one (of many) reasons why dev's shouldn't need to worry about these kinds of optimizations is because the language is conscientious about doing them for devs!

I think this is the main argument: if the idiomatic way is also the most performant possible, you don't even have to think about it and to choose between the two.
But this thinking taken to an extreme could lead to much overkill complexity, so the question I suppose is about whether it is relevant or overkill in this particular case?
I honestly wouldn't know :)

José Valim

unread,
Jan 15, 2021, 1:35:58 AM1/15/21
to elixir-l...@googlegroups.com
Alright, please send a pull request so we can also collect the feedback of the rest of the Elixir team. :)

--
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-co...@googlegroups.com.

Fernando Tapia Rico

unread,
Jan 15, 2021, 2:26:13 AM1/15/21
to elixir-lang-core
One benefit of implementing it with functions is the is_function guards, which provide a better user experience in case of bad arguments :)

Allen Madsen

unread,
Jan 15, 2021, 1:54:11 PM1/15/21
to elixir-l...@googlegroups.com
A macro should be able to tell if a function was passed in most cases at runtime.

Allen Madsen

unread,
Jan 15, 2021, 1:54:58 PM1/15/21
to elixir-l...@googlegroups.com
I meant compile time.

Ben Wilson

unread,
Jan 18, 2021, 2:16:39 AM1/18/21
to elixir-lang-core

Unfortunately it cannot do this in all cases:

fun = &IO.inspect/1

foo
|> tap(fun)
|> blah

`tap` as a macro has no ability to know whether `fun` is a function at compile time.
Reply all
Reply to author
Forward
0 new messages