4

I am learning Scala, and playing with right associate unapply object. I know that if the name ends with ':' then it becomes right associative. However, there seems to be some strange restrictions on the naming

e.g. These are invalid

object cons: { def unapply(value: String): Option[(Char, List[Char])] = ??? }
object :_cons_: { def unapply(value: String): Option[(Char, List[Char])] = ??? }

These are valid

object cons_: { def unapply(value: String): Option[(Char, List[Char])] = ??? }
object >>: { def unapply(value: String): Option[(Char, List[Char])] = ??? }

So there seems to be some weirdness about mixing alpha-numeric characters and symbols in identifiers.

So basically, I want to have a descriptive name i.e. 'cons' and still have right associativity. Also, I would like my operator to be symetric for aesthetic reasons :-), so I dont really like cons_:
Is there a way to make something associate to the right without using a colon? Or any other suggestions to achieve this?

:_cons_: seems to be the closest, but, for some reason the identifier can't start with ':' and have alphanumerics

tshepang
  • 12,111
  • 21
  • 91
  • 136
ekj
  • 1,082
  • 2
  • 11
  • 22

1 Answers1

3

From the spec (section 1.1):

There are three ways to form an identifier. First, an identifier can start with a letter which can be followed by an arbitrary sequence of letters and digits. This may be followed by underscore ‘_’ characters and another string composed of either letters and digits or of operator characters. Second, an identifier can start with an operator character followed by an arbitrary sequence of operator characters. The preceding two forms are called plain identifiers. Finally, an identifier may also be formed by an arbitrary string between back-quotes (host systems may impose some restrictions on which strings are legal for identifiers). The identifier then is composed of all characters excluding the backquotes themselves.

So it looks like you're out of luck—if your identifier starts with a : it can't contain non-operator characters. Note, though, that you can write the following (which isn't intended to do anything meaningful—just to demonstrate the syntax):

scala> class X { def `:cons:`(i: Int) = i }
defined class X

scala> val x = new X
x: X = X@6a665da6

scala> 1 `:cons:` x
res1: Int = 1

The method name still ends with a colon, so you get the right associativity you're looking for.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • Great! I didn't know about using back ticks to allow arbitrary identifiers. Thanks – ekj Aug 01 '13 at 12:54
  • The last character isn't a backquote, it's a colon. The quote characters in a quoted identifier no more become a part of the identifier than the quote characters in a string literal do. The last character of the string denoted by the string literal `"Hello"` isn't `"`, it's `o`. – Jörg W Mittag Aug 01 '13 at 13:39
  • @JörgWMittag: Wow, that was some incredible misreading on my part—the "excluding" is right there. In my defense it was early here and I was still a little bitter about [this](http://stackoverflow.com/q/17863794/334519). I've edited to remove my surprise that the backtick approach works. – Travis Brown Aug 01 '13 at 13:43