This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Pattern match as boolean value

7 replies
Johannes Rudolph 2
Joined: 2010-02-12,
User offline. Last seen 42 years 45 weeks ago.

Hi,

there's a common use case to check if some value matches a pattern.

E.g. to check if a value is a one-element list of a particular value.
This is a bit awkward to achieve right now:

val x: List[Option[String]] = List(None) // ...
x match { case List(Some("Test")) => true case _ => false }

This is inefficient syntax-wise because you have to make the boolean
result explicit as true/false and add the default case. We think that
this may warrant the addition of a new bit of syntax which is
equivalent to the above but more succinct. As ubiquitous as patterns
are in Scala this would be a consequent way to access what is
implemented as `PartialFunction.isDefined` right now. It would be an
additional plus if you could use the short syntax as a predicate
requiring a value of `T => Boolean` similar to "Pattern Matching
Anonymous Functions" (SLS 8.5).

Here's a first syntax proposal:

Expand `x match y` into `x match { case y => true case _ => false }`.
For an equivalent to SLS 8.5 this little change would already include
the short form "_ match y" to make an anonymous function out of it.
Creating even shorter forms may be difficult to achieve because of the
similarity between expressions and patterns and the resulting possible
ambiguity in the parser which is currently solved by allowing patterns
only after certain keywords or in certain positions.

Here are some examples of what would be possible with this syntax addition:

val x: List[Option[String]] = //...
x match List(Some("Test"))

or

x.count(_ match Some("Test"))

or even

x.count(_ match Some("Test" | "test2"))

Unused features from patterns (and therefore perhaps confusing if
allowed at those positions) would be binding and guards.

If you want to play around with this syntax I attached a short patch
against trunk which implements this addition directly in the parser.
What do you think?

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: Pattern match as boolean value
On Fri, Oct 14, 2011 at 1:06 PM, Johannes Rudolph <johannes [dot] rudolph [at] googlemail [dot] com> wrote:
Here's a first syntax proposal:

Expand `x match y` into `x match { case y => true case _ => false }`.
For an equivalent to SLS 8.5 this little change would already include
the short form "_ match y" to make an anonymous function out of it.
Creating even shorter forms may be difficult to achieve because of the
similarity between expressions and patterns and the resulting possible
ambiguity in the parser which is currently solved by allowing patterns
only after certain keywords or in certain positions.

Here are some examples of what would be possible with this syntax addition:

val x: List[Option[String]] = //...
x match List(Some("Test"))

or

x.count(_ match Some("Test"))

or even

x.count(_ match Some("Test" | "test2"))

Unused features from patterns (and therefore perhaps confusing if
allowed at those positions) would be binding and guards.

If you want to play around with this syntax I attached a short patch
against trunk which implements this addition directly in the parser.
What do you think?

You can cut down a bit of the noise today with PartialFunction.cond
  scala> import PartialFunction.cond  import PartialFunction.cond
  scala> if (cond(1) { case 2 => true }) {}
Or
  scala> def cond1[T](t: T)(pf: PartialFunction[T, Any]) = pf.isDefinedAt(t)  cond1: [T](t: T)(pf: PartialFunction[T,Any])Boolean
  scala> if (cond1(1) { case 2 => }) {}
That said, I quite like the proposed syntax.
-jason 
Alex Repain
Joined: 2010-07-27,
User offline. Last seen 1 year 31 weeks ago.
Re: Pattern match as boolean value
I guess this thread would be a good fit for inaugurating the new mailing list, scala-sips ( see http://permalink.gmane.org/gmane.comp.lang.scala/24768 ).

2011/10/14 Jason Zaugg <jzaugg [at] gmail [dot] com>
On Fri, Oct 14, 2011 at 1:06 PM, Johannes Rudolph <johannes [dot] rudolph [at] googlemail [dot] com> wrote:
Here's a first syntax proposal:

Expand `x match y` into `x match { case y => true case _ => false }`.
For an equivalent to SLS 8.5 this little change would already include
the short form "_ match y" to make an anonymous function out of it.
Creating even shorter forms may be difficult to achieve because of the
similarity between expressions and patterns and the resulting possible
ambiguity in the parser which is currently solved by allowing patterns
only after certain keywords or in certain positions.

Here are some examples of what would be possible with this syntax addition:

val x: List[Option[String]] = //...
x match List(Some("Test"))

or

x.count(_ match Some("Test"))

or even

x.count(_ match Some("Test" | "test2"))

Unused features from patterns (and therefore perhaps confusing if
allowed at those positions) would be binding and guards.

If you want to play around with this syntax I attached a short patch
against trunk which implements this addition directly in the parser.
What do you think?

You can cut down a bit of the noise today with PartialFunction.cond
  scala> import PartialFunction.cond  import PartialFunction.cond
  scala> if (cond(1) { case 2 => true }) {}
Or
  scala> def cond1[T](t: T)(pf: PartialFunction[T, Any]) = pf.isDefinedAt(t)  cond1: [T](t: T)(pf: PartialFunction[T,Any])Boolean
  scala> if (cond1(1) { case 2 => }) {}
That said, I quite like the proposed syntax.
-jason 



--
Alex REPAIN
ENSEIRB-MATMECA - student
TECHNICOLOR R&D - intern
BORDEAUX I      - master's student
SCALA           - enthusiast


adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
Re: Pattern match as boolean value
FWIW:
class Matches[T](x: T) {  def matches(pf: PartialFunction[T, Any]) = pf isDefinedAt x}
implicit def anyToMatches[T](x: T) = new Matches[T](x)
scala> val x: List[Option[String]] = List(None)
scala> x matches { case List(Some("Test")) =>  }res0: Boolean = false
scala> x matches { case List(None) =>  }res1: Boolean = true


On Fri, Oct 14, 2011 at 2:00 PM, Alex Repain <alex [dot] repain [at] gmail [dot] com> wrote:
I guess this thread would be a good fit for inaugurating the new mailing list, scala-sips ( see http://permalink.gmane.org/gmane.comp.lang.scala/24768 ).

2011/10/14 Jason Zaugg <jzaugg [at] gmail [dot] com>
On Fri, Oct 14, 2011 at 1:06 PM, Johannes Rudolph <johannes [dot] rudolph [at] googlemail [dot] com> wrote:
Here's a first syntax proposal:

Expand `x match y` into `x match { case y => true case _ => false }`.
For an equivalent to SLS 8.5 this little change would already include
the short form "_ match y" to make an anonymous function out of it.
Creating even shorter forms may be difficult to achieve because of the
similarity between expressions and patterns and the resulting possible
ambiguity in the parser which is currently solved by allowing patterns
only after certain keywords or in certain positions.

Here are some examples of what would be possible with this syntax addition:

val x: List[Option[String]] = //...
x match List(Some("Test"))

or

x.count(_ match Some("Test"))

or even

x.count(_ match Some("Test" | "test2"))

Unused features from patterns (and therefore perhaps confusing if
allowed at those positions) would be binding and guards.

If you want to play around with this syntax I attached a short patch
against trunk which implements this addition directly in the parser.
What do you think?

You can cut down a bit of the noise today with PartialFunction.cond
  scala> import PartialFunction.cond  import PartialFunction.cond
  scala> if (cond(1) { case 2 => true }) {}
Or
  scala> def cond1[T](t: T)(pf: PartialFunction[T, Any]) = pf.isDefinedAt(t)  cond1: [T](t: T)(pf: PartialFunction[T,Any])Boolean
  scala> if (cond1(1) { case 2 => }) {}
That said, I quite like the proposed syntax.
-jason 



--
Alex REPAIN
ENSEIRB-MATMECA - student
TECHNICOLOR R&D - intern
BORDEAUX I      - master's student
SCALA           - enthusiast



Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
RE: Pattern match as boolean value

This works as well – might need a bit more syntax for cases like case 1|2|3 but…

 

Try it now: http://bit.ly/mXSXZj

 

implicit def toKaKu (x:Any) = new KaKu(x)

class KaKu (val x:Any) {

    def matches[T] (what:T) = what == x

}

 

List(1,2,3) matches List(1,2,3)

List(1,2,3) matches Seq (1,2,3)

 

System.currentTimeMillis matches "nada"

 

Also – you can take a look at the matchers of scalatest and expect()…

 

Having said that, I also like the syntax proposed – would simplify a bunch of code and less to remember/import.

 

From: scala-debate [at] googlegroups [dot] com [mailto:scala-debate [at] googlegroups [dot] com] On Behalf Of Adriaan Moors
Sent: October-14-11 10:30 AM
To: scala-debate
Subject: Re: [scala-debate] Pattern match as boolean value

 

FWIW:

 

class Matches[T](x: T) {

  def matches(pf: PartialFunction[T, Any]) = pf isDefinedAt x

}

 

implicit def anyToMatches[T](x: T) = new Matches[T](x)

 

scala> val x: List[Option[String]] = List(None)

 

scala> x matches { case List(Some("Test")) =>  }

res0: Boolean = false

 

scala> x matches { case List(None) =>  }

res1: Boolean = true

 

 

 

On Fri, Oct 14, 2011 at 2:00 PM, Alex Repain <alex [dot] repain [at] gmail [dot] com> wrote:

I guess this thread would be a good fit for inaugurating the new mailing list, scala-sips ( see http://permalink.gmane.org/gmane.comp.lang.scala/24768 ).

 

2011/10/14 Jason Zaugg <jzaugg [at] gmail [dot] com>

On Fri, Oct 14, 2011 at 1:06 PM, Johannes Rudolph <johannes [dot] rudolph [at] googlemail [dot] com> wrote:

Here's a first syntax proposal:

Expand `x match y` into `x match { case y => true case _ => false }`.
For an equivalent to SLS 8.5 this little change would already include
the short form "_ match y" to make an anonymous function out of it.
Creating even shorter forms may be difficult to achieve because of the
similarity between expressions and patterns and the resulting possible
ambiguity in the parser which is currently solved by allowing patterns
only after certain keywords or in certain positions.

Here are some examples of what would be possible with this syntax addition:

val x: List[Option[String]] = //...
x match List(Some("Test"))

or

x.count(_ match Some("Test"))

or even

x.count(_ match Some("Test" | "test2"))

Unused features from patterns (and therefore perhaps confusing if
allowed at those positions) would be binding and guards.

If you want to play around with this syntax I attached a short patch
against trunk which implements this addition directly in the parser.
What do you think?

 

You can cut down a bit of the noise today with PartialFunction.cond

 

  scala> import PartialFunction.cond

  import PartialFunction.cond

 

  scala> if (cond(1) { case 2 => true }) {}

 

Or

 

  scala> def cond1[T](t: T)(pf: PartialFunction[T, Any]) = pf.isDefinedAt(t)

  cond1: [T](t: T)(pf: PartialFunction[T,Any])Boolean

 

  scala> if (cond1(1) { case 2 => }) {}

 

That said, I quite like the proposed syntax.

 

-jason

 



--
Alex REPAIN
ENSEIRB-MATMECA - student
TECHNICOLOR R&D - intern
BORDEAUX I      - master's student
SCALA           - enthusiast

 

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: Pattern match as boolean value

+1

This would also enable match-based assertions, as discussed on the list
not long ago.

Jeff Olson
Joined: 2011-06-29,
User offline. Last seen 42 years 45 weeks ago.
Re: Pattern match as boolean value
+1

I've wanted this many times. I would love to see language support for it. I second the suggestion to post over on the new scala-sips [at] googlegroups.com list.

@Adriaan: That's a awesome trick. Thanks.

-Jeff
HLKlaperman
Joined: 2011-05-31,
User offline. Last seen 47 weeks 1 day ago.
Re: Pattern match as boolean value
+1I third the suggestion to move to scala-sips.  Johannes, it's your suggestion, so you should be the one to post, if you wish.  :)
I would add that the danger in this proposal is that beginning Scala programmers might try to use the following Kotlinesque gibberish:
if (x match P1)  r1else if (x match P2)  r2[...]else  r0
in place of:
x match {  case P1 => r1  case P2 => r2  [...]  case _ => r0}
which is why I think this feature isn't already in the language.  It's a simple matter to fix this issue, however.  Just have the compiler emit a warning when it sees an if-else expression (yes, specifically one with an else branch) whose conditional is a match-test expression.  (We need a name to distinguish this match from the existing match statement as well, and a disambiguating name for the existing match.  Perhaps we could use x case P1 instead of x match P1 as the syntax for the proposed match-test expression; though this would have the disadvantage of not sounding right when read aloud.)

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland