Thursday, November 12, 2009
ScalaModules slides from W-JAX 09 online
There were a lot of interesting talks at the OSGi Day at W-JAX. If you are interested in the slides of my ScalaModules talk you can take it from here: http://www.slideshare.net/heiko.seeberger/wjax-09-scalamodules
Wednesday, November 11, 2009
Lift slides from W-JAX 09 online
The Scala Day at W-JAX was a great success: Many cool talks and lots of interested folks. If you are interested in the slides of my Lift talk you can take it from here: http://www.slideshare.net/heiko.seeberger/wjax-09-lift
Friday, October 16, 2009
Scala 2.8: Be more concise with named and default arguments
Scala 2.8 will bring quite a lot of interesting new features, e.g. redesigned collection libraries, named and default arguments, support for continuations, a pimped REPL, etc. In the following I will show how named and default arguments enable us to write our Scala code even more concisely than before.
Let's flesh out an example in the 2.7 style: An order with an ID, order items and a shipping mode.
The order's ID shall be "mandatory" while we want to allow for defaults for the item list and the shipping mode. Hence we have to provide some auxiliary constructors.
As you can see, now it is possible to create an order by only giving the ID, e.g.
will create an order with the items set to the empty list (OK, this does not make too much sense in practice) and the shipping mode set to standard shipping.
On the one hand that's nice. But on the other hand the code is blown up significantly and it will take the reader some time to reason about the different possibilities to create an order, what is mandatory and what is optional with defaults.
Scala 2.8 let's us define default values with the class (or method) parameters by simply putting the default values behind the type.
Now we can leave out the arguments for which defaults are defined, e.g.
will again create an order with no items and standard shipping. But this time there is no auxiliary constructor necessary to achieve that. Wow!
But how can we give the shipping mode and leave out the items? Looking at the order of the parameters in the primary constructor it is obvious that we have to give the item list before the shipping mode.
This is where named arguments enter the game. We simply prepend an argument value with its name, e.g.
This way Scala knows how to get things right. Wow!!
Let's flesh out an example in the 2.7 style: An order with an ID, order items and a shipping mode.
case class Order27(id: Long,
items: List[Item],
mode: ShippingMode)
case class Item()
sealed trait ShippingMode
case object StandardShipping extends ShippingMode
case object ExpressShipping extends ShippingMode
case object OvernightShipping extends ShippingMode
The order's ID shall be "mandatory" while we want to allow for defaults for the item list and the shipping mode. Hence we have to provide some auxiliary constructors.
case class Order27(id: Long,
items: List[Item],
mode: ShippingMode) {
def this(id: Long, items: List[Item]) =
this(id, items, StandardShipping)
def this(id: Long, mode: ShippingMode) =
this(id, Nil, StandardShipping)
def this(id: Long) =
this(id, Nil, StandardShipping)
}
As you can see, now it is possible to create an order by only giving the ID, e.g.
val order = Order27(1)
will create an order with the items set to the empty list (OK, this does not make too much sense in practice) and the shipping mode set to standard shipping.
On the one hand that's nice. But on the other hand the code is blown up significantly and it will take the reader some time to reason about the different possibilities to create an order, what is mandatory and what is optional with defaults.
Scala 2.8 let's us define default values with the class (or method) parameters by simply putting the default values behind the type.
case class Order28(id: Long,
items: List[Item] = Nil,
mode: ShippingMode = StandardShipping)
Now we can leave out the arguments for which defaults are defined, e.g.
val order = Order28(1)
will again create an order with no items and standard shipping. But this time there is no auxiliary constructor necessary to achieve that. Wow!
But how can we give the shipping mode and leave out the items? Looking at the order of the parameters in the primary constructor it is obvious that we have to give the item list before the shipping mode.
val order = Order28(1, HERE GOES THE ITEM LIST, OvernightShipping)
This is where named arguments enter the game. We simply prepend an argument value with its name, e.g.
val order = Order28(1, mode = OvernightShipping)
This way Scala knows how to get things right. Wow!!
Saturday, September 12, 2009
Invitation to improve ScalaModules's DSL
Over the last months the ScalaModules team has worked on the upcoming 2.0 release. There will be a lot of improvements, e.g. auto-registration of service interfaces, operator notation, filters as objects and the user guide transferred to the Wiki. We are not ready for a final release yet, but most things should already be fairly stable.
There is still one thing we are racking our brains over a lot and maybe one of you could come up with a better solution that we have got right now. The new API for registering services offers auto-registration of service interfaces, such that there is no need to explicitly define the service interface(s). The following snippet will register the service greeting under the service interface Greeting, because greeting implements Greeting.
trait Greeting ...
val greeting = ...
ctx register greeting
Of course there are times when you want to explicitly register a service under a certain service interface. Now it would be very nice to write something like
ctx register greeting as classOf[AnotherInterface]
But this will not work in the current implementation, because register will be executed before as, which will register greeting under Greeting, just like above. Hence you have to use parenthesis like
ctx register (greeting as classOf[AnotherInterface])
Of course we have come up with a nice operator notation which takes the neccessary precedence into account. You could register greeting under the service interface AnotherInterface like this
ctx < greeting / classOf[AnotherInterface]
There is no need to use parenthesis here, because / will be executed first, because its precedence is higher than <.
But we would still like to get rid of the parenthesis in the "wordy" style. Roman already came up with an idea which you can take from the ScalaModules Google group. But when it comes to using as and withProps at the same time this is not adequate. So the question is, whether you have an idea how we could write something like
ctx register as classOf[AnotherInterface] withProps ("x" -> "y")
I am looking forward for your suggestions!
OSGi-fied Scala libraries updated to 2.7.6
Now that we have got Scala 2.7.6 I also updated the OSGi version of the Scala libraries. Please take it from the scala-tools.org Maven repository.
Currently there is an ongoing discussion about modularizing the official Scala code base, just take a look at the scala-internals mailing list. Hopefully we will see some success soon which might make the extra OSGi version obsolete though. But right now these extra OSGi-fied libraries are the way to go if you want to run OSGi on Scala or Scala on OSGi.
Monday, June 22, 2009
OSGi on Scala slides from OSGi DevCon Europe 09 online
In my former blog post I reasoned about whether I should do a live demo of OSGi on Scala / ScalaModules at OSGi DevCon Europe 09. As I received very positive feedback from the community (thanx for that!) I decided to go for it. Now I just finished my short talk and everything (at least the hacking part) went fine. For those not able to attend, please find the slides (which try to give you some live feeling) at my Slidespace.
Tuesday, June 16, 2009
Running OSGi and ScalaModules in Scala's REPL
Next Monday I will talk about OSGi on Scala at OSGi DevCon Europe 09. As I have already given this talk twice (OSGi DevCon 09 and JAX 09), I am currently searching for some kind of fresh and cool style. Sitting in a very lonely German town I have come up with a crazy idea: Why not do the (short) talk using Scala's REPL (the interactive Scala console) instead of slides? To be honest, I am not yet sure whether to go this way, but my trials were very facinating and hence I would like to share my experiences with you.
OK, one step back. What exactly am I talking about? Well, fairly simple: Run the Scala REPL, launch OSGi (Felix, because it is very easy to launch/embed) to get a BundleContext (of the system bundle) and do some ScalaModules tricks to show the power of this DSL for OSGi.
In order to have Felix and ScalaModules on the classpath we have to copy felix.jar (currently using 1.8.0), scalamodules-core-1.1-SNAPSHOT.jar and scalamodules-util-1.1-SNAPSHOT.jar to a local directory and run Scala like this:
scala -cp felix.jar:scalamodules-core-1.1-SNAPSHOT.jar:scalamodules-util-1.1-SNAPSHOT.jar
scala>
First let's import some important stuff:
scala> import org.apache.felix.framework._
import org.apache.felix.framework._
scala> import org.scalamodules.core.RichBundleContext._
import org.scalamodules.core.RichBundleContext._
Then let's create and start Felix and get the BundleContext (which subsequently will be implicitly converted into a RichBundleContext):
scala> val felix = new Felix(null)
felix: org.apache.felix.framework.Felix = org.apache.felix.framework [0]
scala> felix.start
scala> val ctx = felix.getBundleContext
ctx: org.osgi.framework.BundleContext = org.apache.felix.framework.BundleContextImpl@e0c389
Then let's create a service interface:
scala> trait Greeting { def hello: String }
defined trait Greeting
Now let's use ScalaModules to (try to) get a Greeting service and use it. If you are experienced in OSGi you will know that for this task you would have to get a ServiceReference, check for null, get the service, check for null again and finally unget the ServiceReference again => Fairly low-level and involved. Now look at ScalaModules:
scala> ctx getOne classOf[Greeting] andApply { _.hello } match {
| case Some(s) => println(s)
| case None => println("No Greeting service available!")
| }
No Greeting service available!
OK, now let's register a Greeting service:
scala> val greeting = new Greeting { def hello = "Hello" }
greeting: java.lang.Object with Greeting = $anon$1@6159e9
scala> ctx registers classOf[String] theService greeting
found : java.lang.Object with Greeting
required: String
ctx registerAs classOf[String] theService greeting
^
As you can see, service registration with ScalaModules is type-safe at compile time. Hence let's do it right now and try to use it once more:
scala> ctx registerAs classOf[Greeting] theService greeting
res4: org.osgi.framework.ServiceRegistration = ...
scala> ctx getOne classOf[Greeting] andApply { _.hello } match {
| case Some(s) => println(s)
| case None => println("No Greeting service available!")
| }
Hello
There a lot of other things we could do the easy way using ScalaModules instead of OSGi API. I will show some more of these at my talk at OSGi DevCon Europe 2009, but first I have to decide whether using REPL for the talk is a good idea. What do you think?
Subscribe to:
Posts (Atom)
