Estimation: “
“
(From the genius that is xkcd.com.)
Estimation: “
“
(From the genius that is xkcd.com.)
Ending the Era of Patronizing Language Design
I linked, indirectly, to this article the other day and, after reading it again, I agree completely. Well, I agree completely with the notion that we should stop accepting “we didn’t put that feature into the language because you’re too stupid to use it” from language designers.
You really should read the comments accompanying the article, some are wise, many are interesting, unsurprisingly many seem to be commenting on a totally different article.
Now, what this doesn’t mean is that every language should have every feature, it just means that presumed incompetence isn’t an acceptable reason for not having it. Languages need to be designed with taste, discrimination and a desire to facilitate developer productivity.
For too long we have been told by programming language designers that we should eat our steak with a spoon because knives are too dangerous.
What sort of features am I thinking of here? Well, Java is a major culprit of the “you’re too stupid” mindset.
Automatic memory management : This isn’t the sort of feature I’m talking about. This is an enabling feature, something added to the language to help developers. Does it have drawbacks? Sure it does, there are times when direct-to-the-metal can be useful. But a decision was made here to facilitate in one area and compromise in another.
Operator overloading : Can it be used for evil? Sure. So can talcum-powder.. that doesn’t mean we should ban it and force our babies to suffer from trench-nappy-region. There are many cases where operator overloading makes sense and its absence in Java is painful. Exhibit 1 ‘BigDecimal’.
Immutable Strings : Another case of “not what I’m talking about”. Mutable Strings can be useful and powerful, but not having them brings advantages too. This was a conscious decision.
No meta-model : Without a meta model programmers dive into byte code manipulation and magical “doesn’t work like anything else in the language” constructs like DynamicProxy. Can meta-programming be hard and weird? Sure, so is physics. Shall we ban that? It isn’t the same, I hear you cry. You’re damn right it isn’t. Those guys created the atom bomb, and we still let/encourage/train/pay people do it. Heck we teach physics to CHILDREN. There are times in this world, when nuclear fission is just plain useful.
The list goes on.
Sharp vs. Blunt Instruments: “If you want your team to produce great work and take responsibility for their decisions, give them powerful tools.”
(Via Glenn Vanderburg: Blog.)
Hallelujah brother Glen. Everyone say, “praise the power”. C’mon now, say it with me, “praise the power”.
As a tribute to Sir Humphrey, indeed the whole of the Ministry of Administrative Affairs, I shall endeavour to deliver this message in a suitably unhelpful format.
Sir Humphrey : “For those of you who’ve not seen it, and those of you who have - and therefor want to see it again - assuming, that is, the sanity, soundness, fitness, health, quality, control and general ‘fit for purpose’ utility of your mind, that is your brain, control centre, seat of consciousness etc. The greatest (a word I use not lightly, nor without appropriate consideration, contemplation and cogitation) comedy show of many, most, or indeed, perhaps all decades, including but not limited to those after the invention of television - although, of course, those decades before, preceding, that is, those that are, if you would, antecedent of the years and decades in question, are automatically disqualified on grounds of technical ineligibility which presupposes, induces and creates an inability to compete - has been released via iTunes.”
Jim Hacker : “Sorry, what was your point?”
Sir Humphrey : “Yes Minister has been released on iTunes. And you should go and buy it”
Jim Hacker : “Yes Minister?”
Sir Humphrey : “Yes, Minister.”
Jack Cough on Software: Scala over Ruby - My Debate Ends: This article struck a chord with me today.
I spent most of today flipping back and forward between Ruby and Scala. I’m working on a project where I’m writing some Ruby talking over sockets and streams and files and I needed something JVM flavoured on the other end.
The JVM end was just some driver code that was going in the bin. I had IDEA open because I was using it to write the Ruby side ( at which it is fantastic ) and a simple Scala script seemed easiest - that’s where my head has been recently so it seemed most natural.
Things did not go so well - the embedded Ruby that I was using was badly mangled and had chunks of the standard libraries missing. I ended up spending the day bashing away at various ways of solving the problem. With each change of direction I had to rework both the Ruby and the Scala side of the solution. I noticed something odd.
Version 1.0 was a bit faster to write on the Ruby side. I’m a better Ruby programmer than I am a Scala programmer, but that aside I feel that it was slightly easier to express the problem than in Scala. But as the day went on the Scala code became easier to work with whilst the Ruby code had good and bad patches. Significant refactorings or changes of approach often led to runtime errors in the Ruby code. This wasn’t a problem in the Scala code. The IDE, compiler and type system caught most of the problems well before I got the application running.
Have I abandoned Ruby forever? No, it is near and dear to my heart and it is still better for bashing out scripts for which there will be no version 2. The benefits of Scala didn’t become apparent until 4 to 6 hours into the piece.
Some questions come to mind:
How well would the Scala fare long term? I don’t know. It is possible that I won’t understand it tomorrow and that every day will have a 4 to 6 hour ramp up time. But I don’t think so. I think I’d reap more benefits tomorrow than I did today.
How would Java have fared? I worked on a similar problem the day before and I used Java. It was a pain in the patooty in many ways, but I’m not sure if it comes above or below the Ruby version though. Many of the same characteristics that Scala has were apparent in that session too. I am sure that I found the Scala experiment more productive - despite the fact that I’m a much, much better Java programmer than I am a Scala or Ruby programmer.
I’ve jumped ahead in the book. The next few sections cover a variety of different components where we could use the same sort of tricks with closures and extension methods to make the interactions a little nicer but I don’t think there’d be much value to that. I’ve skipped ahead to page 93 where we encounter forms for the first time.
Forms are interesting because they introduce bean-bindng - automatically associating form fields with properties of Java objects.
I’m a little surprised to find this in here, on one hand it feels like a step towards the ‘Naked Objects’ approach which I really like but on the other hand, I’m not sure why the Form abstraction is needed in a framework that has such powerful Ajax functionality. I have my suspicions that this is a holdover from an earlier time, a time when Vaadin was more request/response oriented. It is interesting nonetheless, and I’ll see where it leads me.
I am expecting to run into some problems here. Scala code doesn’t always look the way I’d naively hope from the Java side of the fence.
So, here we go. Version 1. Imagine we were building a Pirate administration tool…
package spike
import com.vaadin.Application
import com.vaadin.data.util.BeanItem
import com.vaadin.ui._
class Pirate {
private var name: String = ""
private var weight: Int = 0
def getName: String = {
return name
}
def setName(newName: String): Unit = {
this.name = newName
}
def getWeight: Int = {
return weight
}
def setWeight(newWeight: Int): Unit = {
this.weight = newWeight
}
}
class SpikeApplication3 extends Application {
override def init: Unit = {
val mainWindow = new Window("And now... a form.")
val form = new Form()
form.setCaption("This be the caption. Yes it be, it do!")
form.setDescription("What we 'ave 'ere is a tool fur the displayin' o' pirates.")
form.setItemDataSource(new BeanItem(new Pirate))
form.setValidationVisible(true)
mainWindow.addComponent(form)
setMainWindow(mainWindow)
}
}
That works pretty well. I defined a Pirate class and adhered to the gnarly Java syntax for defining Bean properties and, hey presto, we have a form with two bean properties nicely represented on it.
The property syntax is just plain fugly though. Let’s get to the Scala pimp action.
package spike
import com.vaadin.Application
import com.vaadin.data.util.BeanItem
import com.vaadin.ui._
import reflect.BeanProperty
class Pirate {
@BeanProperty var name: String = ""
@BeanProperty var weight: Int = 0
}
class SpikeApplication3 extends Application {
override def init: Unit = {
val mainWindow = new Window("And now... a form.")
val form = new Form()
form.setCaption("This be the caption. Yes it be, it do!")
form.setDescription("What we 'ave 'ere is a tool fur the displayin' o' pirates.")
form.setItemDataSource(new BeanItem(new Pirate))
form.setValidationVisible(true)
mainWindow.addComponent(form)
setMainWindow(mainWindow)
}
}
That’s much better. We’ve replaced the fuglyness with an annotation. This annotation is interesting. From a Scala perspective, it doesn’t really do anything. From a Java perspective there’s a world of difference. The annotation tells the scala compiler that the output should include Bean style getters and setters for the this property. In effect the annotation provokes the compiler into doing a chunk more work so that we don’t have to.
I’m not happy though. I always hated the Java convention whereby beans should have no-arg constructors. The number of bugs that I’ve seen stemming from improperly initialised objects is, well, it’s too damn many.
class Pirate(@BeanProperty var name: String, @BeanProperty var weight: Int)
There’s our Bean class, replete with two arg constructor. I like it.
Another experiment. Scala’s BeanDisplayName should be able to be used to change the label placed on the field - assuming the Vadiin developers have gone through the BeanInfo for the class rather than using simple reflection to guess at properties.
class Pirate(@BeanProperty var name: String, @BeanProperty var weight: Int) {
@BeanProperty @BeanDisplayName("Landlubbers put to the sword") var victims: Long = 0
}
Sadly this doesn’t work. The field that appears in the form is labelled Victims rather than ‘Landlubbers put to the sword’. Whether this is a hole in Vaadin, a problem with Scala, a problem with the Scala to Java integration or just because I screwed up I can’t say.
In part 4 of the Scala & Vaadin series I threw in the line “I believe that comments are, for the most part, an abomination” without really explaining it.
There are a couple of comments on that post that I think explain my position - and other people’s reaction - in more detail.
I was out shopping with my wife this morning. We popped into a craft store to allow her to pick up a few things for a project she’s undertaking.
I noticed this :

Which made me chortle a little. The fact that Kanban - Quality As Standard had made it into the realms of hand-crafted gift cards was surprising. Then my jaw dropped at the next card in the rack:

Wow! Waterfall and Kanban, right next to each other competing. Then I noticed this:

It turns out that nobody is buying Waterfall in the craft world. Nobody is buying it, no matter how it is packaged.


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.
Kent Beck asked some interesting questions around the behaviour of the software community with respect to ‘getting paid’.
I’ve been irked by the behaviour of the community on this subject for quite a while. Personally I blame paranoid ass-hats like this. Harsh but…
It has come to my attention that people have misinterpreted my last story.
When they told me they wanted me to spend hours in focus group meetings, I laughed at them and walked away. Anyone who didn’t would be in the low-wattage light-bulb category.
End of message.
A few weeks ago I was on holiday in Las Vegas. In one section of the casino I was staying at, there was an area run by one of the big US TV networks where they were testing out TV pilots and newly shot episodes of TV shows.
As you passed by, they would stop you and ask you if you’d like to help them choose the future of TV. I thought it might be amusing, so I took a leaflet and listened to a thirty second pitch. Spending an hour watching a show and giving feedback might be fun - it was near the end of the day and I was tired and footsore from sightseeing.
They started out with “we’ll give you $75 to go through our process”.. hmm, that made it even more attractive. I can have a seat and a beer and pay for dinner with the proceeds. Then came the kicker. After watching the show, you have to participate in FIVE focus groups, each lasting an hour or so.
It turns out that the reason most TV shows suck is because the people who review them are morons. You’re staying in a casino, paying two or three hundred dollars a night for a room, and you’re going to give up a whole day to review a TV show for seventy five dollars. Anyone who’s not a moron would conclude that this is a pretty bad deal.
Strangely, there were people queueing up to watch the shows… I looked at them, and judged them in the light of the information I had. I stand by my moron theory.
Firstly, I’d like to thank all the people who’ve said nice things about the first three parts - here, on twitter and on various news-groups. Of special note is Mark Harrah, the creator of SBT. Not only did he drop me a nice note, he made a change to SBT so that the issue whereby you couldn’t usefully run jetty in batch mode is solved. Now that’s service!
I’d also like to apologise to the people who’ve been reading my blog on the web. I realise that I need to change to a variable width column layout so that you can actually see all of the code. I’ll get to it soon… honest.
Last time I promised I’d talk about continuous compilation and deployment. This is pretty complex, so try to keep up.
Normally to compile all the code and run jetty you’d type:
~/code/spike : sbt > jetty-restart
Or some such. To get continuous compilation and deployment going you need to do this:
~/code/spike : sbt > ~ jetty-restart
See the tilde on the second line? That’s it. That sets up file watchers to watch for changed files/resources and executes the specified action when it detects them
Want to run your tests every time the code changes?
~/code/spike : sbt > ~ test
I’m sorry if you’d like an XML configuration file or something similar. We’re all out of complexity this evening, try again tomorrow.
Back to the Scala & Vaadin.
The next example, from page 40 of the Book of Vaadin is slightly more substantial. I’m hoping that Scala will let us make even bigger improvements to the code because we’ve more to work with.
The Java code:
public class WindowOpener extends CustomComponent implements Window.CloseListener {
Window mainwindow;
Window mywindow;
Button openbutton;
Button closebutton;
Label explanation;
public WindowOpener(String label, Window main) {
mainwindow = main;
final VerticalLayout layout = new VerticalLayout();
openbutton = new Button("Open Window", this, "openButtonClick");
explanation = new Label("Explanation");
layout.addComponent(openbutton);
layout.addComponent(explanation);
setCompositionRoot(layout);
}
public void openButtonClick(Button.ClickEvent event) {
mywindow = new Window("My Dialog");
mywindow.setPositionX(200);
mywindow.setPositionY(100);
mainwindow.addWindow(mywindow);
mywindow.addListener(this);
mywindow.addComponent(new Label("A text label in the window."));
closebutton = new Button("Close", this, "closeButtonClick");
mywindow.addComponent(closebutton);
openbutton.setEnabled(false);
explanation.setValue("Window opened");
}
public void closeButtonClick(Button.ClickEvent event) {
mainwindow.removeWindow(mywindow);
openbutton.setEnabled(true);
explanation.setValue("Closed with button");
}
public void windowClose(CloseEvent e) {
openbutton.setEnabled(true);
explanation.setValue("Closed with window controls");
}
}
public void init() {
Window main = new Window("The Main Window");
setMainWindow(main);
main.addComponent(new WindowOpener("Window Opener", main));
}
The free floating init() method is supposed to be placed into the Application class.
I’ve removed the comments and done a little tidying up of the structure: people have suggested that by not tidying the Java code in the earlier examples I was doing Java a disservice. I also removed the comments because I believe that comments are, for the most part, an abomination, a crutch that has removed the need for programmers to support their own weight and write clean code. As with most things, I could be wrong. I doubt it, but it is possible. I’m not egotistical enough to believe I’m never wrong. Just very, very rarely. Honest.
Transliteration:
package spike
import com.vaadin.Application
import com.vaadin.ui._
class WindowOpener(abel: String, main: Window) extends CustomComponent with Window.CloseListener {
var mainwindow: Window = null
var mywindow: Window = null
var openbutton: Button = null
var closebutton: Button = null
var explanation: Label = null
mainwindow = main
val layout = new VerticalLayout()
openbutton = new Button("Open Window", this, "openButtonClick")
explanation = new Label("Explanation")
layout.addComponent(openbutton)
layout.addComponent(explanation)
setCompositionRoot(layout)
def openButtonClick(event: Button#ClickEvent): Unit = {
mywindow = new Window("My Dialog")
mywindow.setPositionX(200)
mywindow.setPositionY(100)
mainwindow.addWindow(mywindow)
mywindow.addListener(this)
mywindow.addComponent(new Label("A text label in the window."))
closebutton = new Button("Close", this, "closeButtonClick")
mywindow.addComponent(closebutton)
openbutton.setEnabled(false)
explanation.setValue("Window opened")
}
def closeButtonClick(event: Button#ClickEvent): Unit = {
mainwindow.removeWindow(mywindow)
openbutton.setEnabled(true)
explanation.setValue("Closed with button")
}
def windowClose(e: Window#CloseEvent): Unit = {
openbutton.setEnabled(true)
explanation.setValue("Closed with window controls")
}
}
class SpikeApplication2 extends Application {
override def init: Unit = {
val main = new Window("The Main Window")
setMainWindow(main)
main.addComponent(new WindowOpener("Window Opener", main))
}
}
I’ve dropped this into a new file on my system src/main/scala/spike/Application2.scala.
To get it to run, you need to change the web.xml. Change the line:
<param-value>spike.SpikeApplication</param-value>
to:
<param-value>spike.SpikeApplicatio2n</param-value>
Yup, there’s a 2 on the end of the class name now. Fire up the app and have a look - we’re going to get pimping!
So, what do I want to change first? Well, if you look where the Buttons are instantiated you’ll see something that made my skin crawl. In an earlier episode I talked about the ugly anonymous inner class usage, but mentioned that it was probably the best choice. Best of a bad lot in Java as it were. This is one of the other choices. The button is being instantiated with a target object and a method name so that the button can call the method when clicked. I know why people do this, I’ve done it myself and in Ruby or Smalltalk it’d be idiomatic, people would be prepared for it, and it wouldn’t get messed up. In Java having method names as strings is always a bad idea. Amusingly, as if my sub-consience was trying to prove me right, I misspelled one of the method names not once, but twice. And when I ran the app.. it didn’t work.
Using method names as Strings and calling them by reflection isn’t a good idea. There are so many things that can go wrong - signature changes, misspellings, changes in visibility level, return type changes, exceptions etc. In Java, the belief that static typing protects you from these sort of problems means that developers just aren’t prepared for it. Thankfully, the SButton class we created earlier solves this problem in a nice type-safe, statically defined way. Goodbye reflection invocation.
One of the ugly parts about using reflection is that the methods you’re calling back to have to be public so that the reflector can see them. This leads to classes with odd “don’t call me I’m not what you think” methods.
This class also implements the WindowListener interface because it needs to respond somehow, and some of the class’ state is modified as a result of the callback. Implementing this interface here was the expedient thing to do, but it does mean that the class has a broader interface, implements an interface so that it can comply with the demands of its own internal workings and, if it wanted to listen to multiple child windows would need to jump through hoops to figure out which child window it was that was being close. I’m gonna get my closure tools out again.
package spike
import com.vaadin.Application
import com.vaadin.ui._
class SWindowCloseListener(action: Window#CloseEvent => Unit) extends Window.CloseListener {
def windowClose(event: Window#CloseEvent) = {
action(event)
}
}
class WindowOpener(private val mainWindow: Window) extends CustomComponent {
private val openbutton = new SButton("Open Window", _ => createSubWindow)
private val explanation = new Label("Explanation")
private val layout = new VerticalLayout()
layout.addComponent(openbutton)
layout.addComponent(explanation)
setCompositionRoot(layout)
private var subWindow: Window = null
private def createSubWindow: Unit = {
subWindow = new Window("My Dialog")
subWindow.setPositionX(200)
subWindow.setPositionY(100)
subWindow.addComponent(new Label("A text label in the window."))
subWindow.addComponent(new SButton("Close", _ => closeSubWindow))
subWindow.addListener(new SWindowCloseListener(_ => onSubWindowClose))
mainWindow.addWindow(subWindow)
openbutton.setEnabled(false)
explanation.setValue("Window opened")
}
private def closeSubWindow = {
mainWindow.removeWindow(subWindow)
openbutton.setEnabled(true)
explanation.setValue("Closed with button")
}
private def onSubWindowClose = {
openbutton.setEnabled(true)
explanation.setValue("Closed with window controls")
}
}
class SpikeApplication2 extends Application {
override def init = {
val main = new Window("The Main Window")
main.addComponent(new WindowOpener(main))
setMainWindow(main)
}
}
In the tidy up, we’ve gone from five instance variables down to four ( three of them immutable values), lost a constructor parameter that didn’t do anything, created a nice little reusable listener class, removed risky reflection invocation and removed ALL of the new public methods and properties. The interface of our class is now identical to the interface of our super class.
Recent Comments