Sunday, February 10, 2013

Duck typing in Scala (kind of). Structural Typing.

Scala offers a functionality known as Structural Types which allows to set a behaviour very similar to what dynamic languages allow to do when they support Duck Typing (http://en.wikipedia.org/wiki/Duck_typing)

The main difference is that it is a type safe, static typed implementation checked up at compile time. This means that you can create a function (or method) that receives an expected duck. But at compile time it would be checked that anything that is passed can actually quack like a Duck.

Here is an example. Let’s say we want to create a function that expects anything that can quack like a duck. This is how we would do it in Scala with Structural Typing:

def quacker(duck: {def quack(value: String): String}) {
  println (duck.quack("Quack"))
}


You can see that in the definition of the function we are not expecting a particular class or type. We are specifying an Structural Type which in this case means that we are expecting any type that has a method with the signature quack(string: String): String.

So all the following examples will work with that function:

object BigDuck {
  def quack(value: String) = {
    value.toUpperCase
  }
}

object SmallDuck {
  def quack(value: String) = {
    value.toLowerCase
  }
}

object IamNotReallyADuck {
  def quack(value: String) = {
    "prrrrrp"
  }
}

quacker(BigDuck)
quacker(SmallDuck)
quacker(IamNotReallyADuck)


You can see that there is no interface or anything being implemented by any of the three objects we have defined. They simply have to define the method quack in order to work in our function.

If you run the code above you get the output:

QUACK
quack
prrrrrp


If on the other hand you try to create an object without a quack method and try to call the function with that object you would get a compile error. For example trying to do this:

object NoQuaker {

}

quacker(NoQuaker)


You would get the error:

error: type mismatch; found : this.NoQuaker.type required: AnyRef{def quack(value: String): String} quacker(NoQuaker)

Also, you don’t even need to create a new type or class. You could use AnyRef to create an object with the quack method. Like this:

val x = new AnyRef {
  def quack(value: String) = {
    "No type needed "+ value
  }
}


and you can use that object to call the function:

quacker(x)

You can also specify in the function that expects the structural type, the the parameter object must respond to more than one method. Like this:

def quacker(duck: {def quack(value: String): String; def walk(): String}) {
  println (duck.quack("Quack"))
}


There you are saying that any object you pass to the function needs to respond to both methods quack and walk. This is also checked at compile time.

Under the covers the use of Structural Types in this way will be handled by reflection. This means that it is a more expensive operation than the standard method call. So use only when it actually makes sense to use it.

Tuesday, February 5, 2013

Understanding Currying with Scala

Learning Scala is not an easy task. There are many things to learn. Some of them are very different and some of them seem complex.

Currying is a technique not necessarily complex, but is one that you probably are not familiar with if you come from Java background as it is not a straightforward technique to apply in that language. Currying allows to turn a function that expects two arguments into a function that expects only one, and that function returns a function that expects the second argument. Creating basically a chain of functions.

Let’s see with a simplistic example how it works.

Let’s say we have this two simple classes:

case class Message(value: String){

}

case class Endpoint(prompt: String){
 def send(m: Message) {
   println(this.prompt + " " + m.value)
 }
}
 
Now let’s pretend we want to send a Message to an Endpoint in a general function. We can create a function that looks like this:

def routeTo(m:Message, e:Endpoint) = {
  e.send(m)
}
To call this function we would do something like:

routeTo(Message("hola"),Endpoint("sending"))
(You could ask why we just don’t create the endpoint and call send with the message like Endpoint(“sending”).send(Message(“hola”)) and there is no reason in this example. Simply to illustrate currying).

Now let’s suppose we want to send the same message to different endpoints. For that we could use the currying technique. We will basically turn our function into a function that returns another function:

def route(m:Message) = {
  (e: Endpoint) => e.send(m)
}
 
You can see we have created a function that just receives the Message and returns a function that receives the Endpoint and sends the message to that endpoint.

Now we could do something like the following:

val routeCiao = route(Message("ciao"))

routeCiao(Endpoint("sending again"))
routeCiao(Endpoint("sending over again"))
You can see that we are assigning the return of route(Message(“ciao”)), which is a function (Endpoint => Unit) to the val routeCiao. In practice this is basically returning the function (e: Endpoint) => e.send(“ciao”) as the value of the variable m is replaced by “ciao” when calling to the route function.

Then we are simply calling the returned function passing the value of the endpoint as the only argument. So this function is executed and the message is sent to the endpoint.

You could of course call the currying function without storing the mid result in a val. Like this:

route(Message("hi"))(Endpoint("sender"))
Scala supports a more compact way to defining currying functions. We could replace the route function with the following:

def route(m:Message)(e:Endpoint) = {
   e.send(m)
}
The effect is the same if you call like this: route(Message("hi"))(Endpoint("sender")) However to call and store the mid result in a val you need to do it like this:

val routeCiao = route(Message("ciao")) _


Note the underscore at the end of the assignment.

On programmers and programming languages. Your opinion?

This is a small article in which I want to talk about a couple of issues that I sometimes talk about with my colleagues at work, but most of the time keep to myself. These are two subjects that I would like to know the general software community’s opinion about.

The first thing is regarding the role of software developer and using different programming languages in your work.

The second is regarding what makes a good programmer.


Let’s start with the first one:

I consider myself a software developer, more than a Java developer, Ruby developer or any other language specific developer. I think this is a very important thing in this field of work. To be able to produce results in any language that you work with, without having prejudices against them.

I am not saying here that you need to like all programming languages, but what I am saying is that you need to consider that most programming languages have good characteristics and advantages over other languages, no matter if those other languages are your favorite ones.

I am not saying either that you should be an expert on every language out there, but I do think that you should try to be good in at least two languages that are different enough between them to involve certain change of thinking going from one to the other.

It is also fine to be an expert in a particular language, specializing in it. But this doesn’t mean disregard the other ones as useless. I’m talking about this for two main reasons. First because in my current job and in my current position we were very recently looking for Java and Ruby developers. Not Java developers and Ruby developers. But a Java/Ruby developer to work in both languages at the same time. The other reason is that I usually write in this blog about different things in technology and mainly about Ruby and Java as they are the languages I know better.

In both scenarios (interviews and blog writing) the majority of the people that works in one of this languages disregard the other one as complete horrible. The Ruby people say that they will never work with Java as it is cumbersome, full of boilerplate, full of XML, horrible syntax, too many frameworks to care about, boring typing, and a big etc. The Java people say that Ruby is a toy language, some people say working with it is not even programming, they say is just too slow to do anything useful, that everything is a mess without types, that metaprogramming is magic that you just don’t know what is happening and another big list of etc.

So it is really hard to find developers that work and enjoy working with this two different languages (and probably between any two different languages). Sometimes it feels like they don’t even want to give the opportunity to the other language to prove its worthiness and is simply discarded from the beginning. Sometimes I really think it might be a case of laziness to actually try and learn something new and different when you are in the comfort of what you already know. I, on the other hand find this learning really interesting and definitely worth my time as I think it makes me better as an overall developer and help me understand the goods and bads of every language, because I can tell you, both Java and Ruby are very good languages in their own way.


The second point I wanted to talk about is regarding on what makes a good programmer.

What brings me to this particular subject is the way I see myself and the way I see all developers I work with or the ones I interview or even the ones whose code I look on different open source projects.

I can’t really answer what a good programmer is as I think it can be different things to different people. As an example, I try to use good programming practices a lot in my day to day work, I try to use and enforce the use and benefits of TDD on my colleagues. I try to enforce the use of simple principles like DRY, SRP, and also the readability and conciseness of the code that I and my colleagues write. I also think that I find good solutions to the day to day tasks that I have, and I try to think of the best possible ways to solve the problems at hand. So in that sense, I consider myself a good programmer.

However, from a different perspective I would say I am not really good at all. This perspective comes into place in let’s say, for example, an environment where I need to develop really super efficient algorithms using mathematical efficient formulas to solve problems. It comes to mind maybe things like 3D gaming, Artificial intelligence and the like.

As an example, I was recently solving a couple of problems in TopCoder. One of the problems took me like 1 hour to solve I would say. It was an implementation that if I don’t remember wrong had a couple of for loops (one nested inside the other) and 3 or 4 if statements. I remember it also had a HashMap structure for storing some middle results of the final computation. I was happy that I solved, but I knew it didn’t look great (not the code itself, which was OK, but the solution as a whole), so I went on to see other people’s solutions. One of the solutions I found was 2 lines of code with a couple of mathematical formulas that really didn’t make sense to me at that point, and that I had no idea how that small thing could do all that my 30 line algorithm did. So from that point of view, I would say that the other guy is definitely a better programmer than me.

So sometimes when I am interviewing people at my job, asking my questions (What is Dependency Injection, What is AOP useful for, Explain how you use Strategy pattern, etc etc...) if they don’t have any idea of this I always wonder if they might be amazing at this other programming skills that I maybe don’t have. But I guess I can’t really know, as we are looking for a particular profile, and if it doesn’t have the skills we require, we say he is not a good programmer and he doesn’t get hired.
That happened very recently, some colleague was interviewing this Computer Science PhD who didn’t answer any of this questions, and so he was rejected as he was no good at all. But I ended up wondering. If he’s got a PhD he needs to be good right?. Maybe he is just good at different things and not at what we are looking for.