Nabegh
Nabegh

Reputation: 3289

Scala map method syntax

The code below from http://www.scalaclass.com/book/export/html/1 to do matrix dot product.

I can't understand the syntax between the curly brackets.

Thanks.

type Row    = List[Double]
type Matrix = List[Row]

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ t:(Double, Double) => t._1 * t._2 }.reduceLeft(_ + _)

Upvotes: 28

Views: 39023

Answers (4)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297195

  • Why are the curly brackets used, not the regular method parentheses?

Some people prefer to use curly braces when the parameter is an anonymous function. For one thing, curly braces enable pattern matching anonymous functions, whereas parenthesis do not. In this particular example, there's no need for curly braces.

Here's an example where curly braces are required (because of the case pattern matching):

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ case (a, b) => a * b }.reduceLeft(_ + _)

Note that the above function accomplishes the same thing as the one in the question, in a slightly different way.

  • Is t an anonymous method?

No, it is a parameter. Just like v1 and v2 are parameters for dotProd, t is a parameter for the anonymous function being passed to map.

  • What is ._1 and ._2?

Methods on t. The parameter t was defined as being a tuple (specifically, Tuple2[Double, Double], which can be written as (Double, Double)), and tuples let you extract each member of the tuple with methods like that: _1, _2, _3, etc.

A Tuple2 only has _1 and _2, of course. Note that the first parameter is _1, not _0, because of influence from other functional languages.

Anyway, the zip method will convert Row (List[Double]) into a List[(Double, Double)]. The method map takes a function that converts the elements of the list (which are (Double, Double) tuples) into something else.

Upvotes: 39

Matthew Farwell
Matthew Farwell

Reputation: 61705

You can find a very good answer to the differences between braces {} and parentheses () in this question: What is the formal difference in Scala between braces and parentheses, and when should they be used?

For the _1, _2, see Meaning of _2 sign in scala language.

And yes, t:(Double, Double) => t._1 * t._2 is an anonymous function (not a method actually). Difference between method and function in Scala

Upvotes: 5

om-nom-nom
om-nom-nom

Reputation: 62835

In this particular case curly brackets have no advantage over plain old syntax, but in general the sweet thing about using curly brackets is that they allow you to write pattern matching expressions inside map ...:

so I can rewrite this

.map{ t:(Double, Double) => t._1 * t._2 }

into this

.map{ case(a: Double, b: Double) => a*b }

but this will not compile:

.map( case(a: Double, b: Double) => a*b )

._1, ._2 provides access to first, second, ... N element of N-tuple, as Lee said.

Upvotes: 22

Lee
Lee

Reputation: 144136

The curly brackets denote an anonymous function which has type Tuple2[Double,Double] => Double. The argument is given the local name t, so t is a tuple of two doubles.t._1 refers to the first item and t._2 the second.

Therefore map yields a list of the element-wise products of the components of the two vectors, and reduceLeft sums these products to calculate the dot product.

Upvotes: 1

Related Questions