Am I the only one confused with the receive/after pattern — it feels like an anti-pattern.

Skip to first unread message

Brandon Gillespie

May 6, 2024, 12:49:13 PMMay 6
I’ve had to re-read those docs several times, and I personally find receive/after rather confusing. It feels like an anti-pattern to the other idioms in elixir, because:
  1. with other uses of `after` in elixir the code therein is literally run AFTER the other stuff is done, and usually its ALWAYS run. But with receive, the value after `after` is an integral definition for how the first block of code/patterns is even handled. The 'after' block may or may not run, it's not always run. And finally, you can only specify one function anyway, so why treat it with that -> pointer operator at all?
  2. It feels like I should be able to set several timeouts, based on using the `->` operator where even right above you can specify many. But no! Only a single expression may be used...

  3. The receive block above is a pattern matching series, but the block under after is NOT, it’s more like cond where the value is evaluated. Seeing both right next to each other is confusing:
millis = 1000
recieve do
  ^millis -> blah # to demonstrate the difference
  millis -> blah


Now to counter some of the arguments I suspect will come up :D

  • “I think it reads fine” -> great, but not helpful. So you’ve already gotten past the mental clunk it causes. I’m interested in finding rough edges to make the whole language more approachable to a wider audience.
  • “Its how it is in erlang” -> In my opinion “status quo” is never an argument. Moving on :D

I had several suggestions, which included adding the timeout value at the top, or using a new `timeout` token instead of `after`, but in the end, I think what is probably the best middle of the road is to allow another `do` instead of the `->`

receive do
  pattern ->
  pattern ->...
after 1000 do
  moar code here


Just some observations/random suggestions. Take them for what you will.


Andrey Yugai

May 6, 2024, 1:53:35 PMMay 6

In my not so long professional experience with elixir, you don't write bare receive/after, usually it comes in some form of genserver callbacks. I agree that after clause not being pattern matching is confusing, but it's a fair trade-off to keep language at least visually consistent, and also not having to dealing with uneven do's and end's from your suggestion.

-------- Original Message --------
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
To view this discussion on the web visit

Jon Rowe

May 7, 2024, 7:48:16 AMMay 7
to Elixir Lang Core
To put across an alternative viewpoint, the way it is now reads consistently with other constructs such as with / else, and adding a second block form would be diferrent from every other construct. The 'may or may not' of the after condition has never bothered me as from my perspective its obvious that you read it as a timeout to be executed after a set period.

I conceed that adding / allowing pattern matching in the after block would be consistent with other uses, but it also would presumedly create problems, you have to specify the timeout after all or it would block forever, and I don't feel allowing multiple timeouts would be helpful.


Allen Madsen

May 7, 2024, 3:28:16 PMMay 7
Reply all
Reply to author
0 new messages