Scala pattern matching syntax - scala

I've been playing with scala pattern matching recently and was wondering whether there is a way to create an extractor inside of the case statement. The following code works, but you have to define the extractor first and assign it to a val:
val Extr = "(.*)".r
"test" match {
case Extr(str) => println(str)
}
What I would like to do, or what I would like someone to confirm is impossible, is something like this:
"test" match {
case ("(.*)".r)(str) => println(str)
}
EDIT: In case anyone from the scala team is reading this: Would it be feasible to implement this?

Unfortunately it is not possible and I see no way to simplify your first example.
The case statement has to be followed by a Pattern. The Scala Language Specification shows the BNF of patterns in section 8.1. The grammar of patterns is quite powerful, but is really just a pattern, no method calls or constructors are allowed there.

I had a similar problem and i solved it like this:
case x if x.matches("regex") => foo(x)
I don't know if this is exactly what you want, but it works

Related

Check the runtime type of Scala class instance

If I run the following code, then I get an error:
import scala.reflect.ClassTag
class General {
}
class SubGeneral extends General {
def test() = println("tested")
}
class ProGeneral[T <: General: ClassTag] {
var array = Array.ofDim[T](3, 3)
def funcForSubGeneral(): Unit =
if (array(0)(0).isInstanceOf[SubGeneral]) then array(0)(0).test()
}
That is because General does not have the function test().
I know that I can fix this with pattern matching. This instead of the above funcForSubGeneral() works:
def funcForSubGeneral(): Unit =
array(0)(0) match {
case s: SubGeneral => s.test()
case _ => println("nope")
}
But I was wondering if it is possible to get the runtime type of array(0)(0) and check if it is a SubGeneral, and if that is the case then I call test(), which shouldn't cause a problem?
That is what I was actually trying by using isIntanceOf. I want to omit pattern matching since I'm just interested in one type.
isInstanceOf doesn't change anything, you would need to do array(0)(0).asInstanceOf[SubGeneral].test() in order to force the casting.
Note that the casting may fail at runtime, so that is why you need to check with the if before. Thus the end code looks like this:
if (array(0)(0).isInstanceOf[SubGeneral]) then array(0)(0).asInstanceOf[SubGeneral].test()
But, since this is cumbersome and error-prone, we have pattern matching:
array(0)(0) match {
case subGeneral: SubGeneral => subGeneral.test()
}
However, note that type tests are considered a bad practice; mainly because they are actually class checks and may fail certain circumstances. For example:
List("a", "b", "c") match {
case numbers: List[Int] => numbers.head + 1
}
Will throw an exception in runtime since, due to type erasure, we lost the [String] part and it matches only List then it tries to read the first element as an Int which is an error.
Anyways, this is the fourth time in two days you ask a question that shows bad practices and unidiomatic code.
My advice:
I would bet you are not following an appropriate resource to learn the language. Rather, it seems you are just trying to mimic another language (Python?) with different syntax. - Thus, I encourage you to pick an appropriate book, course, tutorial, etc; that properly introduces the language and its idioms.
I would encourage you to join the official Discord server which is more suitable for newcomers than StackOverflow.
I would recommend you to explain the meta-problem you are trying to solve in detail (either here in a new question or in the Discord server), I am pretty sure there are better and more idiomatic ways to solve it.

multiple-origin extractions in the scala matcher

I often find myself wanting to clump multiple matchers / extractors into the one line, but this doesn't seem to be allowed. e.g.:
text match {
case regex1(a) | regex2(a) => a + "-"
}
(even though a is the same type for both matchers)
so I'm forced to refactor like this (which can get ugly when there are several of these, all handling different matches, mixed with inline responses)
text match {
case regex1(a) => op(a)
case regex2(a) => op(a)
}
def op(a: String) = a + "-"
is there a cleaner way? And will this be supported in Scala in the future?
No, this is not possible in the general case. However, there are a few workaround that might be use to combine pattern matching cases:
Match on a super class of the cases you are willing to group
Use the case a # _ if boolexpr(a) or boolexpr(a) => construction
Factorize the common code in a function, like you did in your example
And probably others. I don't think this is going to change any time soon as it would encourage writing cryptic mach/cases.

Motivation for match expression syntax

The syntax for match expressions is pretty nice:
expr match {
case Test(l1) => ...
...
}
But it's driving me nuts that I don't understand the motivation to why this this syntax is used instead of match (expr) ..., like branching statements in a decent C descendant!
I see no reasonably explanation for this. And I don't find the answer neither in Programming in Scala, the Scala web site, in this paper, this thesis, here on SO nor on the rest of the web.
It's not that it's anything wrong with it, just that it's a complete mystery. And when match work in this way, why not if and for also?
Does anybody know? I don't think I can stand using the language any longer without finding this out. I think about it all the time. I can hardly sleep at night.
To take a similar bit of Scala syntax, guards in pattern matching cases don't require parentheses around their conditional expressions—e.g., the following:
case i if i % 2 == 0 => i / 2
Is just as valid as this:
case i if (i % 2 == 0) => i / 2
Sticking to the C-family style would mean requiring the latter form, even though the parentheses aren't necessary for disambiguation. The Scala language designers decided that reducing line noise trumped maintaining the family resemblance in this case.
I'd guess that a similar motivation is at work in the match syntax, and to my eye match (expr) { ... } does indeed look pretty awful (and misleading) compared to expr match { ... }.
Also, just this afternoon I refactored someone else's x match { ... } on an Option to x map { ... } instead. match as an infix operator makes the similarity between these two expressions clear.
On the issue of why match isn't just a method, here's a five year-old question from David Pollak on the scala-debate mailing list:
Why is 'match' a language level construct rather than a method on Any?
And Martin Odersky's answer:
It used to be that way in Scala 1. I am no longer sure why we changed.
syntax highlighting? error reporting? not sure. I don't think it
matters much either way, though.
I'm with Martin on this one.
Note that there are a couple of practical differences (apart from the simple "dot or not" question). For example, this doesn't compile:
def foo[A, B](f: PartialFunction[A, B])(a: A) = a match f
If match were still a method on Any, requiring a literal bunch of cases would be a rather strange requirement.

Strange case class syntax

I've been learning Scala and decided to play with JSON parsing using json4s. I decided to use XPath syntax for deserializing and came across this strange bit of syntax I've never seen before.
val json = JsonMethods.parse("""{"meaningOfLife": 42}""")
val JInt(x) = json\"meaningOfLife"
The part confusing me is this bit right here
val JInt(x) = ...
I can't wrap my mind around what's happening there, I don't even know how to search this syntax or what it's called. Can anyone help me out? Scala is an amazing language with a lot of neat features that I'm not used to in other languages like C++ and Java.
Edit
To clarify, I'm confused because x isn't defined, but it's somehow being passed into a function or constructor then being assigned to the result of json\"meaningOfLife" which returns a JValue.
Edit 2
After some research and playing around, I figured out that this has something to do with case classes. I was able to run the following code.
case class MyCaseClass (x: Int)
val MyCaseClass(x) = new MyCaseClass(5)
println(x, x.getClass) // prints (5,int)
Which, after looking at some of the code, gives me a good understanding at what's happening.
val MyCaseClass(x) = MyCaseClass(5)
Is extracting (for lack of a better term) the Int value 5 from the instantiated MyCaseClass and storing that into x, meaning x will be of type Int.
In the code for json4s a JInt is a JValue which the \ operator returns. So the JInt(x) is taking out a BigInt (stored in the class JInt) and putting that into the value x from what I gather.
But I still have a question. What is this process called? Is there any documentation on it?
It's called "irrefutable pattern matching" and it's essentially equivalent to this bit of code:
val json = JsonMethods.parse("""{"meaningOfLife": 42}""")
val x = json match {
case JInt(xMatched) => xMatched
}
In other words, any case class or any extractor that fits the pattern of the declaration's left-hand-side can be used in this way.
Addendum:
The "irrefutable" means that a MatchError will be thrown if the pattern cannot be satisfied.

scala: alias for a keyword?

is there a way to create an alias for a scala keyword? in particular i have some boilerplate syntax that involves "val" and in order to make it easier to read i'd like to be able to type something "##" instead and have that translated to val.
Edit:
In some cases, it might be very convenient to be able to replace "lazy val", not just "val". The use case has to do with a function that acts as a python decorator. It looks like this:
lazy val function = Decorate(function_ _)
def function_(x: Int, ...) = { ... }
it would be a lot nicer if it looked like this:
# function = Decorate(function_ _)
def function_(x: Int, ...) = { ... }
just so that there's not a val stacked on top of a def, where both names are extremely similar. (the function_ name is not meant to be called, so it's the cleanest to make the names similar.)
No, there isn't.
(filler so SO will let me post)
Ouch! This isn't particularly idiomatic Scala.
To start with, you're naming a method "function_", they're not the same thing, a method is simply a member of some class, a Function is an object in its own right (although a method can be "lifted" to a function by the compiler, in a similar fashion to the autoboxing of primitives).
Second, what is Decorate? The initial uppercase letter suggests that it's a singleton, therefore an object and the only actual "Function" in that expression!
Could you post a bit more info as to what the method and decorator actually do, so that I can give you a better example as to how you might achieve the same in Scala?
I guess one could write a Scala Compiler Plugin to achieve this. At least the Eclipse Plugin actually uses the original Scala Compiler, so it might actually work nicely with the IDE.
Other then that: Daniel C. Sobral is correct: No, there isn't.
Still it sounds like a lot of trouble for a little gain.
If function_ is never meant to be called directly, why not write
lazy val function = Decorate { (x: Int, ...) => ... }
or even
/**
* This version makes it more explicit that it's a function value.
*/
lazy val function: (Int, ...) => ReturnType =
Decorate { (x, ...) => ... }
Some caution is advised: conciseness and terseness are two different things. Here, it looks like you're trying to buy a few keystrokes at a very high price in terms of readability.
Update:
If you really want to achieve a simpler syntax for this sort of thing, you will need a compiler plugin. If you're going to go that far, I'd suggest using an annotations-based syntax that's likely to be pretty intuitive for Java/Scala developers:
#decorate(Memoize)
def slowFn(i: Int) = { ... }