Let's first rewrite your example in more modern ECMAScript:
const add = x => y => x + y;
The Scala equivalent is very similar, it looks almost like this, the only difference is the val instead of const (although we could actually use var in both cases, and make the code truly identical):
// almost correct, but doesn't compile
val add = x => y => x + y
Except that doesn't work because Scala doesn't know what the types are, so we have to help just a little bit by either declaring the types of x and y, so Scala can properly infer the type of add or declare the type of add, so Scala can properly infer the types of the functions:
val add = (x: Int) => (y: Int) => x + y
// or
val add: Int => Int => Int = x => y => x + y
Scala also allows us to write them with a proper fat arrow if we want to:
val add = (x: Int) ⇒ (y: Int) ⇒ x + y
// or
val add: Int ⇒ Int ⇒ Int = x ⇒ y ⇒ x + y
So, as you can see, apart from the type declarations, the code is actually identical.
println(add(1)(2)) // 3
val increment = add(1)
val addTen = add(10)
increment(2) //=> 3
addTen(2) //=> 12
There is, however, another kind of currying in Scala, that is actually built into the language. In Scala, methods (which are different from functions) can have zero or more parameter lists, unlike most other languages (including ECMAScript) where there is always exactly one (potentially empty) parameter list. Methods that are defined with multiple parameter lists are called "curried" methods:
// this is a *method*, not a *function*, and thus different from the OP's example!
def addMeth(x: Int)(y: Int) = x + y
In Scala, we can convert a method into a function using η-expansion; this is written by placing an underscore after the name of the method:
// this converts the method `addMeth` into an anonymous function
// and assigns it to the variable `addFunc`
val addFunc = addMeth _
Now we can do the same things we did above using our curried addFunc function:
println(addFunc(1)(2)) // 3
val increment = addFunc(1)
val addTen = addFunc(10)
increment(2) //=> 3
addTen(2) //=> 12
But we can also use our addMeth method directly:
println(addMeth(1)(2)) // 3
val increment = addMeth(1) _
val addTen = addMeth(10) _
increment(2) //=> 3
addTen(2) //=> 12
So, unlike ECMAScript, Scala actually has a language built-in concept of currying, but
- not for functions, only for methods and
- not based on individual parameters but on parameter lists