Consider a login component which can send events of a custom type LoginEvent. That's how we would write the code to work with it in Java style:
val prompt = new LoginPrompt()
prompt.addListener( new Listener {
def componentEvent(event: Event) {
if(event.isInstanceOf[LoginEvent]) {
try {
AccessController.login(event.asInstanceOf[LoginEvent].credentials)
} catch {
case NonFatal(e) => log.error("Could not login", e)
}
}
}
That is terrible, is not it? Would not it be more readable this way:
val prompt = new LoginPrompt()
prompt.addListener(newListener {
case event: LoginEvent => AccessController.login(event.credentials)
})
And indeed we can achieve that if we put this sort function in scope:
def newListener[U](pf: PartialFunction[Event, U]) = {
new Listener {
def componentEvent(event: Event) {
try {
if (pf isDefinedAt event) pf(event)
} catch {
case NonFatal(e) => log.error(s"Listener function $pf failed ", e)
}
}
}
}
Now we can add new listeners as small and concise Scala pattern match expression. See how those are fully type safe and we did not write that ugly "isInstanceOf" or "asInstanceOf" calls.
I love Scala...