nescala 2014 roundup

by Hung Lin @hunglin

Who is @hunglin?

  • software engineer @ Audax Health
  • use Scala for about 2.5 years now
  • co-organizer of DC Scala meetup
  • was Java coder before turned
  • still trying to understand the gist of monad, macros, dependent types, ...

What is nescala?

  • nescala stands for North East Scala
  • every year around Feb/March time since 2011
    • 2011 @ NYC
    • 2012 @ Boston
    • 2013 @ Philly
    • 2014 @ NYC
  • speakers are
    • people from Typesafe
    • people from academia like EPFL
    • people from Twitter, Linkedin, Meetup, Tumblr, ...
    • cool kids of Scala communities

It's One of the Big Event in Scala Community

nescala 2014

  • March 1-2, 2014
  • Day 1:
    • 13 talks @ NYU
    • happy hours @ Foursquare HQ
  • Day 2:
    • unconference @ Meetup HQ

buzz words

  • Functional Programming
  • Type System
  • Scala Macros
  • sbt
  • streaming
  • Programming Languages Concepts
  • Finagle

1st talk: Scala's Type System

by Heather Miller

what's Scala's Type System?

abstract type members


trait Pet

class Cat extends Pet

class Person {
  type Pet
}

class Susan extends Person {
  type Pet = Cat
}
						
						
class Person[Pet]
class Susan extends Person[Cat]
						
Abstract Type Members v.s. Generic Type Parameters by Bill Venners

existential types


case class Fruit[T](val weight: Int, val tooRipe: T => Boolean)

class Farm {
  val fruit = new ArrayBuffer[Fruit[T] forSome { type T }]
}
						
you can leave some parts of your program unknown (unimplemented), and still type check it with different implementations for those unknown parts.

higher-kinded types (container types, type constructor)


trait C[M[_]] {   }
//C is higher-kinded type because it abstracts over type constructor M
						

implementation of functor in Scala


  trait GenericFunctor[->>[_, _], ->>>[_, _], F[_]] {
    def fmap[A, B](f: A ->> B): F[A] ->>> F[B]
  }

  trait Functor[F[_]] extends GenericFunctor[Function, Function, F] {
    final def fmap[A, B](as: F[A])(f: A => B): F[B] =
      fmap(f)(as)
  }

  trait Applicative[F[_]] extends Functor[F] {

    def pure[A](a: A): F[A]

    def apply[A, B](f: F[A => B]): F[A] => F[B]

    final def apply[A, B](fa: F[A])(f: F[A => B]): F[B] =
      apply(f)(fa)

    override def fmap[A, B](f: A => B): F[A] => F[B] =
      apply(pure(f))
  }
						
abstraction over abstractions

typeclasses (it's so 2013)


// typeclass:
trait Ordering[T] {
  def compare(x: T, y: T): Int
}
						

// typeclass instance:
implicit object intOrdering extends Ordering[Int] {
  def compare(x: T, y: T): Int = x - y
}
						

// usage:
def sort[T](s: Seq[T])(implicit evidence: Ordering[T]): Seq[T]
						

// use context bound to write less codes
def sort[T: Ordering](s: Seq[T]): Seq[T]
						
context bounds are type constructors, not types

type level programming

WAT?

EPFL interview question
(if you want to be Odersky's PhD student)

please implement a map, using scala compiler

let's define interface first:

  • input: types
  • output: types

how to do it?

  • define type level functions
  • apply those functions during type checking

use implicits for defining relations on types


class HasCapital[T <: Country, C <: City] {
  def capital: C
}

implicit val capitalOfFrance = new HasCapital[France, Paris]
implicit val capitalOfGermany = new HasCapital[Germany, Berlin]
implicit val capitalOfUK = new HasCapital[UK, London]
						

applying type level functions


def lookupCapital[T](implicit ic: HasCapital[T, C]): C = {
  println(s"the capital is ${ic.capital.toString}")
  ic.capital
}

val c = lookupCapital[France]
						
CanBuildFrom use the same trick to compute the best result type of combinators like map

dependent types
(cool kids' buzz word of 2014)

  • Types that includes logical propositions, for example, type safe key value store. The type of the key contains the type of the value.
  • shapeless library (HList) by Miles Sabin

Odersky's talk @ strangeloop 2013 The Trouble With Types

resources

May Your Data Ever Be Coherent

by Daniel Spiewak

def sumPairs(left: List[Int], right: List[Int]): Int = {
  if (left.isEmpty)
    0
  else
    (left.head + right.head) + sumPairs(left.tail + right.tail)
}
						
data can be incoherent

def pairInts(x: List[Int], y: List[Int]): List[(Int, Int)] = ???

def sumPairs(pairs: List[(Int, Int)]): Int = {
  if (pairs.isEmpty)
    0
  else {
    val (left, right) = pairs.head
    left + right + sumPairs(pairs.tail)
  }
}
						
code can be incoherent

def sumPairs(pairs: List[(Int, Int)]): Int = pairs match {
  case (left, right) :: tail =>
    left + right + sumPairs(tail)
  case Nil => 0	
}
						
compiler checks the data and code coherence

xs.length is bad and useless

length explode one datum into two
how do you do merge sort?
how do you do matrix operation?

take away:

  • constrain your representations
  • focus on data flow, not control flow
  • if you cannot constrain your data, constrain its origin (make it only come from one place

Summingbird

by Oscar Boykin

Macros v.s. Types

by Eugene Burmako

Functional Programming is Terrible

by Runar Bjarnason

WartRemover

by Brian McKenna

sbt 1.0

by Josh Suereth

and more

  • Learning Scalaz by Eugene Yokota
  • scalaz stream by Paul Chiusano
  • Better Living Through sbt @ Banno by Luke Amdor
  • GeoTrellis by Josh Marcus
  • what you see is what you get by Doug Tangren
  • Play2, Akka and WebSocket @ NYTimes by Victor Chan

Happy Hours @ Foursquare HQ

Day2: Unconference

  • rethink Scala Macros by Eugene Burmako @ EPFL
  • finagle by Moses Nakamura @ Twitter
  • scalaz
  • haskell
  • new libraries
  • new programming languages
  • and a lot, a lot more
nescala 2014 unconference grid

call for ACTIONS

  • We should participate
  • We should give talks
  • We should host
  • nescala 2011 @ NYC
  • nescala 2012 @ Boston
  • nescala 2013 @ Philly
  • nescala 2014 @ NYC

nescala 2015 @ DC

Questions?

  • anyone going to Scala Days 2014 @ Berlin?
  • anyone going to nescala 2015?