scala-fp

scala-fp

  • Book
  • GitHub

›Scala

Book

  • Table of contents

Scala

  • Introduction
  • JVM
  • TODO

Functional Programming

  • Introduction
  • Advanced
  • Ecosystem
  • More

Other

  • Haskell
  • Math

Introduction

Resources

  • Programming in Scala (2016)(3rd) by Martin Odersky, Lex Spoon, and Bill Venners (Book)
  • Scala High Performance Programming (2016) by Vincent Theron, Michael Diamant (Book)
  • Scala Puzzlers
  • Tour of Scala (Documentation)
  • Scala Improvement Proposals
  • Twitter Scala School
  • S-99: Ninety-Nine Scala Problems
  • Scala Exercises
  • Scala for Project Euler
  • Scala Collections performance characteristics
  • The Neophyte's Guide to Scala
  • Scala Compiler Phases with Pictures
  • Most Useful Resources For Learning Scala

Related projects

  • sbt - The interactive build tool
  • Dotty - A next-generation compiler for Scala
  • Scaladex - The Scala Library Index
  • ScalaFiddle - An online playground for creating, sharing and embedding Scala fiddles
  • Scastie - Scastie is an interactive playground for Scala with support for sbt configuration
  • Ammonite - Scala Scripting
  • Scala Native - An optimizing ahead-of-time compiler and lightweight managed runtime
  • Scala.js - Optimizes Scala code into highly efficient JavaScript

FAQ

What is the Scala hierarchy?

scala-hierarchy

What is the difference between by-name and by-value parameters?

A by-value parameter is evaluated before the method is invoked e.g. (x: Int) while a by-name parameter is not evaluated before the method is invoked, but each time the parameter is referenced inside the method e.g. (x: => Int)

What is the difference between eager, lazy and memoized evaluation?

  • Eager computations happen immediately
  • Lazy computations happen on access
  • Memoized computations are run once on first access, after which the results are cached

What are the differences between def val lazy var?

  • def defines a method, it is lazy and not memoized
  • val defines a fixed value, it is immutable, eagerly initialized and memoized
  • lazy val is only initialised when required and as late as possible (deferred evaluation), it is not recomputed like by-name parameters i.e. it's lazy and memoized
  • var defines a variable reference, it is mutable and should be avoided

What are Nothing Nil None Empty Null null Unit?

  • Nothing is a trait that is the bottom subtype of every subtype of Any
  • Nil is an empty list that is defined as a List[Nothing]
  • None is an empty option that is defined as a Option[Nothing]
  • Null is a trait and is the bottom type similar to Nothing but only for AnyRef not AnyVal
  • null is an instance of the Null trait
  • Unit is a subtype of AnyVal, it's only value is () and it is not represented by any object in the underlying runtime system. A method with return type Unit is analogous to a Java method which is declared void

What good are right-associative methods?

All methods whose names end in : are right-associative. That is, the expression x :: xs is actually the method call xs.::(x) , which in turn calls the data constructor ::(x, xs)

What is type inference?

  • Type inference (Documentation)

The compiler can often infer the type of an expression so you don't have to declare it explicitly

val myInt = 8
// myInt: Int = 8
val myString = "hello"
// myString: String = "hello"

What is a companion object?

  • Singleton Objects (Documentation)
  • How to override apply in a case class companion?

An object is a class that has exactly one instance. It is created lazily when it is referenced, like a lazy val. An object with the same name as a class is called a companion object. A companion class or object can access the private members of its companion

static members in Java are modeled as ordinary members of a companion object in Scala

What does it mean reify a trait?

You can't call functions on a trait, so you need to create a concrete instance of that trait before you do anything else. This technique is common with the modular programming approach, and it's known as reifying the trait. The word reify is defined as "Taking an abstract concept and making it concrete"

trait MyTrait {
  def myMethod = "hello"
}

object MyTrait extends MyTrait

MyTrait.myMethod
// res0: String = "hello"

What is the relationship between currying and partially applied function?

  • Currying (Documentation)
  • Partially-Applied Functions (and Currying) in Scala
  • How to use partially applied functions in Scala

Currying is a means of transforming a function that takes more than one argument into a chain of calls to functions, each of which takes a single argument

When you call a function that has parameters, you are said to be applying the function to the parameters. When all the parameters are passed to the function, you have fully applied the function to all of the parameters. But when you give only a subset of the parameters to the function, the result of the expression is a partially applied function

When a method is called with a fewer number of parameter lists, then this will yield a function taking the missing parameter lists as its arguments

val sum = (a: Int, b: Int, c: Int) => a + b + c
// sum: (Int, Int, Int) => Int = <function3>

// fully applied function
sum(1, 2, 3)
// res1: Int = 6

// partially applied function
val f = sum(1, 2, _: Int)
// f: Int => Int = <function1>

f(3)
// res2: Int = 6
def curry[A, B, C](f: (A, B) => C): A => (B => C) = ???
def uncurry[A, B, C](f: A => B => C): (A, B) => C = ???

What is a variadic function?

A variadic function accepts zero or more arguments. It provides a little syntactic sugar for creating and passing a Seq of elements explicitly. The special _* type annotation allows to pass a Seq to a variadic method

sealed trait MyList[+A]
case object MyNil extends MyList[Nothing]
case class MyCons[+A](head: A, tail: MyList[A]) extends MyList[A]

object MyList {
  def apply[A](list: A*): MyList[A] =
    if (list.isEmpty) MyNil
    else MyCons(list.head, apply(list.tail: _*))
}

MyList()
// res3: MyList[Nothing] = MyNil
MyList("a", "b")
// res4: MyList[String] = MyCons(
//   head = "a",
//   tail = MyCons(head = "b", tail = MyNil)
// )
MyList(1, 2, 3)
// res5: MyList[Int] = MyCons(
//   head = 1,
//   tail = MyCons(head = 2, tail = MyCons(head = 3, tail = MyNil))
// )

What is type ascription?

  • Ascription (Documentation)

Ascription is basically just an up-cast performed at compile-time for the sake of the type checker

What is covariance and contravariance?

  • Covariance and contravariance in Scala
  • The Scala Type System: Parameterized Types and Variances
  • Cheat Codes for Contravariance and Covariance

Variance relates to subtypes i.e. B is a subtype of A if we can use a value of type B anywhere we expect a value of type A. Covariance and contravariance annotations arise when working with type constructors

Covariance means that the type F[B] is a subtype of the type F[A] if B is a subtype of A

trait F[+A]

// example
trait List[+A]
trait Option[+A]

Contravariance means that the type F[B] is a subtype of F[A] if A is a subtype of B

trait F[-A]

Invariance means the types F[A] and F[B] are never subtypes of one another, no matter what the relationship between A and B. This is the default semantics for Scala type constructors

trait F[A]

What is autoboxing?

  • Autoboxing and Unboxing

The JVM defines primitive types (boolean, byte, char, float, int, long, short and double) that are stack-allocated rather than heap-allocated. When a generic type is introduced, for example, scala.collection.immutable.List, the JVM references an object equivalent, instead of a primitive type. For example, an instantiated list of integers would be heap-allocated objects rather than integer primitives.

The process of converting a primitive to its object equivalent is called boxing, and the reverse process is called unboxing. Boxing is a relevant concern for performance-sensitive programming because boxing involves heap allocation. In performance-sensitive code that performs numerical computations, the cost of boxing and unboxing can can create significant performance slowdowns

What is the @specialized annotation?

  • Avoiding unnecessary object instantiation with specialized generics
  • Quirks of Scala Specialization

Specialization with @specialized annotation, refers to the compile-time process of generating duplicate versions of a generic trait or class that refer directly to a primitive type instead of the associated object wrapper. At runtime, the compiler-generated version of the generic class (or, as it is commonly referred to, the specialized version of the class) is instantiated.

This process eliminates the runtime cost of boxing primitives, which means that you can define generic abstractions while retaining the performance of a handwritten, specialized implementation

What is the @switch annotation?

In scenarios involving simple pattern match statements that directly match a value, using @switch annotation provides a warning at compile time if the switch can't be compiled to a tableswitch or lookupswitch which procides better performance, because it results in a branch table rather than a decision tree

What is the @inline annotation?

  • The Scala 2.12 and 2.13 Inliner and Optimizer

An annotation on methods that requests that the compiler should try especially hard to inline the annotated method

Inlining a function means that instead of having a function call resulting in parameters being placed on the stack and an invoke operation occurring, the definition of the function is copied at compile time to where the invocation was made, saving the invocation overhead at runtime

To enable this feature you need to explicitly set the -optimize compiler flag

What is a value class?

  • Value classes (Documentation)

The AnyVal class can be used to define a value class, which is optimized at compile time to avoid the allocation of an instance

final case class Price(value: BigDecimal) extends AnyVal {
  def lowerThan(p: Price): Boolean = this.value < p.value
}

TODO What is a sealed trait?

TODO

  • Everything You Ever Wanted to Know About Sealed Traits in Scala
  • More on Sealed Traits in Scala

What is the difference between foldLeft and foldRight?

  • foldLeft traverses from left to right (start to finish)
  • foldLeft definition def foldLeft[B](z: B)(f: (B, A) => B): B
List(1, 2, 3).foldLeft("nil")((accumulator, item) => s"($item operation $accumulator)")
// res6: String = "(3 operation (2 operation (1 operation nil)))"

List(1, 2, 3).foldLeft(List.empty[Int])((a, i) => i :: a)
// res7: List[Int] = List(3, 2, 1)
  • foldRight traverses from right to left (finish to start)
  • foldRight definition def foldRight[B](z: B)(f: (A, B) => B): B
List(1, 2, 3).foldRight("nil")((item, accumulator) => s"($item operation $accumulator)")
// res8: String = "(1 operation (2 operation (3 operation nil)))"

List(1, 2, 3).foldRight(List.empty[Int])((i, a) => i :: a)
// res9: List[Int] = List(1, 2, 3)
  • foldLeft and foldRight are equivalent if the binary operation is associative - see Monoid

TODO What is string interpolation?

  • Scala String Interpolation
← Table of contentsJVM →
  • Resources
  • Related projects
  • FAQ
    • What is the Scala hierarchy?
    • What is the difference between by-name and by-value parameters?
    • What is the difference between eager, lazy and memoized evaluation?
    • What are the differences between def val lazy var?
    • What are Nothing Nil None Empty Null null Unit?
    • What good are right-associative methods?
    • What is type inference?
    • What is a companion object?
    • What does it mean reify a trait?
    • What is the relationship between currying and partially applied function?
    • What is a variadic function?
    • What is type ascription?
    • What is covariance and contravariance?
    • What is autoboxing?
    • What is the @specialized annotation?
    • What is the @switch annotation?
    • What is the @inline annotation?
    • What is a value class?
    • TODO What is a sealed trait?
    • What is the difference between foldLeft and foldRight?
    • TODO What is string interpolation?
scala-fp
Contribute
How toGitHub
Copyright © 2022 niqdev