Tag Archives: scala

Implicit Conversion In Scala

These days, software engineers with knowledge of robust frameworks/libraries are abundant, but those who fully command the core basics of a language platform remain scarce. When required to come up with coding solutions to perform, scale or resolve tricky bugs, a good understanding of the programming language’s core features is often the real deal.

Scala’s signature strengths

Having immersed in a couple of R&D projects using Scala (along with Akka actors) over the past 6 months, I’ve come to appreciate quite a few things it offers. Aside from an obvious signature strength of being a good hybrid of functional programming and object-oriented programming, others include implicit conversion, type parametrization and futures/promises. In addition, Akka actors coupled with Scala make a highly scalable concurrency solution applicable to many distributed systems including IoT systems.

In this blog post, I’m going to talk about Scala’s implicit conversion which I think is part of the language’s core basics. For illustration purpose, simple arithmetics of complex numbers will be implemented using the very feature.

A basic complex-number class would probably look something like the following:

class Complex(r: Double, i: Double) {
  val re: Double = r
  val im: Double = i
  override def toString =
    ...
  // Methods for arithmetic operations +|-|*|/
  ...
}

Since a complex number can have zero imaginary component leaving only the real component, it’s handy to have an auxiliary constructor for those real-only cases as follows:

  // Auxiliary constructor
  def this(x: Double) = this(x, 0)

Just a side note, an auxiliary constructor must invoke another constructor of the class as its first action and cannot invoke a superclass constructor.

Next, let’s override method toString to cover various cases of how a x + yi complex number would look:

  // Override method toString
  override def toString =
    if (re != 0)
      if (im > 0)
        re + " + " + im + "i"
      else if (im < 0)
        re + " - " + -im + "i"
      else  // im == 0
        re.toString
    else  // re == 0
      if (im != 0)
        im + "i"
      else
        re.toString

Let’s also fill out the section for the basic arithmetic operations:

  // Overload methods for arithmetic operations
  def + (that: Complex): Complex =
    new Complex(re + that.re, im + that.im)
  def - (that: Complex): Complex =
    new Complex(re - that.re, im - that.im)
  def * (that: Complex): Complex =
    new Complex(re * that.re - im * that.im, re * that.im + im * that.re)
  def / (that: Complex): Complex = {
    require(that.re != 0 || that.im != 0)
    val den = that.re * that.re + that.im * that.im
    new Complex((re * that.re + im * that.im) / den, (- re * that.im + im * that.re) / den)
  }

Testing it out …

scala> val a = new Complex(1.0, 2.0)
a: Complex = 1.0 + 2.0i

scala> val b = new Complex(4.0, -3.0)
b: Complex = 4.0 - 3.0i

scala> val c = new Complex(2.0)
c: Complex = 2.0

scala> a + b
res0: Complex = 5.0 - 1.0i

scala> a - b
res1: Complex = -3.0 + 5.0i

scala> a * b
res2: Complex = 10.0 + 5.0i

scala> a / b
res3: Complex = -0.08 + 0.44i

So far so good. But what about this?

scala> a + 1.0
:3: error: type mismatch;
 found   : Double(1.0)
 required: Complex
       a + 1.0
           ^

The compiler complains because it does not know how to handle arithmetic operations between a Complex and a Double. With the auxiliary constructor, ‘a + new Complex(1.0)’ will compile fine, but it’s cumbersome to have to represent every real-only complex number that way. We could resolve the problem by adding methods like the following for the ‘+’ method:

  def + (that: Complex): Complex =
    new Complex(re + that.re, im + that.im)
  def + (x: Double): Complex =
    new Complex(re + x, im)

But then what about this?

scala> 2.0 + b
:4: error: overloaded method value + with alternatives:
  (x: Double)Double 
  (x: Float)Double 
  (x: Long)Double 
  (x: Int)Double 
  (x: Char)Double 
  (x: Short)Double 
  (x: Byte)Double 
  (x: String)String
 cannot be applied to (Complex)
       2.0 + b
           ^

The compiler interprets ‘a + 1.0’ as a.+(1.0). Since a is a Complex, the proposed new ‘+’ method in the Complex class can handle it. But ‘2.0 + b’ will fail because there isn’t a ‘+’ method in Double that can handle Complex. This is where implicit conversion shines.

  // Implicit conversion
  implicit def realToComplex(x: Double) = new Complex(x, 0)

The implicit method realToComplex hints the compiler to fall back to using the method when it encounters a compilation problem associated with type Double. In many cases, the implicit methods would never be explicitly called thus their name can be pretty much arbitrary. For instance, renaming realToComplex to foobar in this case would get the same job done.

As a bonus, arithmetic operations between Complex and Integer (or Long, Float) would work too. That’s because Scala already got, for instance, integer-to-double covered internally using implicit conversion in object Int, and in version 2.9.x or older, object Predef:

// Scala implicit conversions in class Int
final abstract class Int private extends AnyVal {
  ...
  import scala.language.implicitConversions
  implicit def int2long(x: Int): Long = x.toLong
  implicit def int2float(x: Int): Float = x.toFloat
  implicit def int2double(x: Int): Double = x.toDouble
}

Testing again …

scala> val a = new Complex(1.0, 2.0)
a: Complex = 1.0 + 2.0i

scala> val b = new Complex(4.0, -3.0)
b: Complex = 4.0 - 3.0i

scala> a + 1.5
res11: Complex = 2.5 + 2.0i

scala> 3 - b
res12: Complex = -1.0 + 3.0i

scala> a * 2
res13: Complex = 2.0 + 4.0i

scala> val x: Long = 50
x: Long = 50

scala> a + x
res14: Complex = 51.0 + 2.0i

scala> val y: Float = 6.6f
y: Float = 6.6

scala> val y: Float = 4.0f
y: Float = 4.0

scala> y / b
res15: Complex = 0.64 + 0.48i

Implicit conversion scope

To ensure the implicit conversion rule to be effective when you use the Complex class, we need to keep it in scope. By defining the implicit method or importing a snippet containing the method in the current scope, it’ll certainly serve us well. An alternative is to define it in a companion object as follows:

// Instantiation by constructor
object Complex {
  implicit def realToComplex(x: Double) = new Complex(x, 0)
}

class Complex(r: Double, i: Double) {
  val re: Double = r
  val im: Double = i
  def this(x: Double) = this(x, 0)  // Auxiliary constructor
  override def toString =
    if (re != 0)
      if (im > 0)
        re + " + " + im + "i"
      else if (im < 0)
        re + " - " + -im + "i"
      else  // im == 0
        re.toString
    else  // re == 0
      if (im != 0)
        im + "i"
      else
        re.toString
  // Methods for arithmetic operations
  def + (that: Complex): Complex =
    new Complex(re + that.re, im + that.im)
  def - (that: Complex): Complex =
    new Complex(re - that.re, im - that.im)
  def * (that: Complex): Complex =
    new Complex(re * that.re - im * that.im, re * that.im + im * that.re)
  def / (that: Complex): Complex = {
    require(that.re != 0 || that.im != 0)
    val den = that.re * that.re + that.im * that.im
    new Complex((re * that.re + im * that.im) / den, (- re * that.im + im * that.re) / den)
  }
}

As a final note, in case factory method is preferred thus removing the need for the ‘new’ keyword in instantiation, we could slightly modify the companion object/class as follows:

// Instantiation by factory
object Complex {
  implicit def realToComplex(x: Double) = new Complex(x, 0)
  def apply(r: Double, i: Double) = new Complex(r, i)
  def apply(r: Double) = new Complex(r, 0)
}

class Complex private (r: Double, i: Double) {
  val re: Double = r
  val im: Double = i
  override def toString =
    if (re != 0)
      if (im > 0)
        re + " + " + im + "i"
      else if (im < 0)
        re + " - " + -im + "i"
      else  // im == 0
        re.toString
    else  // re == 0
      if (im != 0)
        im + "i"
      else
        re.toString
  // Methods for arithmetic operations
  def + (that: Complex): Complex =
    new Complex(re + that.re, im + that.im)
  def - (that: Complex): Complex =
    new Complex(re - that.re, im - that.im)
  def * (that: Complex): Complex =
    new Complex(re * that.re - im * that.im, re * that.im + im * that.re)
  def / (that: Complex): Complex = {
    require(that.re != 0 || that.im != 0)
    val den = that.re * that.re + that.im * that.im
    new Complex((re * that.re + im * that.im) / den, (- re * that.im + im * that.re) / den)
  }
}

Another quick test …

scala> val a = Complex(1, 2)
a: Complex = 1.0 + 2.0i

scala> val b = Complex(4.0, -3.0)
b: Complex = 4.0 - 3.0i

scala> a + 2
res16: Complex = 3.0 + 2.0i

scala> 3 * b
res17: Complex = 12.0 - 9.0i

Database CRUD In Scala-Play

In a recent startup venture, I adopted Node.js and Python, both dynamic-typing programming platforms, in the core technology stack of a data-centric web application. While I like both platforms for what they’re inherently good at, I still have some biased preference towards static-typing languages. Scala was in my considered list of platforms before I eventually settled on Node.js. I wasn’t going to just forget about what I liked about Scala though.

Coming from a Math background, I have high regard for the benefit of functional programming. To me, Java has always been a great object-oriented programming (OOP) language for general-purpose application development. Although functional programming (FP) has been added since Java 8, the feature isn’t really an integral part of the language core. For that reason, I’m not going to start my pursuit of a static-typing programming platform that embodies OOP and FP with the Java platform.

Scala, Play and Reactive programming

Scala’s static-typing plus blending of object-oriented and functional programming in its language design make it an attractive programming language. The Play MVC framework, which comes with handy features like REST, asynchronous I/O in building web applications in Scala, has also picked up some momentum over the past few years. So, for general-purpose web-based application development, the Scala-Play combo sounds appealing for what I’m looking for.

Typesafe (being renamed to Lightbend as we speak) is a company founded by the authors of Scala and Akka. Advocating the Reactive programming paradigm, it provides a development tool Activator along with application templates to help streamline the development process, with emphasis in scalability, performance, resilience and non-blocking message-driven communication. The browser-based tool and reusable templates help make adopting the framework easier.

Data access layer: Anorm vs Squeryl vs Slick

There are a few libraries/APIs for the data access layer in the Scala-Play ecosystem. Anorm provides functionality for parsing and transformation of query results from embedded plain SQL. Squeryl is an ORM (object-relational mapping) that supports composition of queries and explicit data retrieval strategies. Slick is a FRM (functional-relational mapping) and virtually handles data access operations like using of Scala collections. After some quick review, I decided to try out Anorm.

As always, best way to get familiar with a programming platform is writing code. My hello-world application is a web application that handles database CRUD (create/read/update/delete) operations along with query pagination. Typesafe’s templates come in handy and help tremendously in providing the base code structure in various categories. There are templates with the data access layer using each of the three libraries. There is already a template with sample code for basic database operations and query pagination. That prompts me to bypass building the very basic stuff and instead focus on enhancement for expansion and maintainability.

Creating a project from Typesafe’s templates is straight forward. To run the Reactive development platform, simply launch its web server at the command line under the project root with the following command (or just doubleclick the activator executable from within a file browser):

./activator ui

Activator’s UI will be fired off on a web browser. You can compile and run the application via the UI and check out the launched application at http://localhost:9000/.

Looking under the hood

Based on the few templates I’ve downloaded, below is what a typical project root in the file system would look like:

path-to-project-root/
    build.sbt
    app/
        controllers/
        models/
        views/
    conf/
        application.conf
	routes
        evolutions/
    logs/
    project/
        build.properties
        plugins.sbt
    public/
    test/

Like many other web-based MVC frameworks, much of the file system structure (app/, logs/, public/, test/) is pretty self-explanatory. The *.sbt files contain project-specific build scripts and package dependencies. Routing is configured within file conf/routes. The conf/evolutions/ subdirectory is for tracking database evolution scripts.

Despite my limited experience in Scala, the overall code included in the template is pretty easy to grasp. It’s self-contained and equipped with sample data, scripts for data schema, Scala modules for models, views and controllers, and even jQuery and Bootstrap libaries. After getting a good understanding of the skeletal code in the framework, I came up with a list of high-level changes to be made:

  1. Expand the schema with multiple relational entities
  2. Apply Anorm’s parsing, filtering and query pagination to multiple views
  3. Modularize controller code into multiple controllers
  4. Add a navigation bar with some simple Bootstrap UI enhancement

All of the above are pretty straight forward. A simple 3-table relational data model (song –N:1– musician –N:1– country) is created. SQL scripts for populating the tables are created under conf/evolutions/default/*.sql to make use of Play’s database evolution scripting mechanism. Forms are created for creating and editing songs and musicians. Filtering and query pagination are applied to the song lists and musician lists. Multiple controllers are created for modularity and maintainability.

SQL statements in Anorm

Plain SQL statements can be directly embedded into Play’s model. For instance, the update() function in app/models/Song.scala for updating the song table is as simple as follows:

    def update(id: Long, song: Song) = {
        DB.withConnection { implicit connection =>
            SQL(
                """
                    update song
                    set name = {name}, released = {released}, musician_id = {musician_id}
                    where id = {id}
                """
            ).on(
                'id -> id,
                'name -> song.name,
                'released -> song.released,
                'musician_id -> song.musicianId
            ).executeUpdate()
        }
    }

Anorm SqlParser

Anorm appears to be a lean and mean library that allows developers to directly embed SQL statements into the application. At the same time, it provides flexible methods for parsing and transforming query results. One useful feature in Scala is its parser combinator which allows you to chain parsers to perform sequence of parsings of arbitrary text. For example, the following snippet in app/models/Song.scala shows the using of sequential parser combinator (~) to parse result set of the query from table “song”:

object Song {
    val simple = {
        get[Option[Long]]("song.id") ~
        get[String]("song.name") ~
        get[Option[Date]]("song.released") ~
        get[Option[Long]]("song.musician_id") map {
            case id ~ name ~ released ~ musicianId => Song(id, name, released, musicianId)
        }
    }
    ...
}

Both get[T] and the parser combinator (~) are methods defined within SqlParser as part of Anorm’s API:

def get[T](columnName: String)(implicit extractor: anorm.Column[T]): RowParser[T] = RowParser {
    ...
}

object RowParser {
    def apply[A](f: Row => SqlResult[A]): RowParser[A] = new RowParser[A] {
        def apply(row: Row): SqlResult[A] = f(row)
    }
}

trait RowParser[+A] extends (Row) => SqlResult[A] {
    parent =>
    ...
    def ~[B](p: RowParser[B]): RowParser[A ~ B] = RowParser(row => parent(row).flatMap(a => p(row).map(new ~(a, _))))
    ...
}

Query pagination

Pagination is done in an elegant fashion by means of a helper case class:

case class Page[A](items: Seq[A], page: Int, offset: Long, total: Long) {
    lazy val prev = Option(page - 1).filter(_ >= 0)
    lazy val next = Option(page + 1).filter(_ => (offset + items.size) < total)
}

The list() function in app/models/Song.scala is then defined with type Page[(Song, Option[Musician])]:

    def list(page: Int = 0, pageSize: Int = 10, orderBy: Int = 1, filter: String = "%"): Page[(Song, Option[Musician])] = {
        val offset = pageSize * page

        DB.withConnection { implicit connection =>
            val songs = SQL(
                """
                    select * from song 
                    left join musician on song.musician_id = musician.id
                    where song.name like {filter}
                    order by {orderBy} nulls last
                    limit {pageSize} offset {offset}
                """
            ).on(
                'pageSize -> pageSize, 
                'offset -> offset,
                'filter -> filter,
                'orderBy -> orderBy
            ).as(Song.withMusician *)

            val totalRows = SQL(
                """
                    select count(*) from song 
                    left join musician on song.musician_id = musician.id
                    where song.name like {filter}
                """
            ).on(
                'filter -> filter
            ).as(scalar[Long].single)

            Page(songs, page, offset, totalRows)
        }
    }

And the song list view, app/views/listSongs.scala.html, displays the song page information passed as currentPage, of type Page[(Song, Option[Musician])].

Passing request header as Implicit argument

A navigation bar is added to the main html template, app/views/main.scala.html. To highlight the active <li> items on the nav-bar, Bootstrap’s active class is used. But since the html pages are all rendered from the server-side in this application, request header needs to be passed from the controllers to the associated views (forms, list pages, etc), which in turn pass the header to the main html template where the nav-bar is defined. In Scala-Play, it can be effectively done by passing the request header as the last Implicit argument (which minimizes breaking any existing code). For instance, the argument list within app/views/editSong.scala.html will be as follows:

@(id: Long, songForm: Form[Song], musicians : Seq[(String, String)])(implicit messages: Messages, request: RequestHeader)

The request header passed to the main html template will then be consumed as highlighted below:

@(content: Html)(implicit messages: Messages, request: RequestHeader)
<!DOCTYPE html>
<html>
    <head>
        ...
    </head>
    <body>
        <header>
            ...
            <nav class="navbar navbar-default">
                <div class="container-fluid">
                <ul class="nav navbar-nav">
                    <li class="@{"active".when(request.path == routes.SongController.list(0, 2, "").toString())}"><a href="@routes.SongController.list(0, 2, "")">Songs</a></li>
                    <li class="@{"active".when(request.path == routes.MusicianController.list(0, 2, "").toString())}"><a href="@routes.MusicianController.list(0, 2, "")">Musicians</a></li>
                </ul>
                </div>
            </nav>
        </header>        
        ...
    </body>
</html>

Complete source code of the Scala-Play project is at GitHub.

My thoughts on Scala

Scala runs on JVM (Java virtual machine) and supports standard Java libraries. Based on some quick review of Scala I did a couple of years ago, if you want to quickly pick up the language’s basics, consider Scala School. For a more comprehensive introduction of Scala, try Programming in Scala.

Unless you’re already familiar with some functional programming language like Haskell, Erlang, it isn’t the easiest language to pick up and takes some getting-used-to to read Scala code. But the apparent inconsistency in certain aspects of the language is what makes it hard to learn the language. For instance, the Scala language seems to support semicolon inference in a inconsistent fashion. Here’s an example:

val files = Array(new java.io.File("/tmp/a.txt"), new java.io.File("/tmp/b.z"), new java.io.File("/tmp/c.txt"))

def lines(file: java.io.File) = scala.io.Source.fromFile(file).getLines().toList

def grep(pattern: String, fileExt: String) =
    for (
        file <- files if file.getName.endsWith(fileExt)
        line <- lines(file)
        trimmed = line.trim if trimmed.matches(pattern)
    ) println(file + ": " + trimmed)

The above snippet will fail because the compiler won’t infer semicolons within for(…). Switching to for{…} will fix the problem as semicolons are inferred in {} blocks.

There is also some inconsistency in whether type inference is supported within an argument list versus across curried argument lists, as illustrated in this blog post by Paul Chiusano.

One must also make room in memory to memorize loads of symbols for various meanings in the language, as Scala loves smileys. A few examples below:

<:      Upper type bound
>:      Lower type bound
<%      View bound
^^      Transformation parser combinator
: =>    By-name argument

Conclusion

Nevertheless, I like Scala as an OOP + FP platform by design. I also like how the Play framework along with TypeSafe’s Activator provides the Reactive application development platform and streamlines development process for contemporary web-based applications.

Many other programming language platforms (Java, Ruby, etc) out there support OOP + FP to various extents, but Scala is still one of the few static-typing platforms providing a solid hybrid of OOP and FP. In addition, running on a JVM and supporting Java libraries are really a big plus for Scala.

Having various choices of libraries/APIs in the data access layer allows engineers to pick what’s best for their needs. If you want an ORM, go for Squeryl; functional all the way, use Slick; embedded plain SQL with versatile parsing/filtering functions, Anorm it is.

Then, there is Akka’s Actor-based concurrency model included in Scala’s standard library. Actors are computational primitives that encapsulate state and behavior, and communicate via asynchronous message passing. The simple yet robust Actor model equipped with Scala’s OOP + FP programming semantics creates a powerful tool for building scalable distributed systems.