OVO Tech Blog

Highlights from Scala Italy

Introduction

Gabriel Asman


Scala Functional programming

Highlights from Scala Italy

Posted by Gabriel Asman on .
Featured

Scala Functional programming

Highlights from Scala Italy

Posted by Gabriel Asman on .

Through an unexpected series of events, I found myself travelling to Florence to attend Scala Italy 2018 (14-15th September). The conference has been going on for a few years. This was my first time attending and the first year it was organized in Florence. These are a few of the highlights from the conference. Keep in mind these are only some of the talks, the other talks were equally interesting and I encourage you to watch all of them once they’ve been uploaded.

Keynote - A Programming Language is its Community

Heather Miller spoke about the importance of open-source work as the shared infrastructure on which we all rely. Surveys have shown that the existence of open-source tools ranks as the leading criteria for developers considering a new programming language. While in recent years, the number of users of open-source projects has continued to grow, the number of contributors has stayed flat.

A lot of important projects are maintained by a worryingly small number of contributors (the so-called truck factor), usually in their spare time. One famous example is the case of OpenSSL. A few years ago, the internet woke to the sudden realization that OpenSSL, a library on which large swathes of the internet relies on for security, was being maintained by a single person.

Heather ended the talk, without prescribing particular solutions, but rather encouraging each of us to consider ways in which we can contribute to the various communities we belong to.

5 things you need to know about Scala compiler

Mirco Dotta showed us a few useful things to keep in mind about the Scala compiler:

  1. Build time is different from compilation time. Other steps of the build are: dependency resolution, formatter, setting evaluation, source generators. Consider using Coursier, an SBT plugin that downloads artifacts in parallel and gives better caching. No global lock!

  2. Whitebox macros type check 3 times. In a nutshell, whitebox macros are macros that are allowed to generate new types. Since they type check three times, it’s even more important to cache them, so you don’t derive the same instance multiple times

  3. Type checking should be 30% of compilation time, use compiler flag -verbose to see a breakdown. Usual suspects: macro expansion, implicit resolution (large implicit search space), and type tags. Use -Xlog-implicits to see which implicits have been rejected.

  4. The Typer/Parser Node Factor (TPNF) is the ratio between the size of parsed-scala code and type-checked scala code. Scala has more code-generation than other languages, should still be ~1.2.

  5. Scala compiler is single-threaded. A lot of compilers are, but slow-down in the improvement of hardware has increased demand for parallelism. As of Scala 2.12.6 we have multithreaded class file generation phase. Check out the experimental parallel compiler: Hydra.

The Future of Scala - Panel

The day ended with a panel consisting of Heather Miller, Luka Jacobowitz, Miles Sabin, Mirco Dotta and Ólafur Páll Geirsson, moderated by Jon Pretty. They discussed the future of Scala. Dotty will become Scala 3.0. The costs of transition will be minimized, by having the Scala 3.0 compiler consume Scala 2 code. Scalafix can also be used for automatic rewriting. Macros will be reworked and type classes are going to be a first-class language feature in Scala 3.

Ten Cool Things You can do With Scala 3

Jon Pretty built on the panel discussion with a presentation about new features that will be part of Scala 3

  • Enumerations: Scala 3 will provide enumerations as first-class language constructs. This will mean almost no boilerplate for defining enumeration types, including parameterized data types such as List or Option.
enum Color {
  case Red, Green, Blue
}
enum Option[+T] {
  case Some(x: T) 
  case None
}
  • Type Lambdas: Current syntax is horrible, as it was discovered through a combination of other features, rather than designed.
({ type T[A] = Map[Int, A] })#T // Scala 2
[A] => Map[Int, A] // Scala 3
  • Implicit Function Types: A new feature that allows the encoding of implicit arguments inside the function’s type itself. This allows you to avoid the boilerplate associated with repeatedly passing contextual information, not just at call-site (as implicit parameters do), but also at declaration site.
type Contextual[T] = implicit Context => T 
implicit val ctx: Context = ...
def f(x: Int): Contextual[Int] = ...
f(2)    // is expanded to f(2)(ctx)
  • Named Type Parameters: Self-explanatory. Importantly, allows partial specification of type parameters, allowing you to specify some of the types, while making use of the type inference for the rest.
def asEither[E, A](x: A): Either[E, A] = ...

val a = toRightEither[E = Error](7)
  • Erased Terms: Gives you the ability to mark arguments as erased. Erased arguments don’t exist at run-time, can not be used in the body of a function, and serve only as a compile-time constraint.
class MyClass[T] {
   def fooWithInt(implicit evidence: T =:= Int) = ... //Scala 2
   def fooWithInt(erased evidence: T =:= Int) = ... // Scala 3, parameter only exists at compile time
}
  • Dependant Function Types: At the moment, Scala has dependant types in methods, but these can not be easily turned into functions because there is no convenient way of describing their type.
trait Entry { type Key; val key: Key }
def extractKey(e: Entry): e.Key = e.key          // a dependent method
val extractor: (e: Entry) => e.Key = extractKey  // Scala 3: a dependent function value
  • Safer Equality: Self explanatory. At the moment, Scala has universal equality, like Java. A safer equality will disallow comparisons between incompatible types.

  • If-Then-Else: Groundbreaking stuff.

if 3 < 4 then "Yes" else "No" // Old syntax still available
  • Principled Meta Programming

Shared State in Pure FP: When a state monad won’t do

Fabio Labella talked about managing state when doing Functional Programming. The state monad, while a useful abstraction, can not handle shared state, the S => (A, S) abstraction being inherently sequential.

A better option is to use an effect - such as Cats-Effect IO - to suspend side-effectful computation, and Ref[F, A] to represent shared state. Ref is built on top of Java’s AtomicReference, providing primitive effectful operations out of the box (get, set, update, create). One can use Ref directly, or build more specialized abstractions on top of it - such as Counter.

The key point is that functional programming is valuable especially in big systems with shared state, where the guarantees of referential transparency - such as local reasoning - are most useful. When using Ref, the regions of state sharing are the same as the call graph.

Gabriel Asman

View Comments...