Addicted to Pattern Matching

210 views
Skip to first unread message

Eric Kolotyluk

unread,
Jan 31, 2012, 3:40:36 AM1/31/12
to scala-debate
When I first started trying to learn Scala a few years ago there was so
much hype in the documentation about how wonderful pattern matching was,
but I didn't really pay much attention to it as I could not get a feel
for the utility of it.

Now that I have been writing more product code in Scala, increasingly I
find myself using match/case so much now that I am getting addicted to
it. In fact I am increasingly finding new ways to make use of it and new
ways to structure my code to make better use of it - for example
creating case classes for function results.

Yesterday I started using regular expressions in Scala for the first
time, and I really like how well they work with match/case.

Another thing I really like is that pattern matching can improve the
readability of the code substantially. Sometimes if you take the time to
set up your pattern matching code the problem and solution just jump
right out at you.

One disappointment was I could not seem to get pattern matching to work
well with arrays, such as Array[String]. I found various examples on the
web, but could not seem to get any of them working. Fortunately
converting Array[String] to List[String] is trivial, and lists work
great with pattern matching. I always prefer working with lists, but all
programs start with main(arguments : Array[String]).

Has anyone else found themselves getting addicted to pattern matching?
Now when I promote Scala to others at work and elsewhere I'll be
spending more time on the joys of pattern matching.

Does anyone know of a really good treatment of pattern matching from the
basics to more sophisticated stuff - preferably with tons of examples?

Are there plans to add further enhancements to pattern matching in Scala?

Cheers, Eric

Adam Jorgensen

unread,
Jan 31, 2012, 4:00:36 AM1/31/12
to scala-...@googlegroups.com
Pattern matching and case classes are awesome. 'Nuff said :-)

Simon Ochsenreither

unread,
Jan 31, 2012, 6:32:10 AM1/31/12
to scala-...@googlegroups.com
I have never been a fan of it. Couldn't care less if it was removed in Scala 3.

In my opinion the three most over-hyped features of Scala are Enumerations, Pattern Matching and Actors and the amount of bugs associated with them is just terrifying.

martin odersky

unread,
Jan 31, 2012, 6:39:36 AM1/31/12
to scala-...@googlegroups.com

2.10 will have the new pattern matcher and akka as a go-forward
alternative for actors. I am not sure there are open enumeration bugs
in trunk. If there are we should fix them before 2.10 comes out.

So the future looks bright :-)

Cheers

-- Martin

Chris Twiner

unread,
Jan 31, 2012, 6:44:59 AM1/31/12
to scala-...@googlegroups.com
On Tue, Jan 31, 2012 at 12:32 PM, Simon Ochsenreither
<simon.och...@googlemail.com> wrote:

heresy :-)

you can take the other two (although I never remember hype around
Enumerations, adts yes but never those since 2.6), I'm also more than
happy to see by-names disappear and have Function0 take their
place,.....

but pattern matching must be pried from my long dead cold hands. (I
say that as one who doesn't pattern match much, but when I do its a
godsend - there is a meme poster in that)

Eugen Labun

unread,
Jan 31, 2012, 8:33:52 AM1/31/12
to scala-...@googlegroups.com
On 2012-01-31 12:39, martin odersky wrote:
> 2.10 will have the new pattern matcher

What will be different in the new pattern matcher?

Thank you,
EL

Daniel Sobral

unread,
Jan 31, 2012, 8:46:57 AM1/31/12
to Eugen Labun, scala-...@googlegroups.com

The implementation. It abstracts pattern matching in terms of
flatMap/orElse, just like for-comprehensions are implemented in terms
of flatMap/map/foreach/withFilter. In its current implementation, it
uses Option to implement the matching, and optimizes it down to
if/else or switch. One can provide an alternative to Option, though,
which enables some interesting stuff.

--
Daniel C. Sobral

I travel to the future all the time.

Francois

unread,
Jan 31, 2012, 8:46:23 AM1/31/12
to Eugen Labun, scala-...@googlegroups.com

It's virtual, so maybe it will help :)

More seriously, what I know is that it will be simpler to test and
update, and will allow to solve really old bug on the pattern matcher.

There was some discussion about it in the Scala developer list, but as
it seems to be of some interest for the community, perhaps it will be
really cool to have a blog post or a paper about it ?

Cheers,

--
Francois ARMAND
http://fanf42.blogspot.com
http://www.normation.com

Grzegorz Kossakowski

unread,
Jan 31, 2012, 8:55:33 AM1/31/12
to Francois, Eugen Labun, scala-...@googlegroups.com
On 31 January 2012 14:46, Francois <fan...@gmail.com> wrote:
More seriously, what I know is that it will be simpler to test and update, and will allow to solve really old bug on the pattern matcher.

Yes, for the time being the most important fact: new pattern matcher implementation fixes lots of annoying bugs that people would regularly hit when using Lift, Dispatcher or even regexps.

--
Grzegorz Kossakowski

sreque

unread,
Jan 31, 2012, 11:50:37 AM1/31/12
to scala-debate
How else do you data-oriented programming (fixed number of possibly
disjoint types, unlimited number of operations) well? I'll tell you
how I have to do it in C#. It's called the visitor pattern, and it's
so painful that no one uses it unless absolutely necessary. Pattern-
matching with sealed types opens up a whole new incredibly useful
programming style!

On Jan 31, 5:32 am, Simon Ochsenreither

Eric Kolotyluk

unread,
Jan 31, 2012, 9:29:59 PM1/31/12
to scala-...@googlegroups.com
OK, I will just have to assume Simon is being sarcastic and really does
love pattern matching.

I am so tired of the limitations of the C, C++, Java style switch
statement. In C# I cannot believe how many times I switch on String
cases - that small improvement is so incredibly useful. I am glad the
Java is finally catching up in this regard, but both Java and C# are a
far cry from Scala. Over the years I make much more use of switch in
Java than when I used to rely more on chains of if-then-else (which can
get really ugly).

It may be true there are bugs or other issues with pattern matching in
Scala, but I have not encountered them enough (if at all) to find it a
problem. I used the programming language SR over almost 20 years ago,
and I really love how well pattern matching work on events, but I have
not had a chance to do that sort of thing again until recently when
working with Scala. Now that I have been writing production code in
Scala, I just keep finding more an more situations where I can clean up
my code using match/case. Now it is becoming instictive and I write the
code first based on match/case instead of the result of refactoring.

When you think about it, one of the things the human brain is really
good at is pattern matching. One of the reasons I keep stressing that
there needs to be more good concrete examples of Scala code is that I
can often look a well written piece of code and more easily infer what
is going on than reading pages and pages of theory of how to write the
code. Oddly enough, in the past I have often had trouble understanding
people's example of pattern matching in Scala, but now that I have more
experience with it I am finding those example easier to understand.

When I first encountered recursion in University I had trouble
understanding examples of it, but the more I practiced writing code with
it, the more able I was to understand other people's examples.

For the most part I find pattern matching much easier to grok that many
of the sophisticated examples of FP I see in Scala, and I think people
who struggle with FP in Scala, might appreciate trying to master pattern
matching a little more as a way to offset any frustration with mastering FP.

Maybe one day you will be able to do Prolog type stuff in Scala with
pattern matching. I jest of course :-)

Cheers, Eric

Eric Kolotyluk

unread,
Jan 31, 2012, 9:32:22 PM1/31/12
to scala-...@googlegroups.com
Does anyone have any good examples of how to use match/case with
Array[String] - or is it just best to always convert Array[String] to
List[String]?

Cheers, Eric

Eric Kolotyluk

unread,
Jan 31, 2012, 9:39:30 PM1/31/12
to scala-...@googlegroups.com
One of the things I often do now is write functions that return a case
class ReturnResult, with subclasses NormalResult and ErrorResult. Then I
can write code like

fn(foo) match {
case NormalResult(blah) =>
case ErrorResult(blah) = >

While in many cases it is best to throw an exception, often this
return-result pattern works best for me, especially when I am
'scripting' and error results are just as likely as normal results. When
error results are less likely then I tend to prefer exceptions and try
blocks.

Does anyone else have any opinions on this?

Cheers, Eric

sreque

unread,
Jan 31, 2012, 10:55:42 PM1/31/12
to scala-debate
I think for this particular case, where a function can return either
of two values, people usually prefer using class Either or Scalaz's
Validation. That way, you don't have to create boilerplate case
classes each time you want to use this pattern. I actually took the
time to write an Either class in C#, which, even without pattern
matching or good ways of composing functions, has turned out to be
pretty handy. I still have a hard time structuring my programs
functionally with them or structuring all my code inside of a
Validation monad. For instance, In C#, the boiler plate required to
use the ValidationNEL applicative functor to accumulate errors is
pretty painful, especially as their is no type inference for Lambdas
except when passed as a function argument. Also, C#'s type inference
in general isn't nearly as good as Scala's, doesn't have a bottom
type, and, in 3.5, at least, doesn't have type variance to make life
easier. Even with all that, I still like using Eithers! :)

Seth Tisue

unread,
Feb 1, 2012, 1:46:14 AM2/1/12
to scala-...@googlegroups.com

What are you trying to do that doesn't work? Here's some simple things
that work:

Welcome to Scala version 2.9.1.final

scala> Array(1, 2, 3) match {
| case Array(x, y, z) => (x, y, z)
| }
res0: (Int, Int, Int) = (1,2,3)

scala> Array(4, 5, 6) match {
| case Array(_, z @ _*) => z
| }
res1: Seq[Int] = Vector(5, 6)

--
Seth Tisue | Northwestern University | http://tisue.net
lead developer, NetLogo: http://ccl.northwestern.edu/netlogo/

Daniel Sobral

unread,
Feb 1, 2012, 7:15:05 AM2/1/12
to Eric Kolotyluk, scala-...@googlegroups.com

That's Either, without type erasure. There's certainly an advantage to
not having type erasure, in particular Either's type parameters are
type constructors themselves. For example:

// works
(either: Either[String, Int]) match {
case Right(n: Int) => // this is the "right" case, and we can reify n's type
case Left(error: String) => // this is the exception case, and we
can reify error's type too
}


/ doesn't work
(either: Either[String, List[Int]]) match {
case Left(list: List[_]) => // can't reify list's type
case _ =>
}

So, while Either's pattern is nice, it's seriously constrained by type erasure.

Also, its methods make using it on for-comprehensions very awkward.
For an example of how to do it better, see Parsers.ParseResult, or, of
course, Scalaz Validation. While Validation is somewhat verbose, it's
definitely one of Scalaz gateway drugs.

Eric Kolotyluk

unread,
Feb 1, 2012, 1:56:06 PM2/1/12
to scala-...@googlegroups.com
On 2012-01-31 10:46 PM, Seth Tisue wrote:
> On Tue, Jan 31, 2012 at 8:32 PM, Eric Kolotyluk
> <eric.ko...@gmail.com> wrote:
>> Does anyone have any good examples of how to use match/case with
>> Array[String] - or is it just best to always convert Array[String] to
>> List[String]?
> What are you trying to do that doesn't work? Here's some simple things
> that work:
>
> Welcome to Scala version 2.9.1.final
>
> scala> Array(1, 2, 3) match {
> | case Array(x, y, z) => (x, y, z)
> | }
> res0: (Int, Int, Int) = (1,2,3)
>
> scala> Array(4, 5, 6) match {
> | case Array(_, z @ _*) => z
> | }
> res1: Seq[Int] = Vector(5, 6)
>
I was trying to match a regex in one of the Array positions like

scala> val help = "help".r
help: scala.util.matching.Regex = help

scala> val c1 = Array("help")
c1: Array[java.lang.String] = Array(help)

scala> c1 match {
| case Array(help(_)) => println("ok")
| case _ => println("nope")
| }
nope

Is there a way to capture the tail of the array too?

Cheers, Eric

Eric Kolotyluk

unread,
Feb 1, 2012, 2:05:21 PM2/1/12
to Daniel Sobral, scala-...@googlegroups.com

Here is one common way I use Error Results

val dropCommand = List("psql", "-U", "postgres", "-c", "DROP
DATABASE " + database + ";")

Run(dropCommand) match {
case NormalResult(process, outLines, errLines) =>
if (!errLines.isEmpty) {
emit("psql errors:")
emit(errLines)
}
if (!outLines.isEmpty) {
emit("psql output:")
emit(outLines)
}
return true
case ErrorResult(process, outLines, errLines) =>
emitError("psql exitValue = " + process.exitValue)
if (!errLines.isEmpty) {
emitError("psql errors:")
emitError(errLines)
// Succeed if the database does not exist
if (errLines.contains("database \"" + database + "\" does
not exist")) return true
}
if (!outLines.isEmpty) {
emitError("psql output:")
emitError(outLines)
}
}

While (I think) my code is fairly clear, it is more verbose than I would
like. How would Either make this better?

Cheers, Eric

Ryan Hendrickson

unread,
Feb 1, 2012, 2:22:59 PM2/1/12
to Eric Kolotyluk, scala-...@googlegroups.com
> I was trying to match a regex in one of the Array positions like
>
> scala> val help = "help".r
> help: scala.util.matching.Regex = help
>
> scala> val c1 = Array("help")
> c1: Array[java.lang.String] = Array(help)
>
> scala> c1 match {
> | case Array(help(_)) => println("ok")
> | case _ => println("nope")
> | }
> nope

The help regex doesn't have any capturing groups, which is why help(_) won't match anything. Try:

c1 match {
case Array(help()) => println("ok")
}

----------------------------------------

This message is intended exclusively for the individual(s) or entity to
which it is addressed. It may contain information that is proprietary,
privileged or confidential or otherwise legally exempt from disclosure.
If you are not the named addressee, you are not authorized to read,
print, retain, copy or disseminate this message or any part of it.
If you have received this message in error, please notify the sender
immediately by e-mail and delete all copies of the message.

Adriaan Moors

unread,
Feb 3, 2012, 10:27:59 AM2/3/12
to Eric Kolotyluk, scala-...@googlegroups.com


On Wed, Feb 1, 2012 at 3:29 AM, Eric Kolotyluk <eric.ko...@gmail.com> wrote:
Maybe one day you will be able to do Prolog type stuff in Scala with pattern matching. I jest of course :-)
this is exactly what the "virtual" part of the virtualized pattern matcher enables :-)

plug in LogicT instead of Option, et voila! (this is a ways down on my TODO list, but "should work" now (i.e., haven't tested it), and *will* work after higher-priority issues have been sorted out)

There will be blog posts and documentation about this, it's somewhere between "excise remaining dependencies on old pattern matcher" and "experiment with other zero-plus monads" on my TODO list. Think ScalaDays as a timeframe.

adriaan
Reply all
Reply to author
Forward
0 new messages