Tag Archives: java

Criticizing programming languages

Here are snippets from two conversations I had recently:

20:03 < psnively> DRMacIver: I do think of you as taking a “Scala is one of the few languages worth criticizing” stance.

llimllib @DRMacIver So by my count, you’ve been in public arguments over the quality of Scala, Java, Ruby, Lua, Haskell, and OCaml? Missing any?

psnively’s comment is of course patently untrue. I criticize all sorts of languages. It just happens that Scala is one of those I use the most (at least in my free time), so I tend to criticize it more often than others. It’s true that as I rather like it I hold it to higher standards, but I feel no problem with criticizing other languages. :-)

llimllib’s comment is much more close to home. I get into arguments about languages all over the place. The problem is that:

  • All languages have problems with them
  • There are very few languages which don’t have something good about them as well

So the first point gets me into arguments with the people who love the language, the second gets me into arguments with people who hate it. I really can’t win. :-)

So, just to piss everyone off, I figured I’d write a post about the different programming languages I have opinions on. The structure of this will be simple: For every language I feel like I’ve used enough (or at least know enough about and have used some), I will write four items: Two saying what’s good about it, two saying what’s bad about it. These points are not intended to be the best or worst things about the language, or even neccessarily representative. They’re just something that has struck me as good or bad. Also, the format practically guarantees that I’m probably not saying anything anyone else hasn’t said a few dozen times already. :-)

Scala

Good:

  • Very interesting modularity features
  • Implicit arguments are great.

Bad:

  • The standard library is pretty embarrassing
  • It’s very easy for it to look like Java with weird syntax, particularly when using Java libraries.

Haskell

Good:

  • Extremely powerful and interesting type system
  • Purity enforced at the language level often makes it much easier to write correct code

Bad:

  • Really weak support for modularity
  • Aspects of the type system make it difficult to reuse nearly identical code across different contexts (consider sort vs. sortBy and map vs. mapM).

Ruby

Good:

  • Flexible syntax and semantics make it easy to write some very terse code
  • Makes general purpose scripting tasks very easy to hack together

Bad:

  • Namespacing issues abound, between open classes and a tendency to stomp all over the global scope.
  • The implementations.

Java

Good:

  • High quality implementation, with very good JIT and garbage collector.
  • Very rich ecosystem with lots of libraries.

Bad:

  • Bindings to native libraries tend to be rather low quality or non-existent (JNI is a pain)
  • Their closest Java equivalents typically are too

C

Good:

  • Gives you a lot of fine grained control over details that higher level languages hide
  • High performance native code compilers for just about every platform ever

Bad:

  • Almost no capability for abstracting over type.
  • Language level support for modularity basically doesn’t exist – namespacing by prefixing your function names, yay.

Ocaml

Good:

  • Provides a lot of shiny new features over standard ML – lazy evaluation, row polymorphism, polymorphic variants, etc
  • Very powerful module system (which I’ll admit to not entirely understanding)

Bad:

  • If you ignore the shiny new features, the core language is basically a worse Standard ML.
  • Although it has a justified reputation for writing high performance code, this seems to be only true if you write it as if it were C.

Lua

Good:

  • Borrows many more features from functional languages (tail calls, lexical scoping, etc) than most of its peers.
  • Very embeddable, rendering it very easy to use in the context of applications where the core is written in other languages.

Bad:

  • Weirdly deficient standard library (I know this is related to ease of embedding, as it seems to be the result of a desire to keep Lua small)
  • The language can be very verbose in places – consider the use of “local” to mean “Hey, I like not stomping all over the global scope”.

Python

This one is a bit weak, as I’ve only really used python in a few contexts, and haven’t really formed any strong negative opinions about it aside from a generic mild dislike. :-)

Good:

  • Has a lot of really cool libraries / projects built on top of it. (NLTK, NumPy, Sympy, pygame, etc).
  • The batteries included philosophy of the standard library is very appreciated.

Bad:

  • I find the “there is only one way to do it” attitude of community very dogmatic.
  • I’m not a big fan of the syntax. (I know, I know).

SQL

Good:

  • Forms a nice back end for a data processing app
  • Extremely good for constructing ad hoc queries against your data model

Bad:

  • Dear god can it be verbose.
  • Total lack of standardization a pain in the ass.

Javascript

Good:

  • Pretty decent support for functional programming
  • The prototype based OO is interesting and useful.

Bad:

  • Really weird scoping issues in places (particularly behaviour of globals and “this”).
  • The implementations are weak and inconsistent

And there we have it. :-) Some of these I could probably say a lot more good and bad about, some of them I struggled a bit on one side or the other and probably couldn’t, but those tend to be the languages I’ve used the least (in particular I’ve used Lua, Python and OCaml dramatically less than I have the others on the list).

This entry was posted in programming and tagged , on by .

A cute Scala hack

class ErrRef[S](s : S){
  private[this] var contents : Either[Throwable, S] = Right(s);
 
  def update(value : =>S){
    contents = try { Right(value) } 
              catch { case (e : Throwable) => Left(e) }
  }
 
  def apply() = contents match {
    case Right(s) => s;
    case Left(e) => throw e.fillInStackTrace();
  }
}
 
object ER{
  def apply[S](s : S) = new ErrRef(s);
}

And using it…

scala> ER(1)
res0: ErrRef[Int] = ErrRef@a96606
 
scala> res0()
res1: Int = 1
 
scala> res0() = 3
 
scala> res0()    
res3: Int = 3
 
scala> res0() = { println("Hello world"); 3} 
Hello world
 
scala> res0()                               
res5: Int = 3
 
scala> res0() = error("Lets see what happens here...")
 
scala> res0()
java.lang.RuntimeException: Lets see what happens here...
	at ErrRef.apply(RefExcept.scala:11)
	at .<init>(<console>:6)
	at .<clinit>(<console>)
	at RequestResult$.<init>(<console>:3)
	at RequestResult$.<clinit>(<console>)
	at RequestResult$result(<console>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcc...
scala> res0() = throw new IllegalArgumentException("Go away")
 
scala> res0()
java.lang.IllegalArgumentException: Go away
	at ErrRef.apply(RefExcept.scala:11)
	at .<init>(<console>:6)
	at .<clinit>(<console>)
	at RequestResult$.<init>(<console>:3)
	at RequestResult$.<clinit>(<console>)
	at RequestResult$result(<console>)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorI...
This entry was posted in programming and tagged , on by .

A curious fact about overloading in Scala

So I was taking a look at the Scala Array source code, as part of research for a forthcoming blog post (coming soon to a drmaciver.com near you) when I suddenly realised something. Then I suddenly had a WTF moment.

The scala.Array object has a method appy(xs : Int*) : Array[Int], and a method appy(xs : Double*) : Array[Double], and… etc. i.e. it has an overload for each value type and one for the reference types.

Something like this:

object Overload{
  def foo(xs : String*) = "foo";
  def foo(xs : Int*) = "bar";
}

Um.

/home/david/Foo.scala:3: error: double definition:
method foo:(Int*)java.lang.String and
method foo:(String*)java.lang.String at line 2
have same type after erasure: (Seq)java.lang.String
  def foo(xs : Int*) = "bar";
      ^

See, Scala varargs use Seq, so all varargs erase to the same thing.

So how the hell is scala.Array working? Is it compiler magic?

Well, sortof compiler magic. It’s a compiler magic you too can use. Lets change the above code slightly:

object Overload{
  def foo(xs : String*) = "foo";
  def foo(xs : Int*) = 3;
}

This compiles and works fine.

So, what’s going on here?

Well, although this fact is visible only as an implementation detail in most languages, the JVM actually lets you overload based on return type. Two methods are considered identical if they have precisely the same (erased) argument and return types. And although Scala doesn’t let you overload based on return type directly, it seems it will happily accept methods whose arguments erase to the same thing as long as their return types don’t.

This is a bit strange.

This entry was posted in programming and tagged , , on by .

Reusing Java’s tools: Cobertura and Scala

I’ve recently been writing some collection implementations for Scala which will hopefully go in the standard library in the upcoming release. Naturally I want to make sure that I tested the hell out of them, so I’ve been writing a reasonably large number of ScalaCheck tests to test the code and make sure it does what I want it to. Earlier I realised I should probably be doing some sort of coverage checking to make sure I had tested things adequately so thought I’d see how easy it would be to plug Cobertura into a Scala project. And I have good news! The answer is: Essentially trivial.

There were a few minor issues that cropped up while doing it:

  • Cobertura strips scala specific metadata out of the class files. This means that you must compile everything first, including your unit tests, before instrumenting code.
  • Scala does a lot of name mangling and generates a lot of classes with weird names. Cobertura naturally doesn’t understand the mapping back to Scala code, so you’ll see the mangled names. They’re not usually that hard to figure out.
  • Cobertura won’t be able to find your source files if you don’t follow Java directory conventions for packages.

Other than that, it all works fine. You get per line coverage information for your source files, decent per package and per class reports, etc. No problem.

Unfortunately my coverage wasn’t nearly as good as I hoped, so I’ll probably have to write a bunch more tests before I submit a patch.

Update: Actually, the line number reporting for Cobertura + Scala appears to be really bad, and often really hard to decipher. But it’s still a nice tool, and actually helped me catch some bugs.

This entry was posted in programming and tagged , , on by .

Unsigned comparison in Java/Scala

Java (and consequently Scala) lack unsigned integer types. Most of the time this isn’t an issue – the majority of the operations you’re likely to care about (addition, subtraction, bitwise operations) work the same regardless of whether you treat the integer as unsigned. There are a few cases where it is a pain though – one that bit me in the context of the work I’ve been doing on and off with Java classfiles is that converting between types of different size. The other one that’s an issue is comparison – integer comparison is signed in Java and there are no operations for doing the unsigned compare.

One way to fix this is to delegate to a solution to the previous problem: Bump the integers up to a type one size up in an unsigned way so that they get converted to positive values, do a comparison on there. This works fine for the smaller values, but if you were to do this with a long you’d have to upgrade to a BigInt, which is a bit sad. I’d previously been doing it this way but earlier when I needed to do unsigned comparisons on longs I decided to look for a better route. (Full disclosure: Actually what happened is I converted some code using ints to code using long and suddenly all my unit tests broke. At that point I discovered that I’d still been trying to do an unsigned comparison using the code for doing it for integers).

Anyway, I popped into ##java to see if anyone there had any ideas for how to do it. Totally counter to form, ##java was actually incredibly useful. The best solution came from someone who went by Tamutnefret and is as follows:

  def unsignedCompare(i : Long, j : Long) = (i < j) ^ (i < 0) ^ (j < 0)

Which is really neat and avoids doing any branching.

Let’s see why this works. We’ll break it down by cases on i (there’s probably a nicer way to see that it works, but I’m blanking on what it is).

Suppose i = 0. This becomes (0 < j) ^ false ^ (j < 0), which is (0 < j) ^ (j < 0), or j != 0. Which is correct, as the only unsigned integer not > 0 is 0.

Suppose now i < 0. This becomes (i < j) ^ true ^ (j < 0).
If (j < 0) this becomes i < j, as x ^ true ^ true = x ^ false = x. If j >= 0 then we certainly have i < j, so we get true ^ true ^ false = false, which is again correct: In unsigned comparison any negative number is greater than any non-negative one. The case i > 0 follows similarily (the standard mathematician’s weasel words).

Anyway, the explanation of why is boring. It takes less time to convince yourself of its truth than it did to read that. :-) But the point is that it’s a cute, useful formula which I’d not previously encountered so I thought I’d record it here.

This entry was posted in programming and tagged , on by .