14

I start reading Lift framework source code, I find that there're so many methods are defined using a name like methodName_? , is there a convention that _? has some special meaning?

def empty_? : Boolean = {}
Sawyer
  • 15,581
  • 27
  • 88
  • 124
  • Similar question: http://stackoverflow.com/questions/1598410/use-of-special-characters-in-function-names – aioobe Dec 04 '10 at 15:36

2 Answers2

26

You're unlikely to see the construct outside of the lift framework; I suspect that it's mostly Ruby-envy.

Almost any other Scala project will shy away from this syntax. Not because of the trailing question mark, but because it's yet another way to introduce underscores into your code - and the symbol is already far too heavily overloaded.

Based on an evaluation of multiple Scala projects, the notation can be reasonably described as non-idiomatic.

UPDATE

The reason that the underscore is required is to disambiguate from infix notation, in which:

x?y

would be read as

x.?(y)

with ? being a method name. Whereas:

x_?y

Clearly demarks x_? as being atomic.

The syntax is an example of what is formally known as a "mixed identifier", and is intended to allow definitions such as

def prop_=(v:String) = ... //setter
def unary_- = ... //prefix negation operator

It could (arguably) be considered a hack when similar construct is used simply to shove a question mark at the end of a method name.

Kevin Wright
  • 49,540
  • 9
  • 105
  • 155
  • 3
    "the symbol is already far too heavily overloaded" As a separate token, sure, but not inside identifiers. – Alexey Romanov Dec 04 '10 at 15:45
  • 3
    @Alexey Romanov: Still, this goes against the Scala convention of using CamelCase and dromedaryCase in identifiers. – Fred Foo Dec 04 '10 at 15:47
  • Yeah, too much underscores in Scala source code. In Lift, there're underscores everywhere like : ParsePath(List("account", acctName), _ , _ ,_ ) , _ , _ ) , you have to write tons of ParsePath like this. – Sawyer Dec 04 '10 at 15:48
  • 2
    @larsmans It goes against the whole reason for allowing composite identifiers into Scala in the first place! – Kevin Wright Dec 04 '10 at 15:55
  • 6
    Major +1 to this answer. I was going to post something similar, but you beat me to it. In general, Lift (and related modules) is the only Scala framework which uses this convention. It also uses the `_!` suffix for "dangerous" methods (e.g. `open_!` on `Box`). In general, mixed alpha-symbolic identifiers are idiomatically discouraged in Scala with the exception of `_=` on mutators. Instead of `_?`, you should use the Java convention of `is...` except for raw properties, which should just be the property name (e.g. `visible`, rather than `isVisible`). – Daniel Spiewak Dec 04 '10 at 21:10
  • 2
    It would be nice to clearly state "there is no sugar related to method_?, incontrast with method_=". – pedrofurla Dec 05 '10 at 12:20
25

The ? denotes that this is a predicate, a function returning Boolean. This convention goes back to Lisp, where ? (Scheme), p or -p (other Lisps, simulating the question mark with a "similar" letter) also denote predicates. Think of it as asking a question, "is the object empty?"

Scala will only allow mixed identifier names (containing alphanumerics and punctuation) if you separate them by _. E.g.,

scala> def iszero?(x : Int) = x == 0 
<console>:1: error: '=' expected but identifier found.
       def iszero?(x : Int) = x == 0
                 ^

doesn't work, but

scala> def iszero_?(x : Int) = x == 0          
iszero_$qmark: (x: Int)Boolean

does.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836