I was lucky enough to present at Surge 2012, a great devops focused conference put on by OmniTi in Baltimore. I got a chance to talk about some of the stuff I’ve been doing at work, namely a fairly novel distributed system we’re building named Sirius.
I’d never been before, though some of my cow-orkers have, and seemed to enjoy it. I felt a little big Groucho Marx about the whole thing, not really sure if I wanted to go to a conference that would have me as a presenter, but I ended up being glad I did.
One fun moment:
At a bar after the speaker’s dinner, I notice the guy sitting next to me is really into the ball game. We start talking about baseball, how wonky the one game playoff is, how crazy things will be next year with all the inter-league play. Somehow we got from there to DTrace, the tracing framework for Solaris, and other operating systems.
Turns out the guy I was talking to knew his DTrace stuff, I mean really knew it. A few minutes into the conversation I realized I was talking to one of the co-authors of DTrace, a guy named Bryan Cantrill.
There’s a scene in just about any Victorian period movie where a gentleman take off his glove and slaps another gentleman across the face in it. Or, if they’re going for historical accuracy, perhaps just throws it on the ground at his feet. A duel follows shortly after.
programmer, claim strong typing is good. If you’re talking to a Java programmer, claim weak typing is good. Then chose your weapons.
Where was I? Right, Unicorns. They don’t exist. Neither does strong typing. Or weak typing. More accurately, there does not
currently exist a useful definition of the two terms that is widely accepted, and which can be used as the basis for a rational conversation about their relative merits. This is why the terms are only good for starting fights.
Don’t believe me? Let’s take a look at the definitions provided by that ultimate source of truth, Wikipedia.
In computer science and computer programming, a type system is said to feature strong typing when it specifies one or more restrictions on how operations involving values of different data types can be intermixed. The opposite of strong typing is weak typing.
Great, so it’s strongly typed if it “specifies one or more restrictions on how operations involving values of different types can be intermixed”. And its opposite is weak typing. Let’s see what Wikipedia has to say about that.
In computer science, weak typing (a.k.a. loose typing) is a property attributed to the type systems of some programming languages. It is the opposite of strong typing, and consequently the term weak typing has a number of different meanings, just as “strong typing” does.
Well okay then, so we’ve confirmed that weak typing is indeed the opposite of strong typing. That should clear things up. Let’s talk about something else.
They all appear to be adding an integer and a decimal number together, but all is not as it seems.
In most languages, an integer and a floating point number are very different things, at least to the compiler. Signed integers are generally represented as two’s complement while decimals are represented with the IEEE’s floating point standard.
This means that to a computer, 1 and 1.0 may not be the same thing. One may be two’s complement, and the other floating point, so 1 and 1.0 may actually be represented by a different sequence of bytes! You can’t directly add them together.
What Ruby and Scala both do is implicitly convert the two’s complement integer into a floating point number before doing the addition. This is most apparently in the Scala case, where Scala tells us that the result of adding together an Int and a Double is, indeed, a Double.
Implicit conversions are at the heart of most discussions on strong and weak typing, as is hinted at by Wikipedia definition of strong typing - “…specifies one or more restrictions on how operations involving values of different data types can be intermixed”. The intuition here is that if you can’t reasonably perform an operation on values of two different types, possibly by implicitly converting one type to another, than the language should disallow it.
The problem with that definition is that it fits almost every language, for some definition of reasonable. Without implicit conversions, we’d lose a whole ton of convenience, like adding an integer and double together, or concatenating a number on to a string, or assigning an unboxed int to an Integer in Java. However, the more aggressive a language gets with its implicit conversions, the more dangerous they can get. Java is rather conservative here which is why its often called strongly typed, though the conversion from unboxed to boxed numbers, for instance, can have very surprising effects on a program’s memory usage and runtime.
Anyhow, that’s why most discussions about strong and weak typing just degenerate into anarchy. The only workable definition is that a language is weakly typed is that it does implicit conversions you consider bizzare, and it’s strongly typed if it doesn’t. Computer scientists don’t seem to use the terms anymore, they prefer to talk about the type safety of a given type system.
As a side note, Scala give programmers the power to define their own implicit conversions. Here, for instance, is an implicit conversion that will convert from a Scala function to a Java Runnable.
With that implicit defined somewhere in a project, the Scala compiler will convert Scala functions to Runnables when it has a Function and needs a Runnable. It may seem that exposing this sort of power to application developers is dangerous, but rest assured, it was added to the language only after it was discovered that shipping butcher knives without handles to the entire Scala userbase would be prohibitively expensive.
At work, we’ve been doing a lot of our new stuff in Scala lately. One thing that we’re writing is a client, packaged up as a jar, that needs to work from both Scala and Java code. For the most part, the interop between Java and Scala is smooth, but there are occasional strange hiccups.
Scala hasn’t really given me much as much cause to define custom exceptions as I find in Java. Partially this is because we’re doing a lot of work in Akka, which has an Erlang like ‘let it fail’ model. Part of it has to do with Scala’s Option, I find myself returning a None in a lot of situations where I might have thrown an exception in Java.
So when I finally had to create a custom exception for Java interop, I ran into one a bit of a rough edge. Creating a simple custom exception class is, of course, a one-liner.
But next to impossible to do in Scala. Scala requires that every class have a single primary constructor, and that constructor is the only one that’s allowed to call a superclass constructor.
The cleanest thing I could come up with was to use the one argument constructor, which only sets a message, and then set the cause after it was constructed. I wrapped that logic up into some methods on the Exception’s companion object so I could use it as a factory.