3

I am still new to Scala. I found this code inside Spray framework.

I am trying to understand what the method signature means:

 /**
 * Completes the request using the given arguments.
 */
def complete: (⇒ ToResponseMarshallable) ⇒ StandardRoute = marshallable ⇒ new StandardRoute {
  def apply(ctx: RequestContext): Unit = ctx.complete(marshallable)
}

What does the => operator do here? I thought it was used for creating a closure? What is the assignment to marshallable being done here? why is it done outside the brackets?

A java version of this code would be nice to see.

pdeva
  • 43,605
  • 46
  • 133
  • 171
  • possible duplicate of [What does => and () => mean in Scala](http://stackoverflow.com/questions/6951895/what-does-and-mean-in-scala) – Chris Martin Mar 03 '15 at 08:46
  • no. as i mentioned i get that => means creating a closure. but i dont understand in the context of the signature here – pdeva Mar 03 '15 at 08:52
  • It also means other things, as explained in the second answer on that question. – Chris Martin Mar 03 '15 at 08:54
  • 1
    (Though the general case may be sufficiently covered in that question, this is actually pretty tricky to parse, I think. I'll try to answer it.) – Steve Waldman Mar 03 '15 at 08:56

1 Answers1

3

So.

The first thing to notice is that complete is declared with a def, so it is a method, but the parentheses that look like they might be method arguments come after the colon :.

So they are not in fact method arguments. complete is a no-argument method!

Then what's up with the parens after the colon?

(⇒ ToResponseMarshallable) ⇒ StandardRoute is the return type of the no-arg method complete. The function complete returns a function that accepts an expression of type ToResponseMarshallable and returns a StandardRoute.

OK. But then what's up with the arrow before ToResponseMarshallable in the function signature (⇒ ToResponseMarshallable) ⇒ StandardRoute?

In a function signature, an prior to the type name signifies a "call-by-name" argument. Following java, Scala by default evaluates all expressions in an argument list, and then evaluates the method body, substituting the evaluated values for the variable. But Scala also supports call-by-name semantics, in which an expression is substituted unevaluated into a function, and re-executed every time that it is named. complete returns a function whose single argument has call-by-name semantics.

Following the equals sign is just the implementation of this method. The expression beginning with marshallable ⇒ is an anonymous function, or function literal, or lambda (all names for basically the same thing). marshallable ⇒ "hello" would be a function that accepts (by name) a ToResponseMarshallable and returns the String "hello". But we need a method that accepts a ToResponseMarshallable (by name) and retuns a StandardRoute. So we have marshallable ⇒<expression that evaluates to a StandardRoute>

That <expression that evaluates to a StandardRoute> is just an anonymous inner class, an implementation of StandardRoute that overrides its apply method.

And we're done! We (hopefully) understand all the pieces, and what this declaration means.

Steve Waldman
  • 13,689
  • 1
  • 35
  • 45
  • you said, `complete` returns a function that accepts an expression of type StandardRoute, but doesn't the returned function *return* StandardRoute (instead of accepting it)? – pdeva Mar 03 '15 at 09:22
  • argh! yes. let me fix that and pretend it didn't happen. – Steve Waldman Mar 03 '15 at 09:24
  • that's, um, what i meant to say. – Steve Waldman Mar 03 '15 at 09:25
  • it's a long time since i've looked at Spray with any care. but it looks like `ToResponseMarshallable ` is just a handle on a thing that can be marshalled into an HTTP response. If the thing passed to the function returned by `complete` were something ordinarily passed back, XML or JSON or a plaintext String, i'm guessing there would be implicit conversions to `ToResponseMarshallable `. if you want to pass back special things, you'd have to define conversions. but i'm only guessing! (cf http://stackoverflow.com/questions/28130260/required-spray-httpx-marshalling-toresponsemarshallable-error) – Steve Waldman Mar 03 '15 at 09:43