So, while I was somewhat bored by Scala 2.9, after the huge jump 2.8 was, there has been some nice improvements. For one thing, the jLine library used by REPL was replaced with one based on this (the canonical repository to the jLine actually used in Scala is here) giving a much superior experience. Now one can edit input that spans multiple lines (longer than the number of columns in the screen) without trouble, search the history, etc. There's even something to show its key-bindings: just type :keybindings.
And speaking of REPL, it doesn't stop there, by a long margin! There's :javap, which will happily decompile a class or file, :type which will show an expression's type without evaluating it, and :implicits to show what implicits are in scope. Add -v to that last one, and it will show those that come with Predef by default.
Those of you pasting code into REPL, or wanting to define companion objects, or pretty much any other feature that depends on the content of the next line, you'll be happy to know there's now :paste. Instead of instantly evaluating each line, it will wait until you hit ^D.
More recently, a few features came up that will help those that like to do Scala scripting. The -absolute-cp parameter will ensure relative paths on classpaths will be made absolute based on where the script is being run from, not where the compilation daemon was started at. If you don't even know what I'm talking about, then trust me: that will save you a lot of pain.
Another option, -max-idle, will let you specify how long the compilation daemon will stay up when idle, and even disable its auto-shutdown.
And just to make scripting even nicer, SBT's Process library is now available in Scala, as sys.process! Now we can do stuff like this:
import sys.process._ Process cat new URL("http://databinder.net/dispatch/About") !
"find src -name *.scala -exec grep null {} ;" #| "xargs test -z" #&& "echo null-free" #|| "echo null detected" !
Another interesting scripting feature is that not only will files containing a single object with a main method be runnable as if it were a script, but jar files produced by scala when it compiles scripts will be runnable like programs. For example:
% cat script.scala object FiddleDeeMain { def main(args: Array[String]): Unit = { println(args mkString " ") } } % scala -nocompdaemon script.scala a b c a b c
And, conversely,
% cat script2.scala println(args mkString " ") % scala -save script2.scala arg1 arg2 arg1 arg2 % scala script2.jar arg1 arg2 arg1 arg2
On the library side, a few things have happened too. Some changes where made to view, which made it much faster than it used to be. Arguably, its previous lack of performance resulted from a bug, so if you had performances issues with it, you might want to check it out again. Also on the performance front, another change with lots of potential is the introduction of a new hash code algorithm -- murmur3.
To those of you who like writing methods and classes with Numeric and Ordering, you'll probably like to know that you can now add "import Numeric.Implicits._" and "import Ordering.Implicits._" and avoid all that messy implicit parameter handling. For example:
import Numeric.Implicits._ def sum[N: Numeric](lst: List[N]) = lst reduceLeft (_ + _)
It might not seem much for a single method like that, but if you use this stuff often, I'm sure you see the advantages.
There are plenty of small changes that will make life easier, or more intuitive. For example, -5.abs will now work. Scaladoc is much faster. Many bugs have been fixed, even on places you'd never guess there were bugs (scary thought).
An interesting improvement is the introduction of DelayedInit. While most people won't ever hear of it -- unless it starts getting used in DSLs --, it enabled the rehabilitation of a much criticized feature: the Application trait. It is not that Application was a bad idea, but it was badly implemented. Given all that has been written about staying away from it, its new implementation was also given a new name, which we can now start using in our blogs everywhere: App.
On the realm of experimental stuff that may never make 2.9 at all, I'm pretty fond of -Yrich-exceptions. It adds some capabilities to exceptions on REPL. One example is lastException.show, which will display the source code location of the exception, if available (to use it, point SOURCEPATH to the source code).
There are plenty of other improvements, way too many to talk about: better docs, better error messages, better performance, bug fixes, more methods, new traits and classes, not to mention improvements made for people creating compiler plugins or working on Scala itself. If you want to get more dibs into Scala 2.9, there's a japanese site tracking the changes, though only looking through the commit log one can truly feel the scope of what Scala 2.9 is. Kudos to Scala's development team!
Thanks for the write-up, very informative.
ReplyDeleteHey Daniel,
ReplyDeleteGood to see a write-up for some of the improvements in 2.9.0.
A couple of comments.
"another change with lots of potential is a new hash code algorithm -- murmur3, which is replacing murmur2"
Are you sure that murmur2 was used in previous versions? I don't remember seeing it mentioned.
It's also worth mentioning that a lot of work went into the presentation compiler to make it more reliable and better suited for interactive usage. In other words, the foundation for better IDE and advanced text editor support.
Best,
Ismael
To be truthful, I don't know if murmur2 was used in any previous Scala release. However, the commit message for murmur3 mentioned it was replacing murmur2.
ReplyDeleteGreat post. Thanks. I would expect lots of interesting things happening with scala.Dynamic
ReplyDeleteThanks for giving a headsup on Scala 2.9
ReplyDeleteJust hope that they can really improve the scala compiler in 2.9 . Even with fast scala compiler, it can be painfully slow in compiling few lines of scale code. The poor compiler performance will deter potential users from learning it.
ReplyDeletehello
ReplyDeletewhen is scala 2.9 coming out? is from the nightly builds?
is it stable enough to start using?
(i need parallel collections now! haha. that's a little dramatic..)
You can grab a nightly build at any time. I have never seen a Scala build unstable enough to be a major concern -- in fact, nightly builds include many bug fixes to problems found on the releases.
ReplyDeleteThere are problems using nightlies, though. For one thing, it is much harder to get Scala libraries for it, since Scala binaries are usually incompatible from one version to the other. For another thing, the API is not stable -- things may, and do, change.
For production code, it is best to wait for releases. You might want to try out the new version once Release Candidates for it are made available, as Scala libraries and frameworks are usually made for these snapshots, and it gives you the opportunity to catch any bugs that affect _your_ software before the final release is made.
For academic purposes or personal use, Scala's nightlies do fine.
ah... i see... thanks for the info!
ReplyDeletewell, i'm using Scala for the code for my PhD project in natural language processing... so no one will die if it screws up.
do you know when it's out for real? it's basically gonna be like christmas morning. haha.
Who knows? It's too early to get a good feel for how long it might take. All I can say is that it is already at the stage where committers are working to fix any problems that might prevent it from being released.
ReplyDeleteOk.. well, thanks for the info, Daniel.
ReplyDeleteAnd, if you get a multi-core machine between now and then, maybe you'll be less bored about this really cool feature :)