#Tuples pattern matching

1 messages · Page 1 of 1 (latest)

ivory ember
#

I'm trying to pattern match using tuples as:

let a = #(1,2)
let b = #(2,1)
case a {
  #(b.1, b.0) -> {}
  _ -> {}

But the compiler complains:

I'm expecting a pattern here
Hint: A pattern can be a constructor name, a literal value
or a variable to bind a value to, etc.

Which means that I need to unpack b first. I wonder what's the reason I cannot use the tuple directly

oblique tulip
#

Looks fine to me

#

Can we see the whole error please

#

oh

#

sorry

#

Just saw

#

b.1 isn't a pattern, no

#

It's a value

ivory ember
#

but if I let m = #(b.1, b.0) then I can match agains m

#

I'd think that

let m = #(b.1, b.0)
case a {
  m -> {}
}

should be the same as

case a {
  #(b.1, b.0) -> {}
}
#

first snippet works, second does not

vernal burrow
#

That's not doing what you think it's doing. It's accepting any value and assigning to m

#

You'd have to do something if something == m -> to do it like that

hollow torrent
#

Matches in let are on the left side of the equals sign

So you’d see that let #(b.0, b.1) = b would also be a compiler error the same way matching on this with a case branch would be

ivory ember
#

that's because tuples are immutable ?

viral ivy
#

The behaviour you’re expecting is called “pinning” where you can use the value or some other variable inside a pattern

oblique tulip
#

It is intentional

viral ivy
#

In gleam we dont have that, instead you would use guards

ivory ember
#

OIC

oblique tulip
#

We will not have 1 syntax that does 2 different things, and where you can only tell which one it does by reading the entire rest of the module

#

It's a relatively common source of bugs in Erlang

ivory ember
#

this IS possible in Erlang I believe?

viral ivy
#

case a {
#(x, y) if x == b.0 && y == b.1 -> …
#(x, y) -> …
}

viral ivy
ivory ember
#

right, I assumed that you could do it the same way

oblique tulip
#

You can define a variable and suddenly a case expression elsewhere in the function stops working

oblique tulip
viral ivy
#

Oh!

hollow torrent
#

Shadowing isn’t allowed in erlang right so pinning is out of the box

oblique tulip
#

Elixir's one is better than Erlang's imo as you have the operator to tell you if it is binding or equality

#

Erlang you just have to read all the code and be careful not to accidentally reuse variables

#

It'd be even worse in Gleam as we have consts