Jan Gorzny
Jan Gorzny

Reputation: 1772

Not sure what this Scala Syntax is doing

I'm fairly new to Scala and I was wondering what the following line of code is doing:

class E{
  val (a: A, b: B, c:C, d:D) = {
    ...
  }
}

Is it making an assignment (because of the val?) and then executing the body?

Upvotes: 0

Views: 103

Answers (3)

om-nom-nom
om-nom-nom

Reputation: 62855

It's execute the body, then destructure it's result:

val (a: A, b: B, c:C, d:D) = {
    ...
}

First, the body produces some result (which is expected to be tuple*), then this tuple broken down into it's elements, each element is assigned to a, b, c and d respectively.

You probably have seen this code in Java:

int x = 1, y = 2, z = 4;
// now x is 1, y is 2, z is 4

Or even this code in python:

>>> x, y = 1, 2
>>> x
1
>>> y
2

Scala takes this on the next level, with a feature called destructuring assignment, and while it doesn't allow Java and Python syntaxes, it's far more flexible because it allows you not only the similar experience (via using of tuples):

val (x, y) = (1, 2)

But also generalized and extensible concept of such use case of pattern matching, e.g. on arrays:

val xs = Array(1,2,3,4)
val Array(first, second, _*) = xs  // _* mean I don't care about the rest of elements
// first: Int = 1
// second: Int = 2

On lists:

val head::tail = List(1,2,3,4)
head: Int = 1
tail: List[Int] = List(2, 3, 4)

And in many other cases.

You may think that this operation somehow destroys original value, but usually it's not (unless custom extractor function is side-effecting)

* tuple is a kinda like immutable collection of finite known size, each element of it can be directly addressed which ._x method, like foo._1 for the first one, foo._2 for the second one. Tuples in scala has syntax sugar -- braces.

Upvotes: 3

cloud
cloud

Reputation: 1065

You can run scala -Xprint:parser -e "val (a, b) = (1, 2)" to desugar the code. What actually happened is:

val x$1 = (1, 2) match {
  case Tuple2((a @ _), (b @ _)) => Tuple2(a, b)
}
val a = x$1._1
val b = x$1._2

Upvotes: 2

ferk86
ferk86

Reputation: 2345

val defines a variable that cannot be reassigned. Then the (a, b, ..) notation exposes a tuple with values a, b, ... to be assigned.

Here's an example you can run:

// define types
type A = String
type B = String
type C = String
type D = String

// adding tuple@ to show a,b,c,d are components of a tuple aka extraction
val tuple@(a: A, b: B, c:C, d:D) = {
  ("aString", "bString", "cString", "dString")
}

println(tuple)

Additionally, you can specify types more explicitly such as

val tuple@(a: A, b: B, c:C, d:D): (A, B, C, D) = {
  ("aString": A, "bString": B, "cString": C, "dString": D)
}

And the output is:

defined type alias A
defined type alias B
defined type alias C
defined type alias D
tuple: (A, B, C, D) = (aString,bString,cString,dString)
a: A = aString
b: B = bString
c: C = cString
d: D = dString
(aString,bString,cString,dString)

Upvotes: 2

Related Questions