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

43 views
Skip to first unread message

Brandon Gillespie

unread,
May 6, 2024, 12:49:13 PMMay 6
to elixir-l...@googlegroups.com
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
after
  millis -> blah
end

```

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
end

```

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


-Brandon

Andrey Yugai

unread,
May 6, 2024, 1:53:35 PMMay 6
to elixir-l...@googlegroups.com

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 elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/c0677b53-2313-41a3-919b-a29ca273f649%40cold.org.

Jon Rowe

unread,
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.

Cheers
Jon

Allen Madsen

unread,
May 7, 2024, 3:28:16 PMMay 7
to elixir-l...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages