Hi,

I just read a blog post [1] talking about Elixir pattern matching. I was 
thoroughly impressed with the way its handled in Elixir. I am posting this 
here cuz I got rather excited and wanted to discuss this with you all. 

My experience with pattern matching is limited to the basics of F# and 
reading the docs of core.match. I think its a great idea, but I also feel 
unless its supported by language at the fundamental level, it remains as 
syntactic sugar. 

All pattern matching code I had read previously, involve matching on a 
specific argument, often inside a function. From what I see in the blog 
post, in Elixir its taken one step further and pattern matching is done at 
the function declaration/invocation level. Normally one would create one 
outer public function and multiple private (?) functions to handle each 
branch. The outer function would only have the pattern matching code. At 
the very least, I find the Elixir version easier to read. It seems to be 
idiomatic for Elixir libraries, functions to return a tuple whose first 
(few?) elements are purely used for pattern matching. 

Consider the following code samples from that blog post,

def to_registration_result({:ok, res}) do
  {:ok, %Membership.RegistrationResult{
    success: res["success"],
    message: res["message"],
    new_id: res["new_id"],
    validation_token: res["validation_token"],
    authentication_token: res["authentication_token"]
  }}
end

def to_registration_result({:error, err}) do
  {:error, err}
end

Normally, I would have one function with an if condition to check for an 
error value in the args and then call respective functions to handle each 
branch. I could also do

(defmulti to-registration-result first)

(defmethod to-registration-result :ok
  [[_ email password]]
  (println email password))

(defmethod to-registration-result :err
  [[_ err]]
  (println "err: " err))

But this wouldn't be idiomatic Clojure. This would also require all 
libraries and functions to return data in a certain form, one where in the 
first element is some kind of status. 

He has another example where pattern matching is used with recursive 
functions to handle transition from one state/step to another and handle 
terminating conditions. This specific example is a very poor choice, but it 
does demonstrate the possibilities.

def map_single({:ok, res}) do
  cols = res.columns
  [first_row | _] = res.rows
  map_single {:cols_and_first, cols, first_row}
end

def map_single({:cols_and_first, cols, first_row}) do
  zipped = List.zip([cols,first_row])
  map_single {:zipped, zipped}
end

def map_single({:zipped, list}) do
  {:ok, Enum.into(list, %{})}
end

def map_single({:error, err}) do
  {:error, err}
end

Interesting stuff. 

[1] - 
http://rob.conery.io/2015/09/04/using-recursion-in-elixir-to-break-your-oo-brain/

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to