Why do people use _? as an identifier suffix?
Asked Answered
B

2

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 = {}
Bellyband answered 4/12, 2010 at 15:31 Comment(1)
Similar question: #1598910Frankfort
E
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.

Edeline answered 4/12, 2010 at 15:37 Comment(2)
Read the question too quickly. I've deleted mine and voted this one up.Actino
BTW. it does not make sense in Scala - docs.scala-lang.org/style/…Wan
C
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.

Cottonseed answered 4/12, 2010 at 15:42 Comment(6)
"the symbol is already far too heavily overloaded" As a separate token, sure, but not inside identifiers.Hypsometry
@Alexey Romanov: Still, this goes against the Scala convention of using CamelCase and dromedaryCase in identifiers.Edeline
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.Bellyband
@larsmans It goes against the whole reason for allowing composite identifiers into Scala in the first place!Cottonseed
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).Verein
It would be nice to clearly state "there is no sugar related to method_?, incontrast with method_=".Infract
E
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.

Edeline answered 4/12, 2010 at 15:37 Comment(2)
Read the question too quickly. I've deleted mine and voted this one up.Actino
BTW. it does not make sense in Scala - docs.scala-lang.org/style/…Wan

© 2022 - 2024 — McMap. All rights reserved.