fireproofsocks

fireproofsocks

How to think about pattern matching vs. type-checking

This is more of a general question, but I’m wondering how other people in the community think about the pattern matching in function signatures.

Pattern matching is fairly straight-forward when you match on simple values, e.g.
def something([]), do: "Emtpy!"

I start to get some metal friction when I look at type-hinting when there are functions like this:

def something(c = %Plug.Conn{}), do: "Something with the conn"

At first glance, I would think that c contains the empty struct, but of course, it will have the FULL value of whatever was passed to the function so long as the input was of the proper type. In other words, it’s not really a pattern-match at all, it’s a type hint.

Granted, my confusion here is probably the baggage of seeing that syntax used not for type-hinting, but for supplying a default value in many other languages (e.g. PHP, Ruby, Python).

The pattern matching/type-hinting gets a bit stranger for me when it gets nested inside tuples. Consider the following example:

my_tuple = MyContext.get_resource_as_tuple()

case my_tuple do
  {:ok, resource = %{status_id: "valid"}} -> result
  {:ok, %{status: status}} -> "Boo. Status #{status} is not valid."
  {:error, msg}  -> "Error: #{msg}"
end

Again, the resource = %{status_id: "valid"} looks more like an assignment, and I have to remind myself how it actually works. Go, for example, omits the equals sign and puts the type after the variable when it is used as part of a type-check. PHP, puts the variable type in front of the variable when it’s used as part of a type-check.

How do others think about this when they’re walking through code?

Most Liked

rvirding

rvirding

Creator of Erlang

I quite agree with the opinion that writing %Plug.Conn{} = c feels much better in a pattern match, it is how you would write the match in code. Though some prefer the other way as they see it as first matching then binding the variable. But they are wrong. :wink:

Also I just want to point out that you can use the = alias in any patterns anywhere so you can write patterns like {a, b, c} = t and [%Plug.Conn{} = c | rest]. You can have your cake and eat it,

I do just want to stress that both ways result in the same code so there is no “better” choice wrt efficiency.

11
Post #7
rvirding

rvirding

Creator of Erlang

Yes, the meaning of the = is different in patterns and in the inline use.

In the inline use the = actually has the syntax pattern = expression where the expression on the RHS is first evaluated and then the value of the expression is matched against the pattern. So it has a very strictly defined right-to-left semantics.

However, in a pattern it is an alias where both sides are pattern matched and both matches must succeed. All the variables in both patterns are bound if the matches succeed. It is commonly used for the case where you want to match and extract parts of a structure and have a reference to the whole. Like in you examples with maps and structs. It lets you have your cake and it.

Using the same operator perhaps wasn’t the smartest thing but it was inherited from Erlang so you can blame them (me). :wink:

kokolegorille

kokolegorille

I use the other way around…

{:ok, %{status_id: "valid"} = resource}

It reminds me of JS destructuring and got used to this form, and it does not look like an assignement.

Where Next?

Popular in Discussions Top

mmmrrr
Just saw that dhh announced https://hotwire.dev/ Is it just me or is this essentially live view? :smiley: Although I like the “iFrame-e...
New
crispinb
On reading dhh’s latest The One Person Framework it strikes me that Phoenix with LiveView is already pretty much this. However, never hav...
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
marciol
Please, let me know if this kind of discussion already took place in another topic . Hi all, how do you consider if is better to build ...
New
sergio
There’s a new TIOBE index report that came out that shows Elixir is still not in the top 50 used languages. It also goes on to call Elix...
New
rower687
Hi all, I’ve been reading a lot about the “let it crash” term and how supervising processes and the whole messaging passing make an elixi...
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
joeerl
I’m playing with Elixir - It’s fun. I think @rvirding does give Elixir courses these days. Re: files and database - when I given Erlang ...
New
paulanthonywilson
I like Umbrella projects and pretty much always use them for personal Elixir stuff, especially Nerves things. But I don’t think this is ...
New
Markusxmr
Since Drab has been developed for a while in the open, introducing the Liveview functionality in a way it happend appears to undermine th...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36128 110
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New

We're in Beta

About us Mission Statement