Interesting And Unexpected Benefit Of Pattern Matching

So recently I’ve been working on automating some interactions with a website.  Elixir’s Hound library is a great help, of course.  But I also ran across an interesting and unexpected benefit to pattern matching that greatly simplified some code.

I was trying to dynamically build a URL to pass parameters. The URL would be in the form:

http://www.exampledomain.com?param1=p&param2=q&param3=r

Whenever I see code like this, it’s always a little tricky because you want to add the & at the end of each parameter except the last.  This always used to entail writing a special case in the loop to test if the index of the current element was the maximum index.  But with pattern matching and recursion there’s a much simpler and cleaner solution.  Like this:

defp add_params_to_url(url,[%{:name => name, :value => value}]) when is_binary(url) do     #1
 "#{url}#{name}=#{value}"
end
defp add_params_to_url(url,[%{:name => name, :value => value} | t]) when is_binary(url) do   #2
 url = "#{url}#{name}=#{value}&"
 add_params_to_url(url,t)
end
defp add_params_to_url(url,[]) when is_binary(url), do: url   #3

This is Elixir for those unfamiliar with it.  Basically it’s three function clauses.  The first clause (#1) is hit if only one element is in the list passed into the function. The second clause (#2) is hit if multiple elements are present in the list and the third clause (#3) is hit if the list is empty.

So this is how this works.  When I call add_params_to_url, Elixir will automatically try to match the correct function call dependent on which list I pass.  It will also stop at the first function clause which matches so that other function clauses will not be evaluated.

If I pass a list of URL params which has only one element, clause 1 is matched and the parameter and value are appended and I’m done.  The URL already has the ? on the end, of course.  If I pass a list of URL params with mutliple elements, clause 1 doesn’t match so Elixir jumps down to clause 2 and that matches.  Clause 2 takes the first element from the list tacks it on to the list of parameters with a & at the end and then recursively calls itself with the tail of the list.  If the tail of the list contains more than one parameter, clause  1 will once again fail to match and clause 2 will match again.  If it contains only one parameter, clause 1 is matched.  Because clause 1 doesn’t call itself recursively, clause 3 should never be matched; it’s actually more of a guard case in case someone calls the function with an empty parameter list by mistake.

This, to me, is a small bit of genius.  Much simpler to get exactly the effect I want, that is not having an extraneous character tacked to the end of the string, and it’s nice and simple.

By the way, it occurs to me that I might be able to use a reduce or a fold function to achieve this same effect.  The issue there is that it’s less apparent what it is that I’m trying to do and I also run into the same problem–that is, how do I deal with that last element in the list so I don’t get my separator appended?

A Naive Stack Implementation In Elixir

So one of the things I’ve done recently to help me to learn a new language is to tackle creating certain data structures and common operations on those structures in a given language.  And lately I’ve been digging Elixir quite a bit.  So I decided to tackle one of the easiest things I could tackle–a simple, naive stack implementation in Elixir.  First here’s the actual Elixir code:


defmodule Stack do

defstruct elements: []

def new, do: %Stack{}

def push(stack, element) do
 %Stack{stack | elements: [element | stack.elements]}
 end

def pop(%Stack{elements: []}), do: raise("Stack is empty!")
 def pop(%Stack{elements: [top | rest]}) do
 {top, %Stack{elements: rest}}
 end

def depth(%Stack{elements: elements}), do: length(elements)
 end

# Stack.new |> Stack.push(1) |> Stack.push(2) |> Stack.pop

First off, credit where credit’s due: this is more Saša Jurić’s code than it is mine.  I posted my initial code to Code Review and a few folks gave me some great suggestions on how to improve it. But his code seemed the best implementation so this is pretty much his code.

Looking at the code a bit closer, one thing long time OO folks will notice, and something that gave me a lot of trouble initially, is the fact that there’s no member variable to stash the stack in.  The stack has to be passed into each call and the new stack is returned.  This is a big leap in logic and even now after having played with functional for a few years it can still form a large stumbling block for me when I’m trying to solve a problem.

Another thing to notice is this line:


defstruct elements: []

This is within the scope of the module but what is it doing if there’s no member data associated with the module?  It’s easy to assume that modules are analogous to classes in OO and therefore it’s also easy to assume that elements is member data–but that would be a bad assumption.  Elements is actually an abstract data type closely associated with the Stack module.  It’s a way of specifying more information about the data that the various functions in Stack will work with.  You cannot access elements from outside of Stack and in fact it’s not private data within Stack.

One comment Saša made resonates for me. To paraphrase his point,  there is already a stack implementation in Elixir; it’s called a list.  So why bother to build another one?  It’s a fair question; my answer is that if I needed a stack, I’d rather see code that deals with “Stack” directly than see code that deals with lists and has comments littered all over the place that it’s using a list as a stack.  Of course, it’s syntactic sugar but at some level anything other than raw 1’s and 0’s is syntactic sugar.  It’s a question of making it easier for other developers to understand the intent of the code.

I share this not because it’s great or interesting code (although it was much improved by feedback from Johnny Winn, Saša and José Valim) but because someone may want to study this relatively simple code to learn more about Elixir.

 

 

 

Einstein’s Riddle and Closed Questions

There was a question posted to Stackoverflow about an implementation of the solution of “Einstein’s Riddle” in F#.  Here’s the text of the question, which I include in case the text of the question is later altered:

I’m looking for Einstein’s Riddle solution using F# and I’ve found only Einstein meets F#.

Is F# suitable for this problem and are there any other implementations?

After a bit of discussion and debate, the question was closed.  After a bit more discussion, the question was reopened.  It’s currently well on its way to being closed again. This is nothing that unusual for Stackoverflow.

What I found quite interesting and a little bit troubling was a thread of tweets on Twitter about who closed the question and why it was closed.  Perhaps I misunderstood the tweets in question but it seemed that people thought the question was closed partly because it concerned F#. One person implied that one of the people who voted to close the question had no right to do so because he’s never answered an F# question and therefore can’t know anything about F#.

Now this is solely my opinion, of course, but I think the question should be closed, F# or not.  The reason is the second sentence.  “Is F# suitable for this problem and are there any other implementations?”  If he had stopped after the first question, I would have been fine with the question being left on Stackoverflow.  However, think about that second sentence “Is F# suitable for this problem” – well, I don’t know.  Define suitable and then we’ll talk.  F# is suitable for lots of stuff but if you need to build a solution on the JVM then no it’s probably not suitable.  If you need to interface with lots of native DLL’s on Windows, there may be more suitable approaches.  If you’d like very succinct, short code then probably Prolog is more suitable. This strikes me as a terrific example of an open-ended question.  Without additional context it’s impossible to give a definite answer. And the second part “are there any other implementations?”  Well, yes, I’d be willing to bet there are.  Which language?  Why do you want to see the code—I mean I doubt this is something for work so why do you want to study it?  Again, hard to answer without additional context.

To my mind the second sentence is rather an open-ended question no matter how you interpret it.  And the Stackoverflow FAQ pretty clearly asks people not to ask open-ended questions: “Chatty, open-ended questions diminish the usefulness of our site and push other questions off the front page”.  Now the FAQ is not the received word of God but it is a sort of contract that the people paying to run the site ask all of the users to honor.

Frankly I have to say that I’m a little disappointed with my fellow F# developers who seem to think that someone is going through and closing questions solely because they touch on F#.  It takes five votes to close a question—one person with a grudge is only 20% of the way there–and I don’t think implying that someone has a personal grudge against F# is really helpful or productive.

Don’t get me wrong; I have nothing against open-ended discussion questions.  I do have a problem with people posting such questions on Stackoverflow when the people running the site have repeatedly asked members not to do so.

Now some of you reading this will think—fine delete the second sentence.  But that’s not quite the same thing as fixing a typo now is it?  If the original questioner would remove that second sentence I’m sure no one would be voting to close his question.  But that should be his decision.

As I say, I’ve got nothing against open-ended discussions—love them in fact.  But when someone provides a great service to me for free and they ask me to please avoid a certain behavior it seems a bit ungrateful for me not to avoid it.

And please fellow F# developers—dial down the paranoia a bit please?  Hypersensitivity to any whiff of anti-F# feeling isn’t really helping us to get the word out about a great language.

Why I Don’t Care If You Think Functional Programming Matters

Jon Harrop, who is a strong advocate for functional programming, recently tweeted some links to questions on programmers.stackexchange.com (here and here) I’m generalizing a bit (not much though) but the basic substance of these questions amounted to “Why Should I Learn Functional Programming?”  

It’s a fair question.  I’ve been a developer and around developers long enough that I’ve long ago learned that most of them won’t take anything on faith—and justifiably so.  I’ve even coined a term—“Missouri Developers.”  For those who wonder what that means, the state of Missouri in the United States has the nickname “The ‘Show Me’ State”.  A lot of developers, when they feel comfortable with the subject they’re discussing are very much in the “Show Me” crowd; skeptics in the most pejorative sense of that word.

But, honestly, I’m sort of tired of hearing the question because I hear a common subtext; an unstated question.  “If I learn functional programming will I be able to work on cool new technology?”  I’ve been developing software long enough to remember when there was serious debate as to whether or not Java would take off.  I remember reading articles about how foolish Sun was to try to build a VM because Microsoft had so much expertise in building VM’s (VB6 anyone)? The same kind of question came up about Java—”Why Should I Learn Java?”—with the same subtext.  And before that I can recall reading debates in software development magazines about whether or not it was worthwhile to learn C++.

Some people who learned Java back in the early 90’s got to work on some cool tech—some did not. 

The fact of the matter is that any cutting edge technology has certain risks built into learning it.  If you’re trying to decide whether or not you should learn a new technology based on whether or not you might be able to land a cool job if you learn it—do us both a favor and find another career.  The developers I’ve known over the years who I have the deepest respect for are those developers who love to learn.  They don’t need anyone to tell them to learn new technologies and new ideas; they do so because they love to do it.  And they don’t worry about what kind of cool new jobs might open up to them if they learn a new technology—they learn because they want to know. 

I’ve been playing with functional for about two years now.  I can empathize with those developers with years of experience in C and Pascal about the time of the early 90’s—seeing the large shift from procedural to OO had to have been hard to adjust to.  But I can also see some real strides forward that you can get by adopting functional programming—just as the adoption of OO brought about a lot of strides forward in development. 

Now I know some of you will read this and think to yourselves—wow, he drank the whole pitcher of the kool-aid.  I don’t think functional programming is a panacea.  On the other hand I never thought of OO as a panacea either but it seems that many of the Java and C# programmers in the world cannot conceive of software without objects.  And I don’t think of improving software engineering as a zero-sum game either; that is, I don’t believe that if we improve one area of software engineering that another area must necessarily suffer.  Default mutability in a language is an accidental complexity.  Mutability has its place but it should not be the default.

Either way, if you want to learn and expand your mind, then I’ll be glad to share anything I’ve learned with you.  I love talking tech with others who are intellectually curious.  Otherwise, if you aren’t willing to play with functional until you’re convinced there will be plentiful jobs in cool technologies for those who learn functional—then don’t play with functional; I don’t care.  But stop asking me why you should take the time to learn functional.  If you don’t possess any intellectual curiosity feel free to sit on the sidelines and watch the revolution.