Index
Elsewhere
Navigation
« Kanban v's Waterfall - The Craftworld Perspective | Main | Is wanting to be paid such a crime? »
Friday
Jul032009

Adventures with Scala and Vaadin - Part 5

The next few examples in the book cover adding event handlers in more detail. I think we've beaten the 'closures are definitely the best way to do this' horse until it'd like us to stop so... I'll move farther on.

When we get to Chapter 5 we come across an interesting section on resizing components. All components implement the Sizeable interface. The sizeable interface has methods for setting the height and width of the component. There are two choices for each of these methods - set the value as a float along with a unit of measurement, or set the value using a String with the value and the unit.


component.setWidth(12.5, Sizeable.UNITS_EM);
component.setHeight("23%");


I don't find either of these choices to be that inspiring. Not bad, each is just a little sub-optimal, for my particular sensibilities. I'd rather type something that looks like


component.setWidth(7 pixels)


It is a small change, but one that I think makes the code look a little bit clearer, a little bit more expressive. So how do we make it work? Implicit conversions to the rescue. So what's an implicit conversion? In short, by explicitly importing an implicit conversion into a scope, you give the compiler the ability to transform one specific type into another specific type if it needs to. That's a hard sentence to understand, and it probably isn't even correct ( any Scala boffins that want to correct me, feel free ). In practice it is easier to understand. Here's the code that I've added to VaadinUtils.scala:


class Dimension(private val value: Number) {
def pixels : String = value + "px"

def percent : String = value + "%"
}

object Dimension {
implicit def intToDimension(value: Int): Dimension = new Dimension(value)

implicit def doubleToDimension(value: Double): Dimension = new Dimension(value)
}


And then in the imports at the top of my class I import Dimension._ and, presto, I can now use 21 pixels or 34.5 percent ( or 21.pixels or 21.pixels() ) in my code.

What's really going on? Well, as I understand it, when Scala sees an int with a pixels() method being called on it, it scouts around for an implicit conversion that it could apply that would make the code compile. Now, I'm sure that this sounds scary and dangerous, that's why Scala is very conservative about conversions.

You'll notice that I've had to define an implicit conversion for both Int and Double because Scala won't even perform that conversion automatically. One of the things I like about Scala is that it gives you power whilst trying to minimise risk. Neat.

References (17)

References allow you to track sources for this article, as well as articles that were written in response to this article.
  • Response
    investor ascending michele plaza naive theorists hosts chile arrivals jamali front okalkanmeb
  • Response
    Response: www.miller-adv.com
    Hi,Carl from Timeshare New York.Thanks for commenting on my website.I just thought its better for me to visit back to say thanks here:)
  • Response
    If you appreciate football, you most likely have a favorite team from the National Football League or two and have a list of players who like to have noticed.
  • Response
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Response: reverse mortgages
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Response: Belinda Broido
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Response: Belinda Broido
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Response: Belinda Broido
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Response: Belinda Broido
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Response: Belinda Broido
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Response: belinda broido
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response
    Response: Belinda Broido
    Rob Lally : Robert Lally : Renaissance Technologist - Blog - Adventures with Scala and Vaadin - Part 5
  • Response

Reader Comments (4)

Wow... Scala is just really expressive. If we just have had this expressiveness when designing the Vaadin core API:s in 2002...

July 4, 2009 | Unregistered CommenterJoonas

Hmm, sounds nice that you can do stuff like that, and I find it intriguing that you implemented it, but what's the added value? At readability, "20%" or "10px" tells exactly what they mean. At writeability "%" and "px" are just shorter than "percentage" and "pixels". I find the effort inspiring but can't see the solution being more than the suggested "sub-optimal".

July 5, 2009 | Unregistered CommenterPeppe

A great question Peppe. And here's the answers.

1) With the String version, I could enter any arbitrary string and it would compile:

componentSetWidth("I like chicken soup")

With the Scala implicit version you have strict compile time type checking so there's no way to enter an invalid value.

2) My IDE can provide me with code completion with the Scala version so with respect to typing.. you can do less and you don't need to remember all of the possibilities. There are in fact about 8 or so different measurement schemes that can be used and I don't know what they all are. So in-code discoverability is a win here.

3) If it gets into a competition about typing less, I could have called the pixels version px and then I'd be typing '4 px' which is four characters as opposed to the five characters for "4px". The % method is already in use in Scala as a binary operator on numbers, so I'll have to check if I could add an arbitrary unary version with a different return type.

Great question!

July 5, 2009 | Unregistered Commenterrob

Ah, I guess the whole post didn't get through to me on the first run, as I seemed to have missed some points here. Maybe my inexperience with scala, and reading of it at the middle of the night had an effect on my interpretation skills.

I mistook the enumerated data types for something else - but now I see the point in doing this.

You know, the Sizable has the methods setWidth(float width, int unit) etc. which is basically the same as what you have here. For example, you can write textfield.setWidth(5,TextField.UNITS_PIXELS);. It doesn't look as nice as setWidth(7 pixels) but works in the same manner. i always use "5px" because it is just faster to write than fetchin that constant etc., and looks cleaner. I'd say your solution is easier to use with the benefits of restricted data types.

Nicely done and I stand corrected! :)

July 5, 2009 | Unregistered CommenterPeppe

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
All HTML will be escaped. Hyperlinks will be created for URLs automatically.