Partially applied function

A partially applied function is an expression in which you don't supply all of the arguments needed by the function. Instead, you supply some, or none, of the needed arguments. For example, to create a partially applied function expression involving sum,
scala> def sum(a: Int, b: Int, c: Int) = a + b + c
sum: (a: Int,b: Int,c: Int)Int
in which you supply none of the three required arguments, you just place an underscore after "sum". The resulting function can then be stored in a variable. Here's an example:
scala> val a = sum _
a: (Int, Int, Int) => Int = 
Read more: Partially applied functions

functions partially applied functions


Repeated parameters

Scala allows you to indicate that the last parameter to a function may be repeated. This allows clients to pass variable length argument lists to the function. To denote a repeated parameter, place an asterisk after the type of the parameter. For example:
  scala> def echo(args: String*) = 
           for (arg <- args) println(arg)
  echo: (String*)Unit
Defined this way, echo can be called with zero to many String arguments:
  scala> echo()
  scala> echo("one")
  scala> echo("hello", "world!")
Read more: Repeated parameters


Passing repeated parameters

The type of the repeated parameter inside the function is an Array of the declared type of the parameter. Nevertheless, if you have an array of the appropriate type, and attempt to pass it as a repeated parameter, you'll get a compiler error:

  scala> val arr = Array("What's", "up", "doc?")
  arr: Array[java.lang.String] = Array(What's, up, doc?)
  scala> echo(arr)
  :7: error: type mismatch;
   found   : Array[java.lang.String]
   required: String
To accomplish this, you'll need to append the array argument with a colon and an _* symbol, like this:

  scala> echo(arr: _*)
This notation tells the compiler to pass each element of arr as its own argument to echo, rather than all of it as a single argument.
Read more: Repeated parameters



Tail recursion optimization

Scala optimizes the tail recursive call:
def bang(x: Int): Int = 
  if (x == 0) throw new Exception("bang!")
  else bang(x - 1)
scala> bang(5)
java.lang.Exception: bang!
      at .bang(<console>:5)
      at .<init>(<console>:6)
Scala only optimizes directly recursive calls back to the same function making the call. If the recursion is indirect, no optimization is possible:
def isEven(x: Int): Boolean =
  if (x == 0) true else isOdd(x - 1)
def isOdd(x: Int): Boolean =
  if (x == 0) false else isEven(x - 1)
You also won't get a tail-call optimization if the final call goes to a function value.
val funValue = nestedFun _
def nestedFun(x: Int) { 
  if (x != 0) { println(x); funValue(x - 1) }
Read more: Tail recursion



Currying example

Consider the following curried function:
def curriedSum(x: Int)(y: Int) = x + y
There is a way to get an actual reference to curriedSum’s “second” function. You can use the placeholder notation to use curriedSum in a partially applied function expression, like this:
scala> val onePlus = curriedSum(1)_
onePlus: (Int) => Int = <function1>
The underscore in curriedSum(1)_ is a placeholder for the second parameter list. The result is a reference to a function that, when invoked, adds one to its sole Int argument and returns the result:
scala> onePlus(2)
res7: Int = 3
Read more: Currying

higher-order functions currying


Curly braces instead of parentheses

In any method invocation in Scala in which you're passing in exactly one argument, you can opt to use curly braces to surround the argument instead of parentheses.
For example, instead of:
  scala> println("Hello, world!")
  Hello, world!
You could write:
  scala> println { "Hello, world!" }
  Hello, world!
This curly braces technique will work, however, only if you're passing in one argument. Here's an attempt at violating that rule:
  scala> val g = "Hello, world!"
  g: java.lang.String = Hello, world!
  scala> g.substring { 7, 9 }
  <console>:1: error: ';' expected but ',' found.
         g.substring { 7, 9 }
Read more: Writing new control structures


Scala namespaces for definitions

Scala has just two namespaces for definitions in place of Java’s four. Java’s namespaces are fields, methods, types, and packages. Scala’s namespaces are:
• values (fields, methods, packages, and singleton objects)
• types (class and trait names)

In Scala it is forbidden to define a field and method with the same name in the same class, whereas it is allowed in Java.
This Java class would compile just fine:

class CompilesFine {
  private int f = 0;
  public int f() {
    return 1;
But the corresponding Scala class would not compile:
class WontCompile {
  private var f = 0
  def f = 1
The reason Scala places fields and methods into the same namespace is precisely so you can override a parameterless method with a val.
Source: Overriding methods and fields


Overriding methods and fields

In Scala, fields and methods belong to the same namespace. This makes it possible for a field to override a parameterless method. For instance, you could change the implementation of contents in class ArrayElement from a method to a field without having to modify the abstract method definition of contents in class Element
abstract class Element {
  def contents: Array[String]

class ArrayElement(conts: Array[String]) extends Element {
  val contents: Array[String] = conts
Field contents (defined with a val) in this version of ArrayElement is a perfectly good implementation of the parameterless method contents (declared with a def) in class Element.
Source: Overriding methods and fields



@switch annotatition

An annotation to be applied to a match expression. If present, the compiler will verify that the match has been compiled to a tableswitch or lookupswitch and issue an error if it instead compiles into a series of conditional expressions.

Example usage:

val Constant = 'Q'
def tokenMe(ch: Char) = (ch: @switch) match {
  case ' ' | '\t' | '\n'  => 1
  case 'A' | 'Z' | '$'    => 2
  case '5' | Constant     => 3  // a non-literal may prevent switch generation: this would not compile
  case _                  => 4
Note: for pattern matches with one or two cases, the compiler generates jump instructions. Annotating such a match with @switch does not issue any warning.
Scala Documetation

match expression pattern matching switch tableswitch lookupswitch


Best practices: MUST NOT use "return"

The return statement from Java signals a side-effect - unwind the stack and give this value to the caller. In a language in which the emphasis is on side-effect-full programming, this makes sense. However Scala is an expression-oriented language in which the emphasis is on controlling/limiting side-effects and return is not idiomatic.
To make matters worse, return probably doesn't behave as you think it does.
A return statement inside a nested anonymous function is implemented by throwing and catching a NonLocalReturnException.
Besides, return is anti-structural programming, as functions can be described with multiple exit points and if you need return, like in those gigantic methods with lots of if/else branches, the presence of a return is a clear signal that the code stinks, a magnet for future bugs and is thus in urgent need of refactoring.
Read more

return type return statement best practices

Loading rules...
Sign Up Now
or Subscribe for future quizzes