Monday, February 27, 2012

Having Fun with Monoid in Scalaz Seven

It's been some times since my last blog on Scalaz Seven that talks about Functor. You may have guessed that my second post on the series would be Applicative Functor. Well, sorry, I can't write in order yet, I prefer to talk about Monoid in Scalaz Seven instead. OK Let's have fun.

Having Fun With |+|
To start with, let's have some fun with |+| operator.

Let's start

scala> 6 |+| 7
res0: Int = 13

Well, not that interesting. It's just an addition. What about

scala> 6 + "9"
res2: String = 69

scala> 6 |+| "9"
<console>:14: error: type mismatch;
 found   : java.lang.String("9")
 required: Int
       6 |+| "9"

Not bad. |+| somehow protects you from adding integer to String. OK, not bad, but, not that fun. What about this:

scala> some(6) |+| some(9)
res9: Option[Int] = Some(15)

All right, that starts to be interesting. Give me more:

scala> some(6) |+| some(9) |+| some(10)
res10: Option[Int] = Some(25)

scala> some(6) |+| some(9) |+| some(10) |+| none[Int] |+| some(6)
res11: Option[Int] = Some(31)

Not bad at all. Want something more than that. Some String ?

scala> "Hello" |+| "World"

res25: java.lang.String = HelloWorld

scala> some("Hello") |+| some("World")

res26: java.lang.String = Some(HelloWorld)

What else do you have ? List ?

scala> List(2,4) |+| List(4, 5)
res28: List[Int] = List(2, 4, 4,5)

Cool. Boolean?

scala> val b = true
b: Boolean = true

scala> val c = true
c: Boolean = true

scala> b |+| c
<console>:24: error: value |+| is not a member of Boolean
       b |+| c

Ouch. Why ? Well, because |+| can be interpreted in conjunction or disjunction (note that, actually this works in Scalaz 6, not sure if scalaz seven will make it work as in scalaz 6). To fix this, let's do the following:

scala> val a = Conjunction(true)
a: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = true

scala> val b = Conjunction(true)
b: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = true

scala> val c = Conjunction(false)
c: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = false

scala> a |+| b
res34: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = true

scala> a |+| c
res35: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = false

scala> a |+| b |+| c
res36: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = false

All right. That makes sense. What about Disjunction ? Well, just do the same.

scala> val e = Disjunction(true)
e: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = true

scala> val f = Disjunction(true)
f: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = true

scala> val g = Disjunction(false)
g: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = false

scala> val h = Disjunction(false)
h: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = false

scala> e |+| f
res37: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = true

scala> e |+| h
res38: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = true

scala> g |+| h
res39: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = false

OK. That's cool, but it starts to be boring. Doesn't it? Give me something more spectacular.  What about Tuple?  All right, what about Tuple?

scala> (6, "Hello", List(4, 2)) |+| (7, "Hello", List(5))
res40: (Int, java.lang.String, List[Int]) = (13,HelloHello,List(4, 2, 5))

So, |+| actually "sums" each corresponding element of two tuples. That's quite cool. What if they are nested? Will it work ?

scala> (some(6), some("Hello"), (some(5), some(3))) |+| 
        (some(7), none[String], (some(6), none[Int]))

res43: (Option[Int], Option[java.lang.String], (Option[Int], Option[Int])) = 

(Some(13),Some(Hello),(Some(11), Some(3)))

Fantastic! Pretty cool.

[ I heard somebody there "you see, this Scalaz guy loves using funny operator. This time, they use |+|. OMG, That's not readable". All right, all right. You can actually change all |+| above with its alias called mappend, hope you're happier now].

Monoid and Semigroup Behind the Scene

Behind the scene, what happen is that Scalaz offers a quite simple but powerful abstraction, called Monoid. Believe me, Monoid is something quite simple: it's a type class with two functions: append and zero: 

2      trait Monoid[A] { 
3        val zero: A 
4        def append(s1 : A, s2 : => A):A
5      } 

With the following contract (or a law, if you wish)

zero append x = x
x append zero = x
(x append y) append z = x append (y append z)

Scalaz provides several instances of Monoid (we have seen some of them in action above):

  • Int, Short, BigInt, BigDecimal, Byte, Short ...
  • Boolean conjunction and disjunction
  • List and Stream
  • String
  • Either.LeftProjection and Either.RightProjection.
  • ...
What about Option and Tuple ? Actually, Scalaz also provides some derived Monoid, like:
  • Option[A] is a monoid if A is monoid 
  • Tuple[A, B, C, D] is a monoid if A, B, C, and D is monoid
  • Map [A,B] is a monoid if B is a monoid
  • ...
Map is an interesting example. Let's try this:

scala> val m = Map("UO" -> BigDecimal(40.2),
     |              "US" -> BigDecimal(50.1),
     |              "YR" -> BigDecimal(10.1))
scala> val n = Map("UO" -> BigDecimal(10.2),
     |              "US" -> BigDecimal(40.0),
     |              "YZ" -> BigDecimal(10.5))
scala> m |+| n
res47: scala.collection.immutable.Map[java.lang.String,scala.math.BigDecimal] = Map(UO -> 50.4, US -
> 90.1, YZ -> 10.5, YR -> 10.1)

As you can see, |+| adds every corresponding element in m and n. If there's no corresponding element, for example "YR" in m and "YZ" in n, then it just puts the element in the result map.

All examples so far use append function of Monoid, but not zero. A type class with only append is called Semigroup. The function zero is useful when we want to fold a list of monoid, for example using suml function also provided by scalaz:

scala> val xs = List(some(2,4), some(1, 3), some(2, 10))
xs: List[Option[(Int, Int)]] = List(Some((2,4)), Some((1,3)), Some((2,10)))

scala> xs.suml
res48: Option[(Int, Int)] = Some((5,17))

Scalaz provides a cool thing called Semigroup and Monoid. With that, we can benefit the operator |+| and sum for their instances like Integer, String, List, and so on. But the main benefit is that Scalaz provides implementation of Monoid for Option, Tuple, and Map. You don't need to know what Monoid or Semigroup are to benefit all this. But, why should you avoid them ? It's a very simple stuff.

I hope you enjoy this very express introduction to Scalaz Seven Monoid. Who said Scalaz is complex ?
 I'm preparing more on this subject. So, stay tuned.

Wednesday, February 22, 2012

Gatling Tool at Riviera Scala Clojure

This evening, at Riviera Scala Clojure, we received St├ęphane Landelle and Romain Sertelon, Gatling Tools developers.

It's been quite some times I look for stress test tool that is intended for developers, instead of testers. You know, soemething like Caliper, but for stress tests.For a simple reason, I would like to profile my application and identify the problem on the load before even going to QA testing. Profiling can be done using a tool like Yourkit. But for load test, I haven't found anything convincing.

Of course, I used JMeter in the past. But I really want to have something that can be coded, but stays simple. JMeter, well...., it's  not that.

So, Gatling caught my attention. It has already caught my attention since St├ęphane mentioned it in Paris Scala User Group mailing list back in December. So, here they are,  presenting the product in front of Riviera Scala Clojure group.

Performance, DSL, and Reporting
One thing that makes Gatling different is its performance. The performance of Gatling is claimed to be superior than JMeter. This is because Gatling uses Akka and AsyncHttp that allow optimization of concurrent execution of scenarios. The argument really makes sense to me, and I would really love to see it in real. Check their wiki to see the performance benchmark compared to JMeter:

The second important point in Gatling is DSL. The DSL is intended to allow programmatic scenario to be expressed easily. DSL in Gatling,  is nothing more than a fluent API, so, no need to worry, it's Scala. Check here to see the examples of the API.

You may notice that the API is quite simple -- maybe too simple? I found the DSL too imperative, but maybe this is a pragmatic choice by Gatling developer. I would have preferred the DSL to be a little bit more functional with use of pattern matching, partial function, and function composition, and other functional programming concepts instead of sequencing, the use of doIf, and loop.

The reporting is actually an interesting part of Gatling. Unfortunately, we were not lucky enough to have a full blown presentation on it, only an after presentation discussion.

Gatling is an interesting tool to see if you"re interested in having a lightweight load test tool  like me. Its performance benchmark is quite promising. I have had a look at the codes, played with it, and it looks quite promising. The wiki page contains quite extensive information. But, I give you a puzzle: please find me in the wiki a scala file that shows the scenario example. Go ahead, if you can find it in 30 minutes, you're better than I am :-)