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

A weird little syntax oddity

1 reply
DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
I spotted an amusing little syntax ambiguity. It's fairly minor, but I don't think the spec is clear on the behaviour, and it might be worth making it so.

Ok. So given a symbolic case class name, we can use it infix when matching:

scala> def stuff(x : Any) = x match { case "foo" -- "bar" => true; case _ => false; }
stuff: (Any)Boolean

scala> stuff("foo")
res11: Boolean = false

scala> stuff(--("foo", "bar") )
res12: Boolean = true

(Section 8.1.9 of the SLS).

But unfortunately there's one perfectly legitimate symbolic case class name for which this doesn't work:

scala> case class |(foo : String, bar : String);
defined class $bar

scala> def morestuff(x : Any) = x match { case "foo" | "bar" => true; case _ => false; }
morestuff: (Any)Boolean

scala> morestuff("foo")
res13: Boolean = true

scala> morestuff(|("foo", "bar"))
res14: Boolean = false

The problem is that | means something else for pattern matching, but it's also a completely legitimate case class name. The spec is silent on this fact, so it's easy to accidentally miss over (and possibly easy to get wrong when tinkering with the parser. Although presumably one would notice quite quickly that the entire world had broken. :-) )


Burak Emir
Joined: 2009-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: A weird little syntax oddity
Hey David,

would "foo" `|` "bar" work (using a backquoted identifier `|`)?

Burak

On Sun, Feb 15, 2009 at 11:57 PM, David MacIver <david [dot] maciver [at] gmail [dot] com> wrote:
I spotted an amusing little syntax ambiguity. It's fairly minor, but I don't think the spec is clear on the behaviour, and it might be worth making it so.

Ok. So given a symbolic case class name, we can use it infix when matching:

scala> def stuff(x : Any) = x match { case "foo" -- "bar" => true; case _ => false; }
stuff: (Any)Boolean

scala> stuff("foo")
res11: Boolean = false

scala> stuff(--("foo", "bar") )
res12: Boolean = true

(Section 8.1.9 of the SLS).

But unfortunately there's one perfectly legitimate symbolic case class name for which this doesn't work:

scala> case class |(foo : String, bar : String);
defined class $bar

scala> def morestuff(x : Any) = x match { case "foo" | "bar" => true; case _ => false; }
morestuff: (Any)Boolean

scala> morestuff("foo")
res13: Boolean = true

scala> morestuff(|("foo", "bar"))
res14: Boolean = false

The problem is that | means something else for pattern matching, but it's also a completely legitimate case class name. The spec is silent on this fact, so it's easy to accidentally miss over (and possibly easy to get wrong when tinkering with the parser. Although presumably one would notice quite quickly that the entire world had broken. :-) )





--
Burak Emir
--
http://burak.emir.googlepages.com

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