суббота, 15 марта 2014 г.

Multiple dispatch in Java

Today I found a good FP library which is called totallylazy. This library has a lot of great features like persistent collections, options and streams (they call it Computation), but it also has a very good feature, which makes it possible to write multimethods in Java. I think, multiple dispatch is a great tool that makes code much more concise and cleaner. This is how it looks:

       public String collide(Object obj1, Object obj2) {
           return new multi(){}.<String> methodOption(obj1, obj2).getOrThrow(
               new IllegalArgumentException("No method found for args: " +
                   obj1.getClass() + ", " + obj2.getClass()));
       }

       @multimethod
       public String collide(Asteroid asteroid, Spaceship spaceship) {
           return "Asteroid hits spaceship";
       }

       @multimethod
       public String collide(Asteroid asteroid, Asteroid asteroid2) {
           return "Asteroid hits another asteroid";
       }

       @multimethod
       public String collide(Spaceship spaceship, Asteroid asteroid) {
           return "Spaceship hits asteroid";
       }

       @multimethod
       public String collide(Spaceship spaceship, Spaceship spaceship2) {
           return "Spaceship hits another spaceship";

       }

This is a classis example of multiple dispatch taken from Wiki. So if you pass two objects to the collide method, the method with most specific parameter types will be picked:

       Object a = new Asteroid();
       Object s = new Spaceship();
       System.out.println(collide(a, s)); // Prints "Asteroid hits spaceship"

Of course, this uses internally some sort of reflection and this is not as fast as static method linking. But since the famous rule says "Avoid premature optimization", you should not be afraid to write such code.

вторник, 15 октября 2013 г.

понедельник, 16 сентября 2013 г.

Readable string interpolation in Scala

Multiline strings in Scala have a well-known issue: they produce annoying leading whitespaces.
For example:
object MyApp extends App {
  val html = """
    <html>
      <body>
        <p>Lorem ipsum dolor sit amet...</p>
      </body>
    </html>
  """

  println(html)
}
Running this code produces:

····<html>
······<body>
········<p>Lorem ipsum dolor sit amet...</p>
······</body>
····</html>
··  
As you see, there are:
  • One extra line at the beginning
  • Unnecessary leading spaces before html markup
  • One extra line with two spaces at the end
This small library can solve this problem (inspired by Xtend template expressions). Everything you need is to put nice before your multiline string:
import com.github.orionll.scala.ReadableStringInterpolation._

object MyApp extends App {
  val html = nice"""
    <html>
      <body>
        <p>Lorem ipsum dolor sit amet...</p>
      </body>
    </html>
  """

  println(html)
}
Now this code produces:
<html>
  <body>
    <p>Lorem ipsum dolor sit amet...</p>
  </body>
</html>
nice also plays well with expressions inside strings:
import com.github.orionll.scala.ReadableStringInterpolation._

object MyApp extends App {
  val paragraphs = nice"""
    <p>line1</p>
    <p>line2</p>
  """

  val html = nice"""
    <html>
      <body>
        $paragraphs
      </body>
    </html>
  """

  println(html)
}
The output will be exactly you expect it to be:
<html>
  <body>
    <p>line1</p>
    <p>line2</p>
  </body>
</html>
(Now try to run this code with standard s instead of nice and compare the resulting mess with this)

понедельник, 12 августа 2013 г.

Implementing try-with-resources in Xtend

Java 7 and C# provide a convenient syntax that ensures the correct use of Closeable (IDisposable) objects. In Java 7 it is called try-with-resources. Here is an example of its usage (Java code):

try (Reader reader = new FileReader("file.txt")) {
  // do something with reader
}

Xtend does not provide this feature. However, you can implement it easily:

class Using {
  def static <T extends Closeable, R> R using(T resource, (T) => R proc) {
    // This is kept for a case when a Throwable from close()
    // overwrites a throwable from try
    var Throwable mainThrowable = null

    try {
      return proc.apply(resource)
    } catch (Throwable t) {
      mainThrowable = t
      throw t
    } finally {
      if (mainThrowable == null) {
        resource.close
      } else {
        try {
          resource.close
        } catch (Throwable unused) {
          // ignore because mainThrowable is present
        }
      }
    }
  }
}

This is sometimes called a loan pattern which is widely used in Scala. I use using as a method name, because try is a reserved keyword in Java and Xtend. The following example shows how to use the using statement:

import static org.example.xtend.Using.*

val text = using(new FileReader('file.txt')) [
  val buf = CharBuffer::allocate(1024// this is just an example
  it.read(buf)
  buf.rewind
  buf.toString
]

println(text)

One can use it keyword to refer to a passed instance of Closeable.
The nice feature is that using can also return a value. So, "Everything is an expression" principle works here as well.