Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoking anonymous closure

Edit
ok, great feedback here, got me pointed in the right direction. Use case for invoking anonymous closure is in Scalatra routing layer. I have a bunch of routes that are grouped together under various types, in this example, requests common to teams:

class Router {
  type TeamType <: _Controller with _Team

  get("""(schedules|rosters|teamresults|teamstats)/\d{8}""".r) {
    val clazz :: date = captures

    val obj = (clazz match {
      case "schedules" => new RosterController
      case "rosters" => new ScheduleController
    }).asInstanceOf[TeamType]

    obj.show(date)
  }
}

By wrapping the match expression in a a self-invoked anonymous closure, we avoid tacking on "FooController.asInstanceOf[TeamType]" to each matched case, and instead do the type cast on returned instance, maintaining immutability in the process (i.e. could not "val obj = clazz match {...}" followed by type cast as obj has already been val'd)

I believe that this is as short-form as one can get when creating object instances based on string class name. Of course, saying that, there is likely an FP approach that does the job with even greater concision...

Anyway cool stuff, was missing anonymous closures from Groovy, and now I discover Scala has that covered as well ;-)

Original
Not sure how to pull this off in Scala. In Groovy you can both define and invoke an anonymous closure like so:

{String s-> println(s) }("hello")

What is the equivalent in Scala? Also, rather than returning Unit, how would one specify a return type?

Thanks

like image 632
virtualeyes Avatar asked Mar 05 '26 05:03

virtualeyes


2 Answers

((s : String) => println(s))("hello")

As for the return type, just let Scala infer it.

scala> ((x : Int) => x < 4)(3)
res0: Boolean = true
like image 128
Fred Foo Avatar answered Mar 07 '26 20:03

Fred Foo


To add to @larsmans's answer, you can have the Scala compiler infer argument types too. The Scala type inference flows from left to right, so you have to arrange the terms accordingly. We can do this by definiting a pipe-forward operator, |>, such that:

x |> f = f(x)

It's available in Scalaz. If you don't want to use Scalaz, it's not hard to define it yourself.

Usage example:

scala> "hello" |> { s => println(s) }
hello

scala> "hello" |> println
hello

scala> 3 |> { y => y < 4 }
res23: Boolean = true

scala> 3 |> { _ < 4 }
res24: Boolean = true
like image 45
missingfaktor Avatar answered Mar 07 '26 20:03

missingfaktor