{"id":248,"date":"2011-03-06T18:19:39","date_gmt":"2011-03-06T16:19:39","guid":{"rendered":"http:\/\/misto.ch\/?p=248"},"modified":"2011-03-06T18:19:39","modified_gmt":"2011-03-06T16:19:39","slug":"eliminating-pattern-matching","status":"publish","type":"post","link":"https:\/\/misto.ch\/de\/2011\/03\/06\/eliminating-pattern-matching\/","title":{"rendered":"Eliminating Pattern Matching"},"content":{"rendered":"<p>In the last few years, I worked on several Java projects where we transformed and analyzed abstract syntax trees, so when I started learning Scala, pattern-matching quickly became one of my favorite language features. I could never warm up to the visitor pattern, so I was thankful that Scala offered a much more powerful alternative.<\/p>\n<p>What I also liked very much was Scala&#8217;s consistent use of the <tt>Option<\/tt> type in its standard library. Now, instead of having to read the documentation to find out whether some call could return <tt>null<\/tt>, the type checker forced me to handle this where necessary. So a lot of my early Scala code looked as follows:<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\ndoSomething() match {\n  case Some(value) =&gt; Some(doSomethingElse(value))\n  case None =&gt; None\n}\n<\/pre>\n<p>While it&#8217;s still possible to get a NPE in Scala, it just doesn&#8217;t happen with well-written libraries, simply because there&#8217;s no need to ever use <tt>null<\/tt>.<\/p>\n<p>(By the way, isn&#8217;t it funny that Java forces you to check exceptions but doesn&#8217;t help you with the much more common and annoying <tt>null<\/tt> problem?)<\/p>\n<p>So yes, in practice, <tt>Options<\/tt> do save you from NPEs. Does your code also get smaller (because usually, in Scala it will)? Not if you pattern match on <tt>Some<\/tt>\/<tt>None<\/tt>, all the un-wrapping and lifting is quite verbose.<\/p>\n<p>Nowadays, certainly influenced by all the discussions on monads, I realize that pattern-matching on <tt>Option<\/tt> is a very primitive  form of abstraction, and instead of the code above I now write:<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\ndoSomething() map (value =&gt; doSomethingElse(value))\n<\/pre>\n<p>(For those unfamiliar with functional programming, <tt>map<\/tt> applies the function to the value inside a <tt>Some<\/tt>, and does nothing when called on a <tt>None<\/tt>.)<\/p>\n<p>Even better, we can fully automate this refactoring! I&#8217;m currently working on a first version in the scala-refactoring library. So far, I&#8217;ve implemented the refactoring for map, but there are many more we can do, for example:<\/p>\n<ul>\n<li>If the <tt>Some<\/tt> case does not construct a <tt>Some<\/tt> but calls a function that returns an <tt>Option<\/tt>, we use <tt>flatMap<\/tt> instead of <tt>map<\/tt>.<\/li>\n<li>If the <tt>Some<\/tt> case evaluates to <tt>Boolean<\/tt> and the <tt>None<\/tt> case returns <tt>false<\/tt>, we can replace it with <tt>exists<\/tt>. If <tt>Some<\/tt> returns <tt>true<\/tt> and <tt>None<\/tt> returns <tt>false<\/tt>, we can just replace the whole pattern match with <tt>isDefined<\/tt>.<\/li>\n<li>When the <tt>None<\/tt> case is <tt>()<\/tt>, we can transform to <tt>foreach<\/tt>.<\/li>\n<\/ul>\n<p>So far we have only looked at <tt>Option<\/tt>, but there is more: for example, we could also replace pattern-matching on lists and recursion with folds. I&#8217;m sure somebody has already written a paper about such refactorings, but I haven&#8217;t found anything yet.<\/p>\n<p>What do you think about eliminating pattern matching? Do you also prefer mapping to explicit pattern-matching?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last few years, I worked on several Java projects where we transformed and analyzed abstract syntax trees, so when I started learning Scala, pattern-matching quickly became one of my favorite language features. I could never warm up to the visitor pattern, so I was thankful that Scala offered a much more powerful alternative. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,27,1],"tags":[37,38],"class_list":["post-248","post","type-post","status-publish","format-standard","hentry","category-infoq","category-scala","category-uncategorized","tag-refactoring","tag-scala"],"_links":{"self":[{"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/posts\/248","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/comments?post=248"}],"version-history":[{"count":0,"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/posts\/248\/revisions"}],"wp:attachment":[{"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/media?parent=248"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/categories?post=248"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/misto.ch\/de\/wp-json\/wp\/v2\/tags?post=248"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}