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
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
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)
What will be different in the new pattern matcher?
Thank you,
EL
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.
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
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.
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
Cheers, Eric
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
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/
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.
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
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
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.
Maybe one day you will be able to do Prolog type stuff in Scala with pattern matching. I jest of course :-)