Is there a reason for not support multi-assignment on select statement?

Following is a reduced example:

chan = Channel(Tuple(String, String)).new

a = spawn(name: "spawn1") do
  sleep rand(10)
  chan.send({"spawn1", "a"})

b = spawn(name: "spawn1") do
  sleep rand(10)
  chan.send({"spawn2", "b"})

2.times do
  when a, b = chan.receive
    pp! a, b

Get following error:


 15 | when a, b = chan.receive
Error: invalid select when expression: must be an assignment or call


Any idea? Is this question described not clearly enough?

What happens when you wrap the a, b = chan.receive in parentheses?

 15 | when (a, b = chan.receive)
Error: unterminated parenthesized expression

I think it was never implemented. But I don’t there is a blocker to do it. It’s syntax sugar mostly.

Will create a PR for that.

Multiple conditions separated by commas can share a when clause in a case expression. I think it would be quite confusing if the same when could turn the conditions into one multiple assignment when the parser encounters = ... at the end


But it’s a when clause with a select. Unless we foresee some use for comas the parse can be adapted to parse a multi assignment in select-when.

It’s true that having a single parser logic for when is nicer.

I don’t use multi-assign a lot so I won’t miss them if we prefer not to add it.

I see your point. On the other hand I think select behaves differently to case already, suppose

chan = Channel(Nil).new


when a = chan.receive
  pp a

Can the print statement be reached? This is already very different from how a case statement behaves.

That said I think select is an abstraction that don’t match the underlying capabilities the OSes provides very well, and it is not very efficient.

That’s a semantical question, not a syntactic one ;)

I think it looks a bit weird to have a multi assign in a condition of a control structure. if a, b = c doesn’t work either.
Arguably, select is a bit special and conditions actually work quite differently from those of if and case. So maybe it’s okay.

I wouldn’t object to adding it, but I’m not quite convinced about it.


It works in Ruby, and it would be nice if it worked in Crystal too.

In fact, it neither work on ruby too.

if a, b = [100, 200]
  p a, b


syntax error, unexpected ',', expecting `then' or ';' or '\n'
> 1  if a, b = [100, 200]
> 3  end
1.rb:1: syntax error, unexpected ',', expecting `then' or ';' or '\n' (SyntaxError)
if a, b = [100, 200]

I consider this not so useful, because don’t know use which one (a or b?) to as if condition.

Try putting parentheses:

if (a, b = [100, 200])
  p a, b

Yes, this time the syntax is clearly enough to use expression in parentheses as if condition.

Maybe we should support this, create a new issue there.