How do you refer to the Match Operator when reading code?

When you see code like this:

name = "José"

How do you read it in your mind?

In Ruby I would read it as:

name, is set to, José

In Elixir I’m not sure whether to read it as:

name, match, José

or

name, equals, José

How do you refer to it? Is there a ‘correct’ way?

2 Likes

When there is just a single name, I do read it as “name is set to value of expression” while I do read it as “pattern is applied to expression”. I try to avoid to use “pattern matches expression” to avoid confusion with ===, which I often read as “left matches right”.

3 Likes

Yep, I would say name is set to José as well as in Ruby for single assignments. I know it’s not an assignment, but it’s easier to say, and comparing to other languages, the final result is the same of an assignment.

I never thought about compex pattern matching like:

person = %{name: "José"}
%{name: name} = person

But I guess the @NobbZ suggestions it’s pretty clear, the code could be described like:

  • “person is set to a map with the key name set to José”
  • and then “the pattern for extracting the key name from a map is applied to person”

Reading it afterwards, it feels very complex at the first glance (compared to imperative code when described), but I guess that someone with a little bit of experience in FP will understand everything, and will mentally compile it to the explained code.

3 Likes

Anything wrong with "José" is bound to name?

4 Likes

Pedantically, “set to” feels strange because it suggests trivial assignment without pattern matching. Like @NobbZ said, “match” could be confused with a strict equivalence check.

Elixir’s pattern matching is enabled by a unification algorithm, so what do you all think of “x unified with y”?

2 Likes

I like “bound” too. Simple and understandable.

4 Likes

Here’s a another one to throw in the mix:

name, is the same as, José

From this video.

After watching that video, I am leaning towards just saying:

name, equals, José

And just being aware that the operator can be used to assign variables as well as other things/pattern match - because they all boil down to making both sides the same/equal.

I’m also leaning towards this because = is in fact the equals sign :101: and calling it that just seems to make sense. (Can anyone remember when we first told to refer to the = sign as is set to - I distinctly remembering thinking that that’s weird, it doesn’t mean that it means equals! :lol:)

1 Like

I think that it’s wrong question. I doubt you really translate in your mind = sign to a spoken word or phrase. I’m thinking in terms of symbols when I see symbols. Just like my native language being Polish, I don’t translate English text to Polish when I read it. And just as I read and think in English when dealing with English test, people etc. I think in “Programming” in general or “Elixir” in specific when I deal with Elixir code.

But If I was to read aloud this to someone I’d probably choose equals.

4 Likes

You are absolutely correct when it comes to the isolated character or symbol. But name = "José" puts that character in a context - and context can change everything.
:grin:

2 Likes

Well, thinking a little bit more about it, maybe we, programmers, are just addicted to the verb “to set”. If we get back to our math classes, we would find ourselves describing x = 1 + 2 as “x equals to one plus two”.

EDITED

Yes, it conflicts with == but I guess the context should give “equals” the meaning in this cases. For example if (a == b), do: IO.puts("hi") would be described as “if a equals b prints ‘hi’” and we would totally understand.

And in the conflicting cases like x = (a == b) it could be described like “x equals the value of the boolean expression ‘a equals b’”.

2 Likes

I do :lol: if I am reading through code and the sign is a standard character (so not something like -> or ~>) I automatically read it as such.

I’m not really keen on referring to it as different things in different contexts tbh (particularly as it might confuse newbies).

I think acknowledging/explaining that it does different things in different contexts is probably fine, particularly since it more or less does the same thing; it makes equal or tries to make equal both sides. What do you think?

I don’t think there’s a conflict as that’s two together, which I think makes us more attuned and open to accepting that it means something different (similar or related perhaps, but different). Agree?

1 Like

Strictly speaking the match happens on the left side of = - the right side is strictly off limits and remains strictly whatever value the expression evaluates to.

You have to make an accommodation for the fact that programming languages have an underlying grammar - for example this is an Erlang grammar (as expressed for yecc).

In a sense you are demanding that each letter in the alphabet has its own unique meaning, because you don’t want to be bothered with recognizing words - and it is not like you verbally spell out each letter for every word that you enunciate.

In reference to beginners I think it is extremely important for them to realize that in fact there is a difference. They need to train themselves to recognize the patterns that appear in the language’s grammar in order to identify the semantics of the expression - and = isn’t a pattern - ultimately it’s just a glyph in the textual representation of the expression.

Also beginners gravitate towards a “register-model” for the mental model of variables - i.e. name simply identifies a location capable of containing the value "José" - so when you “assign” "Chris", they imagine the "José" value being replaced/destroyed by the "Chris" value in that location. But that is not what is going on in

name = "José"
name = "Chris" 

Both "José" and "Chris" are immutable values (data) and name is simply an identifier. The first match expression succeeds leaving name bound to the "José" data. The second match expression succeeds by binding name to the "Chris" data. Oversimplification lets beginners adopt a mental model that becomes an obstacle to more advanced learning later.

2 Likes

In Erlang/Elixir I always use the bind verb.
There’s no assignment. Overall when your code evaluates "José" this String is already at the VM language, but is bound now to name. When you do the same thing with "Chris" the name name inside the scope is rebound.

2 Likes

I’m not demanding that at all. I think you are confusing what I’d like to refer to it as (when I read code) with what it means. I’m quite happy for it to keep its meaning/s.

I’m just exploring the idea. I probably need to set up a lecture and see how it feels - my initial thoughts are that I think calling it equals (while also explaining its different uses) would be better than calling it two different things. But I’m not certain, hence really interested in what other (more experienced people) already do.

Is that what most Erlang users do? Would be interesting to see what’s common there :slight_smile:

1 Like

I say I bind José to name

4 Likes

I say “name matched with José”. I realise that might not be that useful though! :stuck_out_tongue:

2 Likes

I use ’name is bound to the binary "José". ‘Set to’ invokes to me that a copy is happening, which is not the case here. :slight_smile:

4 Likes

I just want to expand on my previous answer here. The reason I use the term ‘match’ rather than ‘bound’ is because conceptually, that’s what’s happening. e.g. if, instead of

name = "José"

you take:

"José" = name

it still makes sense to say “José matched with name”. There’s a new abstraction here (for me at least), and it has a name (matching), so use the name! :stuck_out_tongue:

3 Likes

I am also leaning towards match now as well. However I am going to reserve judgement until I have read all of my Elixir books :003:

2 Likes

Another thing to consider:

Pattern matching is a conditional construct and destructuring isn’t.

ES6 for example has destructuring assignment. When something is mentioned in the target that the source doesn’t have, that value is silently set to undefined.

In Elixir an impossible match results in a MatchError - behavior that is exploited to conditionally find the correct case branch or function head for a specific piece of data (contexts in which the match operator doesn’t explicitly appear).

And to increase the challenge how do you read: {m,_} = {42,23}
Note that this expression returns {42,23} as that is the successfully matched value.

2 Likes