Common expansions of syntax sugars and anonymous functions

Constructors and Functions as a first class citizen

We know scala is a functional programming language, and it is designed by mathematician. According to wiki, Apply is applying a function to its arguments. In Java, you would commonly expect:

Tree t = new Tree(args)

But in Scala, a Tree(args) is actually Tree.apply(args) so apply method in Scala is the method you should override when you want to provide your functions as an object

object Tree {
  def apply[A](aseq: A*): Tree[A] = {
    ... // saved for brevity
  }
}
  • reference on stackoverflow
  • Quote from the above link:

    apply serves the purpose of closing the gap between Object-Oriented and Functional paradigms in Scala

How to use underscores

// ERROR: missing parameter type for expanded function
myStrings.foreach(println(_.toString))

it expands to:

myStrings.foreach(println(_ => _.toString))

it annoys the compiler because compiler does not know the type of _

  • reference on stackoverflow
  • Quote from it:

    The placeholder syntax for anonymous functions replaces the smallest possible containing expression with a function.

Pass Seq or List to vararg functions

There is a very example of when we need the varargs instead of Seq. A container is holding a type A, and its members are expecting type A as well:

class ContainerClass[+A] {
  def apply(aSeq: A*): ContainerClass[A] = ...
}

If we pass the seq to the apply function, it will actually infer the A to be the type of Seq[A], so we need the A, not the Seq[A]. We can use this call:

ContainerClass.apply(aseq: _*)

The compiler will pass A instead of Seq[A] to the function

Good online Scala material

Pattern matching

In Scala, pattern matching is a function too. The compiler will create anonymous function for us. The compiler needs to be able to tell the type of the arguments in the function.

The nice quotes:

{ case X(x) => ... } is a partial function, but the compiler still doesn't know what your input type is, except that it's a supertype of X. Normally this isn't a problem because if you're writing an anonymous function, the type is known from the context.

And the error we should learn from:

{case QualifiedType(preds, ty) =>
               t.ty = ty ;
               Some((emptyEqualityConstraintSet,preds)) }