Tuesday, April 27, 2010

This topic provides some explanation about how implicit parameters are resulted. There are very strict rules for which implicit value is to be applied to a implicit parameter. A simple way to think about it is that the "closest" definition will be used. Local scope, enclosing class, parent class, companion object of the desired type.

Monday, April 26, 2010

Evidently the topic of implicit parameters has not yet been correctly addressed. There have been several topic that refer to implicit parameters but none that directly discuss them. So before I continue with the topic of implicit parameter resolution I will discuss implicit parameters.

First, implicit parameters are not the same as implicit object conversions. Implicit parameters provide a way to allow parameters of a method to be "found". This is similar to default parameters at a glance but in fact is a different mechanism for finding the "default" value. It differs from implicit object conversion in that it is only a way for parameters for a method to be resolved. Implicit object conversion allows methods to appear to be called on one object when in fact that object is being converted behind the scenes to another type. (more or less)

An implicit parameter is a parameter to method or constructor that is marked as implicit. This means that if a parameter value is not supplied then the compiler will search for an "implicit" value defined within scope (according to resolution rules.) Implicit parameter resolution rules will be discussed soon.

Example:

scala>def p(implicit i:Int) = print(i)

p: (implicit i: Int)Unit

// defining a val/var/def as implicit

// means that it will be considered during implicit resolution

scala> implicit val v=2

v: Int = 2

// scope is searched for a implicit value to sue

// v is found as marked implicit

scala> p

2

// explicit declarations always overrides implicit values

scala> p(1)

1

Implicit parameters are very nice for simplifying APIs. For example the collections use implicit parameters to supply CanBuildFrom objects for many of the collection methods. This is because normally the user does not need to be concerned with those parameters. Another example is supplying an encoding to an IO library so the encoding is defined once (perhaps in a package object) and all methods can use the same encoding without having to define it for every method call.

One important restriction is that there can only be a single implicit keyword per method. It must be at the start of a parameter list (which also makes all values of that parameter list be implicit). I further understand that only the last parameter list may be implicit.

Friday, April 23, 2010

In the Breaks comments there were several questions about the performance of the Scala break command vs the Java break command. So I decided to take a look.

The code for the tests is available on GitHub at: Scala Benchmarks. Feel free to play around with it.

I personally don't think these tests say anything of particular import because they only test how fast the Java break is vs the Scala break without doing any work in the loop. So I don't expect these number would ever been seen in the real world. However that said if you have a tight loop with minimal processing then a Scala break may not be the correct construct to use.

Here is the Java test (labelled JavaSimpleBreak)

int i = 0;

while (i < 10) {

if(i==1) break;

i += 1;

}

Here is the Scala test (labelled ScalaSimpleBreak)

var i = 0;

breakable {

while (i < 10) {

if(i==1) break;

i += 1;

}

}

Out of curiosity I also added a test that created a new Exception each iteration (labelled ScalaException):

var i = 0;

while (i < 10) {

if(i==1) thrownew Exception();

i += 1;

}

And also a test that just throws the same ScalaBreak exception each time. This one is weird since Scala Simple Break also throws the same exception but is much much faster so I think there is something about popping the stack in the example compared to the ScalaSimpleBreak test.

var i = 0;

breakable {

while (i < 10) {

if(i==1) break;

i += 1;

}

}

The results of the tests:

First, don't compare the break tests to the Exception tests. They are sufficiently different to not be worth comparing.Second, remember that this is a micro benchmark and has very little relationship to reality.90000000 iterations. Swapping every 90000000 testsJavaSimpleBreak = 254 (0.0016279129387033098)ScalaSimpleBreak = 2475 (0.015862537493270438)ScalaBreakException = 18806 (0.12052964852462379)ScalaException = 156028 (1.0)

Wednesday, April 21, 2010

When a method requires an implicit there are several ways that the implicit is resolved. One way is to search for an implicit definition in the companion object of the required type. For example: def x(implicit m:MyClass) parameter m will search local scope, class hierarchy and the MyClass companion object for an implicit val or def. (More on implicit resolution later).

To demonstrate the method put the following code block into a file and run the script:

Tuesday, April 20, 2010

Scala 2.8 added the break control flow option. It is not implemented as a special language feature. Rather it is simply implemented as an object/trait using standard Scala mechanisms. If you are interested in creating a control flow object similar to this look at the Defining Custom Control Structures post.

The Break functionality is works basically how you would expect:

// Import the control flow methodsmethods

scala>import util.control.Breaks._

import util.control.Breaks._

// pass a function to the breakable method

scala> breakable {

| for (i <- 1 to 10 ) {

| if(i > 5) break // call break when done

| println(i)

| }

| }

1

2

3

4

5

Pretty intuitive but beware, break only breaks out to the first enclosing breakable. Here is an example of the issue:

scala>def loop(f : Int => Boolean) = breakable {

| for (i <- 1 to 300) if (f(i)) break else println(i)

| }

loop: (f: (Int) => Boolean)Unit

// This never ends because break is caught by breakable in the loop method

scala> breakable {

| while(true) {

| loop{ i => break; true }

| }

| }

Fortunately the implementers provide an elegant way to handle these sorts of cases. The Breaks object extends the Breaks class. By instantiating other instances of Breaks it is possible to control which breaks capture

Monday, April 19, 2010

One performance/consistency change that has been make in Scala 2.8 is to make Scala Array always be a Java Array. This has some consequences which we will examine in this post. The biggest one is that Array is not a Scala Collection/Traversable. It is implicitly converted to one but it is not an instance of a Traversable. There are several reasons this was done. Probably the biggest is for performance. Because a Scala array is a Java array there is no overhead when using a Scala array.

Thanks to implicit type conversion all the normal collection methods are useable with an array. Even better, after running a method like map the result will again be a Java array. So the API is much more consistent.

So suppose you want to be able to accept and use arrays and Traversables in a method but you want to be able to check that the parameter is an Array. Why not match against WrappedArray. You probably can, but you may get performance improvements in some cases if you don't require wrapping the array.

For a more concrete example of why you may want to do this. In a Input/Output routine I wrote I would write the data one way if the input was an Array: stream.write(array). But if the input was a traversable then I would have to handle it differently. My particular issue was more complicated than that but that is the basic issue.

Tuesday, April 13, 2010

One of the most talked about features of Scala 2.8 is the improved Collections libraries. Creating your own implementation is trivial, however if you want your new collection to behave the same way as all the included libraries there are a few tips you need to be aware of.

Note: All of these examples can either be ran in the REPL or put in a file and ran

Starting with the simple implementation:

import scala.collection._

import scala.collection.generic._

class MyColl[A](seq : A*) extends Traversable[A] {

// only abstract method in traversable is foreach... easy :)

def foreach[U](f: A => U) = util.Random.shuffle(seq.toSeq).foreach(f)

}

This is a silly collection I admit but it is custom :).

This example works but if you test the result of a map operation (or any other operation that returns a new instance of the collection) you will notice it is not an instance of MyColl. This is expected because unless otherwise defined Traversable will return a new instance of Traversable.

To demonstrate run the following tests:

val c = new MyColl(1, 2, 3)

println (c mkString ",")

println(c mkString ",")

println(c drop 1 mkString ",")

// this two next assertions fail (see following explanation)

assert(c.drop(1).isInstanceOf[MyColl[_]])

assert((c map {_ + 1}).isInstanceOf[MyColl[_]])

Both assertions will fail. The reason for these failures is because the collection is immutable which dictates by necessity that a new object must be returned from filter/map/etc... Since the Traversable trait returns instances of Traversable these two assertions fail. The easiest way to make these methods return an instance of MyColl is to make the following changes/additions.

import scala.collection._

import scala.collection.generic._

/*

Adding GenericTraversableTemplate will delegate the creation of new

collections to the companion object. Adding the trait and

companion object causes all the new collections to be instances of MyColl

*/

class MyColl[A](seq : A*) extends Traversable[A]

with GenericTraversableTemplate[A, MyColl] {

overridedef companion = MyColl

def foreach[U](f: A => U) = util.Random.shuffle(seq.toSeq).foreach(f)

}

// The TraversableFactory trait is required by GenericTraversableTemplate

object MyColl extends TraversableFactory[MyColl] {

/*

If you look at the signatures of many methods in TraversableLike they have an

implicit parameter canBuildFrom. This allows one to define how the returned collections

are built. For example one could make a list's map method return a Set

Now instances of MyColl will be created by the various filter/map/etc... methods and that is fine as long as the new object is not required at compile-time. But suppose we added a method to the class and want that accessible after applying methods like map and filter.

Adding val o : MyColl[Long] = c map {_.toLong} to the assertions will cause a compilation error since statically the class returned is Traversable[Long]. The fix is easy.

All that needs to be done is to add with TraversableLike[A, MyColl[A]] to MyColl and we are golden. There may be other methods as well but this works and is simple.

Note that the order in which the traits are mixed in is important. TraversableLike[A, MyColl[A]] must be mixed in afterTraversable[A]. The reason is that we want methods like map and drop to return instances of MyColl (statically as well as dynamically). If the order was reversed then those methods would return Traversable event though statically the actual instances would still be MyColl.

Friday, April 9, 2010

In Scala 2.8 there is a useful annotation called 'elidable'. This annotation flags a method so that given certain compiler flags all calls to the method will be removed. This is handy if you are writing a logger. The log methods can be annotated so that when compiling for production all log calls below a certain level would be removed from the compiled code. Several of the methods in Predef are annotated with elidable. Specifically, assume, assert and require.

The elidable annotation takes an Int parameter which specifies the priority of the method. The lower the integer the more likely the method would be removed during compilation. The elidable object defines several values that are used in our example.

When compiling with the -Xelide-below , the compiler parameter will remove all calls to elidable methods value and below.

To try the following example copy the example into a scala file (elidable.scala for example) and compile as indicated below:

package example

import scala.annotation.elidable

import scala.annotation.elidable._

object ElidableExamples {

@elidable(ALL) def all = println("all")

@elidable(ASSERTION) def assertion = println("assertion")

@elidable(CONFIG) def config = println("config")

@elidable(FINE) def fine = println("fine")

@elidable(FINER) def finer = println("finer")

@elidable(FINEST) def finest = println("finest")

@elidable(INFO) def info = println("info")

@elidable(OFF) def off = println("off")

@elidable(SEVERE) def severe = println("severe")

@elidable(WARNING) def warning = println("warning")

}

object Main extends Application {

println("starting")

import ElidableExamples._

all

assertion

config

fine

finer

finest

info

off

severe

warning

println("ending")

assert(false, "boom!")

}

Output from scalac elidable.scala && scala example.Main

startingassertionoffendingjava.lang.AssertionError: assertion failed: boom! at scala.Predef$.assert(Predef.scala:93) at example.Main$.(elidable.scala:34) at example.Main$.(elidable.scala) at example.Main.main(elidable.scala)

startingassertionconfigfinefinerfinestinfooffseverewarningendingjava.lang.AssertionError: assertion failed: boom! at scala.Predef$.assert(Predef.scala:93) at example.Main$.(elidable.scala:34) at example.Main$.(elidable.scala) at example.Main.main(elidable.scala)

startingassertionoffsevereendingjava.lang.AssertionError: assertion failed: boom! at scala.Predef$.assert(Predef.scala:93) at example.Main$.(elidable.scala:34) at example.Main$.(elidable.scala) at example.Main.main(elidable.scala)

The last few topics all discussed variance in its different forms. The following is a cheat sheet of the where the different variances exist within a class.

See Variant positions 1 for a discussion on one position in a class that is a contravariant position.

The example is:

scala>class Output[+A] {def write(a : A) = () /*do write*/ }

In this example A in the method write is an contravariant position. Which means the previous definition is not legal because A is defined as Covariant in the class definition. In a class there are several positions with different variance characteristics. Here's the example from Programming in Scala:

If you remove the superscript + and - the above example actually compiles. The + and - indicate if the position is a covariant or contravariant position. Its not critical to memorize the positions (in my opinion). Just look it up as needed. The rule of thumb is that each nested position is inverted (flipped) value of it enclosing position.

Sunday, April 4, 2010

I just want to let everyone know that I am working hard on a Scala IO library right now and as such I want to dedicate all my spare time to doing that. So (as has been the case lately) I plan to only update the blog 2-3 times a week. Once done with the library I will try to increase the frequency of updates on the blog.

If you have any topics or code snippets you think would be fit good with the block please send them to me at jeichar.w@gmail.com.

Search This Blog

About Me

Jesse EicharI am a senior software developer at Camptocamp SA (Swiss office) and specialize in open-source geospatial Java projects. I am a member of the uDig steering committee and a contributor to Geotools and Mapfish. In addition I regularly work with Geoserver and Geonetwork.

In my free time I am a Scala enthusiast. I am working on the Scala IO incubator project and WebSpecs a Specs2 based testing framework for webapplications.