DSL example in Scala

Here’s a DSL example in Scala that will allow us to express amounts in the context of currencies taking into account the FX rates too.

By the end of it we’ll be able to write the following:

'USD(100) + 'EUR(200) in 'EUR

Here’s the code for it:

object ScalaForexRatesDSL {

  implicit class ccy2money(ccy :Symbol) {
    def apply(amount: BigDecimal) = Money(amount, ccy)
  }
}

case class FromToCcy(ccyFrom: Symbol, ccyTo: Symbol)

case class Money(amount:BigDecimal, ccy:Symbol) {

  def + (other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
    if(ccy == other.ccy) Money(amount + other.amount, ccy) else {
      val convertedOther = convertedOtherMoney(other)
      Money(amount + convertedOther.amount, ccy)
    }

  def - (other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
    if(ccy == other.ccy) Money(amount - other.amount, ccy) else {
      val convertedOther = convertedOtherMoney(other)
      Money(amount - convertedOther.amount, ccy)
    }

  def * (other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
    if(ccy == other.ccy) Money(amount * other.amount, ccy) else {
      val convertedOther = convertedOtherMoney(other)
      Money(amount * convertedOther.amount, ccy)
    }

  def / (other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
    if(ccy == other.ccy) Money(amount / other.amount, ccy) else {
      val convertedOther = convertedOtherMoney(other)
      Money(amount / convertedOther.amount, ccy)
    }

  private def convertedOtherMoney(other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money = {
    val rate = rates.get(FromToCcy(other.ccy, ccy)).getOrElse(1 / rates.get(FromToCcy(ccy, other.ccy)).get)
    Money(other.amount * rate, ccy)
  }

  def in(ccy: Symbol)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
    if (this.ccy == ccy) this else {
      val rate = rates.get(FromToCcy(this.ccy, ccy)).getOrElse(1 / rates.get(FromToCcy(ccy, this.ccy)).get)
      Money(amount * rate, ccy)
    }

  override def toString = amount + " " + ccy.name
}


object Main extends App {

  import ScalaForexRatesDSL._

  implicit val rates = Map((FromToCcy('EUR, 'USD) -> BigDecimal(1.13)))

  print( 'USD(100) + 'EUR(200) in 'EUR )

}

Spring Boot – Testing

Spring Boot dependency for Testing is bringing exactly what I would have wished for (I hope they would include in the future the upcoming AssertJ).

The dependency looks like this:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

and brings in the classpath the usual Testing suspects: JUnit4, Mockito and Hamcrest.

Screen Shot 2015-07-12 at 21.18.17

Spring Boot – Logging

As is the case with any new framework (or major addition to an existing and well known framework) the best way to approach it, work with it and learn it is not to dive head first but rather take baby steps in areas that feel more accessible and can link with ideas/processes/steps you are already following.

Spring Boot is sporting several starter recipes that can speedup your configuration and can be consumed separately to each other.

Let’s first talk about logging.

The best practise is to code against SLF4J, provide a desired implementation (preferably Logback), and include in the classpath SLF4J bridges for JUL, JCL and Log4J.

The process is described here by the person/team that authored SLF4J, Log4J, Log4j2, Logback and all the 3 SLF4J bridges namely for JUL, JCL, and Log4J.

The design we described and we are aiming at is also well depicted in the link above and is provided here for quick reference:

Screen Shot 2015-07-12 at 21.03.18

Let’s now get back to Spring Boot.

The Spring Boot dependency module is the following:


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-logging</artifactId>
		</dependency>

That is actually doing all we want and described above effortlessly leaving our classpath changed by this much:

Screen Shot 2015-07-12 at 21.09.39

Scala Option Advanced example

I’ve been tinkering with mime types in a toy Scalatra file server so while maintain a file with all known mime types a common task is to figure out the extension of a given file name.

With a bit out-of-the-box thinking on capturing the extension but without using Options therefore open to failures:

def findExtension(s:String)=s.reverse.takeWhile(_!='.').reverse

Here’s how it looks while wrapping the string in the Option monad and performing type-safe operations on it before returning a Some or None of the extension:

scala> def findExtension(s:String)=
 Option(s) //wrap into Option
 .filter(_.exists(_=='.'))  //ignore files without a dot
 .map(_.reverse)  //out-of-the-box thinking
 .map(_.takeWhile(_!='.'))  //maybe could be done with some non-greedy advanced regex too
 .filter(_.trim.nonEmpty)  //take "" empty strings as None
 .map(_.reverse)  //reverse back
findExtension: (s: String)Option[String]

scala> findExtension("hi")
res128: Option[String] = None

scala> findExtension("h.io")
res129: Option[String] = Some(io)

scala> findExtension("www.github.io")
res130: Option[String] = Some(io)

Scala For-Comprehension Advanced usage

Let’s say we want to find all three-pair additions that equate to 10 (order is irrelevant so we don’t want dups). What we would normally do in imperative Java would be 3 nested for loops with indexes say i, j and k where i ranges from 1 till 10, j starts from i+1 and k starts from j+1. The body of the for loop would be the if predicate case. We would also need a variable to store the results.

Instead in Scala:


val l = List(1,2,3,4,5,6,7,8,9,10)

for {
   (a,i) <- l.zipWithIndex
   (b,j) <- l.zipWithIndex.drop(i+1)
      c  <- l.drop(j+1)
   if 10 == a + b + c
} println(s"$a $b $c") 

We can also use for comprehension with yield as a returned assignable result rather than println

Stopwatch implementation in Scala

Timing method operations can be a labouring taskĀ littering the method body with the timing variables (sometimes short-lived as in debug mode). Thankfully we can treat the timing activity as a pass-by-name method argument of our newly defined timing operation:

def timed [T] (f: => T): T = {
 val startTime = System.currentTimeMillis()
 try f finally println(s"Function completed in: ${System.currentTimeMillis() - startTime} ms" )
}

Scala call-by-name

The arguement notation : => A denotes passing the argument in call-by-name manner not the traditional call-by-value fashion. That essentially means:

  • If the parameter is never used, it is never evaluated
  • If the parameter is used multiple times, it is getting evaluated each and every time in the by-name invocation

Traditionally call-by-value invocation would be evalutated just once and the calculated value would be just pushed in the method stack:

def myprint(date: java.util.Date):Unit = for(i->1 to 5) println(date)

scala> myprint( {Thread.sleep(1000); new java.util.Date()} )
Sun Apr 27 10:10:37 GMT 2014
Sun Apr 27 10:10:37 GMT 2014
Sun Apr 27 10:10:37 GMT 2014
Sun Apr 27 10:10:37 GMT 2014
Sun Apr 27 10:10:37 GMT 2014

whereas call-by-name would be evaluated each and every time anew:

def myprint(date :=> java.util.Date):Unit = for(i->1 to 5) println(date)

scala&gt; myprint( {Thread.sleep(1000); new java.util.Date()} )
Sun Apr 27 10:12:46 GMT 2014
Sun Apr 27 10:12:47 GMT 2014
Sun Apr 27 10:12:48 GMT 2014
Sun Apr 27 10:12:49 GMT 2014
Sun Apr 27 10:12:50 GMT 2014

How to add Options in Scala

Options are Monads and we can perform operations in their underlying types in a typesafe way using Scalaz:

  import scalaz._
  import Scalaz._

  val a: Option[BigDecimal] = BigDecimal("0.123").some
  val b: Option[BigDecimal] = BigDecimal("1.234").some
  val c: Option[BigDecimal] = BigDecimal("2.345").some

  println( (a |@| b |@| c) { _ + _ + _ } )

  //yields: Some(3.702)

and if the chain is broken, we don’t have to worry since it’s getting short-circuited:

  import scalaz._
  import Scalaz._

  val a: Option[BigDecimal] = BigDecimal("0.123").some
  val b: Option[BigDecimal] = None
  val c: Option[BigDecimal] = BigDecimal("2.345").some

  println( (a |@| b |@| c) { _ + _ + _ } )

  //yields: None

Spring JPA, Hibernate, Data XML configuration

Here’s a cleaned up, plug’n’play version of a Spring database XML config taken from a demo project employing Spring Data for the Repositories interfaces and Hibernate behind JPA.

<beans 	xmlns="http://www.springframework.org/schema/beans"
		xmlns:p="http://www.springframework.org/schema/p"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx.xsd
		http://www.springframework.org/schema/data/jpa
		http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
		  p:entityManagerFactory-ref="entityManagerFactory" />


	<jpa:repositories base-package="com.to.my.data.repository"
					  transaction-manager-ref="transactionManager"
					  entity-manager-factory-ref="entityManagerFactory"/>

	<tx:annotation-driven transaction-manager="transactionManager"/>
	

	
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
					p:database="${database.database}"
					p:databasePlatform="${database.databasePlatform}"
					p:showSql="${database.showSql}"
					p:generateDdl="${database.generateDdl}" />
		</property>
		<property name="jpaProperties">
			<props>
				<prop key="hibernate.dialect">${database.databasePlatform}</prop>
				<prop key="hibernate.max_fetch_depth">3</prop>
				<prop key="hibernate.fetch_size">50</prop>
				<prop key="hibernate.batch_size">10</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
		<property name="packagesToScan" value="com.to.my.bean"/>
	</bean>
	
	<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource"
			p:driverClassName="${database.driverClassName}"
			p:url="${database.url}"
			p:username="${database.username}"
			p:password="${database.password}"
			p:testOnBorrow="true"
			p:testOnReturn="true"
			p:testWhileIdle="true"
			p:timeBetweenEvictionRunsMillis="1800000"
			p:numTestsPerEvictionRun="3"
			p:minEvictableIdleTimeMillis="1800000"
			p:initialSize="1"
			p:maxActive="50"
			p:maxIdle="20"/>

</beans>