Showing posts with label akka. Show all posts
Showing posts with label akka. Show all posts

Tuesday, June 30, 2015

Scala's conform idiom


This is an odd little fellow in akka.testkit.TestFSMRef:

class TestFSMRef[S, D, T <: Actor](
  system: ActorSystem,
  props: Props,
  supervisor: ActorRef,
  name: String)(implicit ev: T <:< FSM[S, D])

What is that <:< symbol? It turns out that it comes from Predef, thus:

  sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
  private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x }
  implicit def $conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]

The documentation says:

Requiring an implicit argument of the type `A <:< B` encodes the generalized constraint `A <: B`.

So, A is a subclass of B. Got it. But how is that enforced for each and every child/parent relationship?

Well, there is a single, implicit $conforms[A] lingering in the ether that insists that A is a superclass or same as A. That's what A <:< A is saying. This is using a type infix operator for syntactic sugar and is equivalent to <:<[A, A].

"A is a superclass or same as A"? This in itself is not terribly useful. However,  <:<[B, A] also must be possible if and only if B is a superclass of A because  <:< is contravariant in its first type (-From) and covariant it its second (+To). That is, <:<[B, A] is a subtype of <:<[A, A] so everything compiles.

So, going back to our original Akka code, the type T <:< FSM[S, D] is enforcing T being a subclass of FSM[S, D] by virtue of there implicitly existing T <:< T and the only way this is satisfied without compilation errors is T <: FSM[S, D].


Wednesday, September 17, 2014

Scala Crib Sheet #3

Scala for the busy Java programmer:

Type Aliasing

In Akka, you'll see this in the Actor object:

type Receive = PartialFunction[Any, Unit]

What this means is that where ever we see Receive we mean PartialFunction[Any, Unit]. This is type-aliasing much like in C where, for example, you see:

   typedef int jint;

This is from the OpenJDK's jni_x86.h where jint is defined as an int in Linux. 

Obviously, running in the JVM, Scala does not need to define the type of something like jint according to architecture. But it's more than a convenience. Scala has something called type members whose effect is a little like parameterized types but promises not to bloat as quickly as generics can.

"In Scala, the inner class is addressed using the expression Outer#Inner instead of Java's Outer.Inner. The '.' syntax is reserved for objects" [1]

Let's use a slightly modified version of Odersky's example [1] to illustrate this:

abstract class Food

class Grass extends Food {
  override def toString() = "grass"
}

class DogFood extends Food {
  override def toString() = "dog food"
}

abstract class Animal {
  type SuitableFood

  def eat(food : SuitableFood) = { 
    println(this.toString + " eats " + food.toString)
  }
}

class Dog extends Animal {
  type SuitableFood  = DogFood

  override def toString() = "dog"
}

class Cow extends Animal {
  type SuitableFood  = Grass

  override def toString() = "cow"
}

object Animals {

  def main(args : Array[String]) {
    val dog                     = new Dog
    val cow                     = new Cow
    val dogFood                 = new DogFood
    val grass                   = new Grass

    dog.eat(dogFood)
    cow.eat(grass)
  }

  def doEat(animal : Animal, food : Animal#SuitableFood) {
    /* This fails to compile with:

 found   : food.type (with underlying type com.phenry.scala.Animal#SuitableFood)
 required: animal.SuitableFood 

    */

    animal.eat(food) // <-- does not compile!
  }
}

The same effect can be achieved with Java generics but that can be subverted via erasure. This appears more solid. More information can be found here.


Emptiness

There are a few ways to represent nothingness in Scala and a good description lives here and here. The main points are that null is just like Java, Nil is an empty List and Unit is just like Java's void.

This last one is interesting. There is only one way to have an instance of Unit and it's represented as (). It's an actual reference (unlike java.lang.Void which cannot be instantiated due to its private constructor) and can be used like this:

  def takesVoidToString(arg: () => String) : Unit = { 
    println("called with " + arg()) 
  }

  def main(arg : Array[String]) = {
    def fnTakesVoidReturnsString() = "fnTakesVoidReturnsString"
    takesVoidToString(fnTakesVoidReturnsString)
.
.

which in this case prints out:

called with fnTakesVoidReturnsString

Here our function takesVoidToString takes another function that in turn takes no arguments and just returns a String. By calling arg() we implicitly call fnTakesVoidReturnsString's apply method. Without the (), we'd see arg's toString method called and see that it is a Function0.

A note on syntax can be found here.

Finally, Nothing can be used when a function does not terminate properly. For example:

scala> def fnThrowsException = throw new UnsupportedOperationException
fnThrowsException: Nothing

That is, the REPL is telling us the return type of fnThrowsException is Nothing.


Partial Application of Functions in Scala

The syntax for a function that can be partially applied looks like this:

  def canBePartiallyApplied(count : Int)(f : Int => Int) { // this compiles but we'd like syntactic sugar: (f : Function1[Int, Int])
    for (i <- 1 to count) {
      println(f(i))
    }
  }

And we call it thus:

    def g(x : Int) = x + 1
    def partiallyApplied = app.canBePartiallyApplied(3)(_)
    partiallyApplied(g)

Note the underscore to indicate that we'll be filling that in later. This is similar but different to currying. The idea of currying takes one argument and returns a function. Partial application takes two arguments (but also returns a function). See here for more information.


Scala Hierarchy

Absolutely everything extends Any.

The Scala equivalents of primitives in Java extends AnyVal. All other types extend AnyRef.

Null is the base class for all  AnyRef.

Nothing is the base class for Null and all AnyVal.


Terminology

"Anonymous functions in source code are called function literals" [1].



Monday, September 15, 2014

Scala Crib Sheet #2

More Scala for Java programmers:

Case statements as functions

In Akka's sample.hello.HelloWorld:

  def receive = {
    // when the greeter is done, stop this actor and with it the application
    case Greeter.Done => context.stop(self)
  }

"Case sequences as partial functions: A sequence of cases (i.e. alternatives) in curly braces can be used anywhere a function literal can be used. Essentially, a case sequence is a function literal, only more general." [1]

Partial Functions

Not to be confused with partially applied functions, this borrows from the mathematical concept of a partial function where not all values in the domain map to other values (this contrasts with a total function). An example of a partial function in mathematics is the log function over all real numbers. Clearly, negative real numbers do not map to any real numbers.

Following on from the idea above of case statements as more generalized functions, then a case statement that does not cover every eventuality is a partial function. The Scala compiler will issue a warning but will not abort compilation of this (although you might get runtime errors).

Taking this example in the Scala docs:

    val isEven: PartialFunction[Int, String] = {
        case x if x % 2 == 0 => { println(x) ; x+" is even" }
    }

we can see that this is indeed a partial function as it doesn't return anything in the event x is odd.

All the other nice functionality that Scala gives you for this class is added by the compiler. For instance, I didn't implement the isDefinedAt function but the compiler did it for me:

$ javap -c ./target/scala-2.10/classes/com/phenry/scala/MyScala\$\$anonfun\$1.class
.
.
  public final boolean isDefinedAt(int);
    Code:
       0: iload_1       
       1: istore_2      
       2: iload_2       
       3: lookupswitch  { // 0
               default: 12
          }
      12: iload_2       
      13: iconst_2      
      14: irem          
      15: iconst_0      
      16: if_icmpne     23
      19: iconst_1      
      20: goto          24
      23: iconst_1      
      24: ireturn 
.
.

which when JADed, becomes:

    public final boolean isDefinedAt(int x1)
    {
        int i = x1;
        boolean flag;
        if(i % 2 == 0)
            flag = true;
        else
            flag = false;
        return flag;
    }


Type parameter hints

In Akka's sample.hello.HelloWorld:

    // create the greeter actor
    val greeter = context.actorOf(Props[Greeter], "greeter")

which calls:

  /**
   * Scala API: Returns a Props that has default values except for "creator" which will be a function that creates an instance
   * of the supplied type using the default constructor.
   */
  def apply[T <: Actor: ClassTag](): Props = apply(defaultDeploy, implicitly[ClassTag[T]].runtimeClass, List.empty)


Unlike Java, Scala can instantiate objects from type parameters. "What's required here is that you help the compiler by providing a runtime hint of what the actual type parameter is ... This means following the type with a a colon and the class name ClassManifest."  [1]. Since Programming in Scala was published, this ClassManifest has been deprecated in favour of ClassTag which is what we see here. It carries the type information that was erased at compile time.

This adding of an implicit parameter is called a context bound.

"Implicits in subclasses and subobjects take precedence over implicits in base classes." [1]

[1] Programming in Scala, Odersky.