sticking ? where it doesn’t belong
One fondness I have in common with Ruby, Clojure, and even Coffeescript is a syntactic idiom of ending the names of functions and methods that return a false value with a ?.
The idea is to immediately convey the intent of the function by means of an expectation you’ve developed reading natural language. When you read something that ends in a ?, you intuitively assume, without thinking, that sentence will result in a yes or no answer. Agree?
In Java land, the idiom is to prepend methods that return a boolean value with is. An example would be isJavaLike(). The idiomatic way in the languages listed above for expressing this would be javaLike?. I prefer predicate methods that end with ? because they read nicer and follow consistent rules. Let’s say you have a method is() in Java that returns a boolean value. If you wanted to be consistent you’d say isIs(). Chances are, you would break consistency and just stick with is() because isIs() just sounds silly. In the languages mentioned above, is? is idiomatically consistent and still readable.
flex time
In my spare time I like to whittle projects made of Scala. Scala is a super-flexible language that allows you to create fluent DSL’s by combining first class functions with a relatively open list of characters that you are free to use for method names.
The only complaint I have is that, while the method definition
def __^|(i: Int) = i % 2 == 0
is syntactically valid
def even?(i: Int) = i % 2 == 0
is not!
If you paste that in a Scala REPL you are likely to get this error
<console>:1: error: '=' expected but identifier found.
def even?(i: Int) = i % 2 == 0
^
Method names in Scala can not end with ?.
How displeasing. :/
Some Scala libraries like Lift have an awkward response to this grammar constraint. In Lift, it is idiomatic to end method names that return boolean values with _?. The even method above would be defined as even_? in Lift. This feels very awkward to me because there is a disconnect in consistency with the mixing of camelCase method names with snake_casing. Something about fooBarBaz_? just doesn’t feel right to me. Does it feelRight_toYou_?.
I should mention at this point that if you read the Variable Declarations and Deļ¬nitions section of the language spec you will see the use of def x_= (y: T ): Unit, suggesting the using of _ as suffix for mutating members. This has always felt awkward to me as well. In these cases, I prefer returning a new copy of type Foo given the method def x(y: T): Foo which retains the method name, unchanged, verses appending a _ and mutating the instance.
But I digress…
Well, Scala is a flexible language so of course there are ways to work around this.
And I’m not talking about something like
def `even?`(n: Int) = n % 2 == 0
In languages like Ruby, you can monkey patch a class. In Scala, you use types to implicitly decorate values.
My first thought was to do something like
implicit def questionable[T](b: Boolean) = new { def ? = b }
This will enable you decorate any expression that returns a boolean value with a ?.
So, you could say something like
if(true?) ...
But that flavoring doesn’t necessarily have the same sweetness to it with methods that take arguments.
if(even(3)?) ...
The ? must come after then expression.
Well then, how about
implicit def questionablefun[T](b: T => Boolean) = new { def ? = b }
def pred[T](f: T => Boolean)(t: T) = f(t)
Let’s hear if for first class functions and currying!
Given the tools above, we can now assign a curried function that returns a boolean to a value and end that with a ? prior to applying the second argument.
val even = pred((i: Int) => i % 2 == 0)_
if(even?(2)) ...
Ha. Take that silly syntax grammar rules!
Now, of course I would not recommend doing something like all that in a production environment, but it does put a smile on my face just knowing that I can. For the time being I will be content with neither is, ?, nor _? and just stick unadorned intention revealing method names with context
if(allElseFails(Seq(4, 8, 15, 16, 23, 42))) ...
Works for me.