Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

Friday, June 05, 2009

JavaOne Talk: Performance Comparisons of Dynamic Languages on the Java Virtual Machine

Below are the sldies. Major thanks to Charlie Nutter for great feedback and advice on the Ruby code and tuning JRuby performance. Thanks to Chouser and Timothy Pratley for help with the Clojure code. And major thanks to Brian Frank for help with the Fan code.

Wednesday, May 20, 2009

JavaOne Talk: Ruby Reversible Numbers

See this post about why this code is being shown. See this post for the Java version to compare against.

class RubyReversible
def initialize(max)
@max = max
@numReversible = nil
end

def allOdd(n)
digits = n.to_s.split(//)
digits.length == digits.map{|c| c.to_i}.select{|i|
i % 2 == 1}.length
end

def reverse(n)
n + n.to_s.reverse.to_i
end

def reversible(n)
allOdd(reverse(n))
end

def countReversible()
@numReversible ||= (11..@max).select{|i|
reversible(i)}.length
@numReversible
end
end

JavaOne Talk: Ruby Word Sort

See this post about why this code is being shown. See this post for the Java version to compare against.

class RubyWordSort
def initialize(fileName)
@dataFile = File.new(fileName)
@words = Array.new
end
def sortedWorts
if (@words.length == 0)
@dataFile.each_line{ |line| line.split(' ').each{ |word| @words << word}}
@words = @words.sort{ |w,w1| w.upcase <=> w1.upcase }
end
@words
end
end

Tuesday, May 05, 2009

JavaOne Talk: Ruby Prime Sieve

See this post for an explanation on why this code is being shown and what kind of responses would be useful. See this post for the Java algorithm to compare against.

class RubyPrimes
attr_accessor :cnt, :primes
def initialize(n)
@primes = Array.new(n,0)
@cnt = 0
i = 2
max = calcSize
nums = Array.new(max,true)
while (i < max && @cnt < @primes.length)
p = i
if (nums[i])
@primes[@cnt] = p
@cnt += 1
(p .. (max/p)).each{ |j| nums[p*j] = false }
end
i += 1
end
end
def calcSize
max = 2
max = max * 2 while ( max/Math.log(max) < @primes.length)
max
end
def last
@primes[@cnt -1]
end
end

Wednesday, October 29, 2008

EclipseWorld

This week I have been speaking at EclipseWorld in Reston, VA. I have been talking about Ruby on Rails mostly, and a little session on iPhone (web) development. Most of the developer here are Java developers, so they look at Rails as a way to make their jobs easier. It's a grim economy, and they are being given the classic task of doing more with less. They look at Ruby on Rails as a way to do just that. More features. Less code. Happier developers!

EclipseWorld has been a great conference to speak at. What has been very cool for me is interacting with developers outside of Silicon Valley. Now don't get me wrong, if you are a developer, especially a web developer, then Silicon Valley is the place you want to be. I would compare it to working on Wall Street if you are in finance, or working in Hollywood if you are in show business. It's not for everybody, but it presents the chance to prove that you've got what it takes, and, if you are lucky, a chance to make a lot of money.

However, in the Valley it is easy to forget that most web development is not about creating The Next Big Thing. In the Valley, @tychay will rip you up for using Rails because it fails at web scale. On the east coast, I have met a lot of developers creating internal web applications, or maybe customer service applications. These are applications that can run just fine a single multi-core box, even with the database running on the same machine. They aren't stressing out over page weight, database partitioning, or terabytes of cache. They are creating sophisticated applications, and always have way more feature requests than they have time.

These are the people who are most empowered by tools, especially Eclipse. They don't have some huge team with specialists for doing the CSS or tuning the database. They do it all themselves, and Eclipse makes that a whole lot easier. I've written a lot about things you can do with Eclipse, but this experience has really put things into better perspective.

Sunday, August 31, 2008

Recent Other Writings

Last week, IBM published an article I wrote on using JRuby on Rails with Apache Derby. It concentrates on rapid prototyping/development. I didn't get too heavily into the IDE side of things, but when you add RadRails into the equation it really is nirvana-ish development. Very fun.

I've also been writing a lot on InformIT about Java Concurrency in Practice. I did some fun stuff over there too, like try to turn some Project Euler code into parallel code. I guess technically that succeeded just fine, but is a good example of when parallel code is not any faster. In this case, the algorithm was CPU bound anyways. Even having two cores didn't really help much. Oh well. I treated it like a strength exercise back when I took piano lessons.

Thursday, July 31, 2008

Jython, It ain't no JRuby

All of my recent excursions into Python convinced me it was time to try out Jython. I have had a great experiences with JRuby. It is definitely faster than CRuby for long running processes (obviously slower for short scripts, because of the JVM startup overhead.) In my experiences, which range from doing mathematical algorithms to web applications using Rails, there is extremely good interoperability. I have had no code blow up in JRuby that ran fine in CRuby. Even IDE support has been on par. So my expectations were high for Jython.

Maybe that was the first problem, unrealistic expectations. Let's not jump into the shortcomings, just yet. First off, Jython installation is nice. Well nice as in "there is a gui." The installer only seemed to copy files into the installation directory, nothing more. That is fine, but makes me wonder I bothered with an installer at all. I at least expected into put the jython executable on my path, but it did not. No big deal.

Running a script is painless. It was odd to see a lot of activity the first time I ran a script, but the messaging (or should I say logging) was good enough to give me a good idea about what was going on and it only happens once. It also seemed like Jython was going out of its way to help performance, and JRuby had caused me to expect a nice performance boost from Jython.

So I tried out a script I wrote to solve a Project Euler problem, in particular Problem #43. The performance on Python is not that great, as it takes about 58 seconds to solve on my Macbook. Here is the code. It has been slightly optimized by Gilly.

def combinations(items, n):
if n == 0:
yield []
else:
i = 0
l = len(items)
while i < l:
for combo in combinations(items[:i] + items[i+1:], n-1):
yield [items[i]] + combo
i += 1

def permutations(items):
return combinations(items, len(items))

def to_int(seq):
return reduce(lambda x,y: 10*x + y, seq, 0)

def main():
primes = [2, 3, 5, 7, 11, 13, 17]
digits = range(0, 10)
sum = 0
for p in permutations(digits):
if p[5] == 5 and p[0] != 0:
j = 0
trait = True
while trait:
if j == 7:
y = to_int(p)
sum += y
print y
break
x = 100*p[j+1] + 10*p[j+2] + p[j+3]
trait = not x % primes[j]
j += 1
print "sum = " + str(sum)

if __name__ == '__main__':
main()

Lots of brute force, with a little bit of clever use of Python features. I was ready to crank this up with Jython, but when I tried to run it, I got this error message:

Traceback (innermost last):
(no code object) at line 0
File "euler43.py", line 5
yield []
^
SyntaxError: invalid syntax

Ouch. This actually made me feel stupid. I should have noticed that the current version of Jython is numbered 2.2.1 and that this obviously corresponds to Python 2.2.1 (that is obvious, right?) I had used a Python feature that did not exist in 2.2.1. Luckily there is an alpha version of Jython that is numbered 2.5. What about 2.3 or 2.4, you say? Uhh...

Anyways, with the alpha version of Jython 2.5 used instead everything worked. However, the performance was not what I expected. The same script ran in 171 seconds! It took three times longer than CPython. Wow.

I wrote a similar algorithm in Ruby and it was horribly slow. Perhaps this is why JRuby is faster than CRuby, CRuby is just so slow. Perhaps not. The nice thing about this is that it forced me to optimize the code more. Here is the optimized Ruby code.

def calc(seq)
seq.inject(0) {|x,y| x = 10*x + y}
end

def test(seq)
primes = [2,3,5,7,11,13,17]
j = 1
trait = true
while j < 8 && trait
num = calc(seq[j,3])
trait = (num % primes[j-1] == 0)
j += 1
end
trait
end

sum = 0
digits = (0..4).to_a + (6..9).to_a
for p in digits.permutation
if p[0] != 0
x = p[0,5] + [5] + p[5,4]
trait = test(x)
if trait
y = calc(x)
sum += y
puts "found one " + y.to_s
end
end
end
print "sum= " + sum.to_s

A couple of things to note. This uses Array#permutation, a new feature of Ruby 1.8.7. This is written in C, so you would think it would be super fast. You would be wrong. The latest JRuby is 1.1.3 and does not implement all of the 1.8.7 features, including Array#permutation. So this code will not run in JRuby. It winds up being much faster than the Python code, but only because the algorithm is so much better. It only deals with 9! numbers instead of 10!. Without the modification, Ruby was so slow that I did not have the patience to let it finsh. We're talking 10+ minutes for something that only took 1 minute in Python. With the improved algorithm it took about 40s to solve the problem in Ruby. When I ported the change over to Python, it dropped Python down to around 9s. When I tried the ported code in Jython, it would not run at all... I haven't tracked down that problem yet.

Friday, July 25, 2008

JRuby 1.1.3 Performance

It's been awhile since I did a post with pretty graphs and meaningless micro-benchmarks. I am using the latest version of JRuby, 1.1.3 on a new project. I knew from some correspondence with Charlie Nutter that the performance bug that I had encountered previously were believed to be solved. I said believed because he had not had a chance to test on the IBM J9 JVM that (along with some other JVMs) exhibited the performance problem. Actually this was fixed in 1.1.2, and I should have tested things then, but didn't get around to it until now. I decided to throw in the latest beta of JDK 1.6 update 10, the magical JDK for The Rest of Us. Here is the purrty chart:


The good news is that even with the J9 JVM, JRuby outperforms native Ruby, at least on this mathematical algorithm. This was not the case prior, so the JRuby fixes have really helped. In fact, if I look at the last data point (x=100), the code executed in less than half the time it took previously with the only change being the JRuby 1.1.3 instead of 1.1. I could describe the source of the bug, but you are much better off reading Charlie's description.

Tuesday, July 22, 2008

Get Lifted

Yeah, I'm a John Legend fan, but that's not the reference here. The reference is to Lift, the web application for Scala. Today IBM published an article I wrote about Lift. This was an article that I pitched to IBM and I was very excited about writing. Lift itself takes a different approach to web development than the typical MVC approaches. It is also in Scala, and takes great advantage of that languages features, especially its native support for XML.

One of the most surprising features of Lift was the ORM that it includes. Lift's creator, David Pollak, commented that he would use JPA for complex schemas and not Lift's ORM. I must admit, it was the part of Lift that took me the longest to get my head around. I consider myself quite the veteran of ORMs, but Lift's is definitely unique. I think it needs some tooling around it, as it felt like some boilerplate-ish code was present (like creating a model class and singleton factory for the model class.) However, I really liked its use of generics.

I didn't have time in the article to get into Comet with Lift and Scala's Actors. That is an awesome feature. Hmm, perhaps that should be another IBM article..

Finally, of Lift and Scala related news... check out Graceless Failure by some of the developer at Twitter. It seems to imply that Scala and maybe Lift or at least "in the mix" at Twitter. I wonder if it is replacing Ruby and/or Rails in some places. Certainly Actors would seem like an obvious way to handle new updates on Twitter.

Friday, May 23, 2008

Armchair Architects

Funny post by @al3x about Twitter architecture. Oh wait it wasn't supposed to be funny, oops. The fact is that he should totally expect more people to diss Twitter and pretend that they could easily solve all of the problems. I am not just being cynical about people, they actually have some good reasons to do so:

  • Twitter crashes a lot. If your site did not crash so much, then people would not think you are an idiot and that they could easily do a better job. The people may all be wrong, but that does not matter. Why do you think Microsoft has come to have such a bad reputation? People do not care about what MSFT did to Netscape, Sun, or Apple. They care about BSODs. People hate Vista because Microsoft did not make it as backwards compatible with 3rd party drivers that did lots of bad, hacky things. But now Vista crashes, so people complain about MSFT.
  • Twitter seems simple. You put a 140 character limit on updates and what do you expect? Part of Twitter's appeal is its simplicity, but that same simplicity creates expectations and makes people think they could do it themselves better. Maintenance is expected for things that seem complex, like cars or Photoshop, but not for (seemingly) simple things like iPods or Twitter. If you think hard about it, Twitter is much more complex than it seems, but who wants to think hard?
  • Ruby developers are obnoxious. Oh this is my favorite. Ruby developers are a small but very vocal group. They love rubbing it in your face that Ruby is so much more expressive or object-oriented or whatever than anything else on the planet. The Rails sub-cult is even worse about this. So when the most high-profile Rails site starts failing constantly, you must expect a lot of smug developers to wag their fingers. It is kind of a shame that Twitter is paying for DHH's bad karma ... but then again @blaine did make that infamous claim about how easy it was to scale Rails. Of course he's gone now, but there is still enough bad karma to go around. How many Ruby developers would admit how bad their software is? Think about that.

Tuesday, May 06, 2008

Dynamic Language Performance

A couple of days ago, I read Charlie's post explaining the performance boost seen in Groovy 1.6. Reading stuff like this always leaves me with a great feeling. Not only do you learn something, but it makes other things make more sense. It brings order to chaos, or something like that. Around the same time I read that, I was working a new article about Grails, so the Groovy angle was particularly interesting. I love benchmarks, so it was time to have some fun.

I wrote a Groovy version of the same Ruby code I had used to benchmark JRuby. This was an extremely straightforward port. I was amazed at just how similar Groovy's syntax is to Ruby. Here is the code:


def expo(n,p){
def r = n % p
def exp = 0
def div = p
while (r == 0){
exp += 1
div *= p
r = n % div
}
return exp
}

def factor(n){
def factors = new java.util.HashMap<Integer,Integer>()
def s = n * 0.5
def p = (2..s).toArray()
p.each{
if (it) {
def r = expo(n,it)
if (r){
factors[it] = r
}
def val = it*2
while (val <= s){
p[val -2] = null
val += it
}
}
}
return factors
}

def numDivisors(n){
def total = 1
factor(n).values().each{
total *= (it+1)
}
return total
}

def n = 2
def num = 1
def max = Integer.parseInt(this.args[0])
def Integer triangle = 0
while (num <= max){
triangle = n*(n+1) * 0.5
num = numDivisors(triangle)
n += 1
}
println(triangle)


Anyways, here is the chart.

There is definitely a performance boost for long running processes where JIT'ing can happen more easily in 1.6. It was not as dramatic as I thought it might be, but it is there. Of course this is just one silly benchmark that is heavy in integer math, so take that for what it's worth. 

I also compared Groovy and JRuby. This was also surprising: 



Pretty close! Groovy seems to start-up a little slower, but pulled ahead slightly on bigger tasks. Perhaps the apprentice has overtaken the master.

Also, just for kicks, I tried out Scala. Here is the code:


import scala.collection.mutable._

object Euler12{
def expo(n:int, p:int):int = {
var r = n % p
var exp = 0
var div = p
while (r == 0){
exp = exp + 1
r = n % div
div = div * p
}
if (exp == 0 ) 0 else (exp-1)
}

def factor(n:int):Map[int,int] = {
var factors = new HashMap[int,int]()
var s:int = (n/2) + 1
val p = (2 until s).toArray
p.foreach( (num) => {
if (num > 1){
val r = expo(n, num)
if (r > 0){
factors.put(num, r)
}
var i = num*2
while ((i-2) < p.length){
p(i - 2) = 0
i = i + num
}
}
})
return factors
}

def numDivisors(n:int):int = {
var total = 1
factor(n).values.foreach((num) => {
total = total * (num+1)
})
factor(n).values.foldLeft(1)((p,m) => {
p * (m+1)
})
}

def main(args:Array[String]) : Unit = {
val t = new java.util.Date()
var n = 1
var num = 1
val max = Integer.parseInt(args(0))
var triangle = 3
while (num <= max){
triangle = n*(n+1)/2
num = numDivisors(triangle)
n = n + 1
}
println(triangle)
}
}


This turned out to not be fair. Scala's performance is exactly on par with Java and thus blows away JRuby and Groovy. 


I guess that is what happens when you have a language written by a guy who once wrote javac... Actually I would guess this is mostly a function of the static typing in Scala. It certainly bodes well for initiatives to bring features of Scala, like (BGGA-style) closures and type inference, to Java. It seems possible to implement all of this with no impact on performance, even on a JVM that has not been made to support such features. 

Thursday, April 24, 2008

Diophantine Equation

Earlier today I solved Problem 31 on Project Euler. The problem is to find the number of ways of making change for 2 British pounds (or 200 pence) given 8 types of coins. For a mathematical person like myself, the problem reduces to a Diophantine Equation:

a + 2b + 5c + 10d + 20e + 50f + 100g + 200h = 200

Where 1,2,5,10,20,50,100,200 are the values of the various types of coins. I had some meetings to go to, so I wrote a brute force solution (in Ruby) and let it run. I got back an hour later, and it was still running. I felt quite stupid. I then came up with a much better solution using some dynamic programming and recursion. It ran in 0.23s. Here it is:


def solve(n,coefficients)
x = coefficients.pop
if (coefficients.length == 0)
if (n % x == 0)
return 1
else
return 0
end
else
d = (n/x).to_i
cnt = 0
0.upto(d){|y|
xc = coefficients.collect{|p| p} #must copy since we pop array
cnt += solve(n-x*y,xc)
}
return cnt
end
end

c = [1,2,5,10,20,50,100,200]
n = 200
puts solve(n,c)

Wednesday, April 02, 2008

Long Division

Earlier this week, I solved another problem from Project Euler. This was #26. Here is the description:

A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:

1/2= 0.5
1/3= 0.(3)
1/4= 0.25
1/5= 0.2
1/6= 0.1(6)
1/7= 0.(142857)
1/8= 0.125
1/9= 0.(1)
1/10= 0.1

Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.

Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.

I knew this problem was related to the totient function, but I went a brute force route instead. The brute force route required writing a long division algorithm, which just seemed like a fun thing to do anyways. So I solved the problem, and the solution was plenty fast (0.185s for the calculation.)

I was ready to post my solution to the forums. I was also planning on reading the forums to see if anyone had a clever solution using the totient function. So I was greatly disappointed to see that the forms were down. Still my ego required me to publish my long division algorithm, so here it is:


def cycle(d)

m,i = 1,1
arr = Hash.new

while m > 0
while m < d
m *= 10

i += 1
end
m = m % d

if arr[m]
return i - arr[m]

end
arr[m] = i
end
return 0

end

max = 0
m = 2
3.upto(ARGV[0].to_i){|n|
c = cycle(n)

if c > max
max = c
m = n

end
}
puts m

Obviously this is in Ruby. The cycle calculates the length of the recurring cycle. The m variable is essentially the digits in the decimal representation of 1/d. The algorithm doesn't capture it, since it is not needed for the problem, but you could easily capture it (append to a string or array or whatever) and return it for a true long division algorithm.

Wednesday, March 05, 2008

More JRuby Performance

In the aftermath of my post on JRuby's performance, I exchanged some info with Mr. JRuby himself, Charles Nutter. Per his request, I opened a bug on the matter. It looks like it is a JVM issue, i.e. JRuby ran slowly on IBM's J9 JVM. I did some micro-benching on Ruby vs. JRuby on a variety of platforms and JVMs. It was only on the J9/2.3 (IBM's JDK 5.0 JVM) that JRuby was was slower than the latest "native" Ruby implementation on that platform. Everybody loves charts, so here are some fun ones.


This was on my MacBook, with both the standard HotSpot Java 5.0 and Java 6.0 preview versions. I also compared using the -J-server (just becomes -server for the JVM) option, since HotSpot on the Mac runs in client mode by default. Thus the -server made a big difference.

This was on my home desktop system, a 32-bit Windows Vista system. I only did native Ruby vs. JRuby with and without the -server option. Again JRuby with the -server option crushed native Ruby.

Finally the environment that caused all the problems, my workstation. As you can see, it did quite poor compared to native Ruby. However, JRuby with either the 5.0 or 6.0 HotSpot JVM was much faster. I was actually hoping to see a better performance advantage on the 6.0 VM vs. the 5.0 one... I don't have IBM's 6.0 VM, so I could not include it. The HotSpot VMs were both 64-bit, whereas the IBM J9 on was a 32-bit VM.

Tuesday, March 04, 2008

JRuby Performance

During my lunch today, I solved Problem 12 from Project Euler. As usual, I wrote the solution in Ruby and was surprised by just how long it took to calculate. It made me decide to try JRuby.

First, a note about the problem and my solution. The problem was to find the first triangle number (where the n_th triangle number is 1+2+3...+n) that has at least 500 divisors. My solution was pretty brute force. I took each triangle number and computed its prime factorization. For example 28 = 2^2 * 7^1. Thus the number of factors is (2+1)*(1+1) = 6. Generally if N = A^a * B^b * ... where A,B,.. are primes, then the number of factors is (a+1)*(b+1)*...

With all of that in mind, why did I think JRuby would be faster than Ruby on a problem like this? This kind of calculation is well suited for JVM optimizations: unwinding of loops, JIT'ing of the code, etc. Thus I thought this might be the kind of problem where the JVM could make JRuby run a lot faster than Ruby. Boy was I wrong!

In general, I found JRuby to take twice as long as plain ol' Ruby (or C Ruby as the JRuby folks like to call it.) This was true on Windows, where Ruby is considered to have a poor implementation by many, and on OSX.

This made me thing that my conjecture was wrong to begin with. Maybe this was not the kind of code that the JVM could do much with. I re-wrote the algorithm in Java and re-ran it. It was exponentially faster in Java than in Ruby or JRuby. Indeed, the JVM was able to optimize the runtime execution of the code and make it fly.

Is this what I should have expected? Is JRuby generally much slower than Ruby? I really thought that part of the idea behind JRuby was to leverage the JVM to make Ruby faster.

Wednesday, February 27, 2008

Project Euler

A friend of mine pointed me to Project Euler. Being a mathematician and a programmer, he knew I would love it. It is a lot of fun. It reminds me of these computer competitions I used to participate in when I was in high school. You would get some list of problems on sheet of paper, have to code a solution, and a judge would come by to test your program. Anyways, I am a 4% genius having completed seven problems so far. I am mikeg on the message boards on there, if you want to check out my solutions. So far I have done everything in Ruby. I picked Ruby for two reasons. First, I like its syntax and want to use it more often. Second, it is slow. So I figured it would force me to come up with good algorithms. Here is a sample of one of my solutions. The problem was to find the largest palindrome that is the product of two 3-digit integers.

def isPal(num)
if num % 11 == 0
return num.to_s == num.to_s.reverse
end
return false

end
 
max = 0
999.downto(100){ |i|
i.downto(100){|j|
val = i*j
if val > max
if isPal(val)
max = val
end
else
break
end
}
}
puts max

Thursday, February 14, 2008

Metaprogramming in Grails

Groovy is a swing-and-a-miss. It will go down like OS/2 did. People will say "man that Groovy language was so good, I don't know why it didn't catch on." Here's an example of why it is a fail.

I was reading this article on developerWorks about GORM, the OR framework in Grails. Like everything else in Grails, it is "inspired" by Ruby on Rails. In this case GORM was inspired by ActiveRecord. In GORM here is an association:

class Airline {
static hasMany = [trip:Trip]

String name
String url
String frequentFlyer
String notes
}

Compare this to the same thing in Rails

class Airline < ActiveRecord::Base
has_many :trips
end

Forget the explicit listing of fields for a minute, concentrate on the has-many notation used by both frameworks. In Grails, you have a static field that has a special name. In ActiveRecord you use a meta-API or macro (or whatever you want to call it) to dynamically add methods to each instance of Airline. Grails accomplishes the same thing, but it is much more of a hack. You just happen to have a static field that has a special name.

It just feels like "wow that feature is cool, we can't do it the same way ... but we can hack something together that is pretty close!" Just seems like Groovy comes up short.

Tuesday, January 22, 2008

Galpin on Rails on IBM

A couple of pieces that I wrote on Rails appeared on IBM at the end of last year. I didn't even realize it until today when somebody emailed me about one of the articles.

The first article is part one of a four part series on using Rails, XForms, and DB2's PUREXML tables together. I also wrote part two, but another writer wrote parts three and four. Only part one is up so far.

The second article is the third tutorial I wrote on using Eclipse as a web development platform. Part one was about using Eclipse for Java web development, and part two was on using it for PHP development. The last tutorial is on using Eclispe (via RadRails) for Rails development. Note, the link for part two shows the intro page to part one. If you login, it correctly gives you part two. Clearly some kind of technical glitch for IBM!

Monday, January 14, 2008

Language Wars 2008

Two interesting blogs inspired this post. First, there is the amazing analysis of the great Neal Gafter. And then there is the insightful rant of Rick Hightower.

I have to admit that I am getting on the Scala bandwagon. Here is why I think Scala is important. Note, most of this is just me ripping off Neal Gafter :-)

There is great potential in languages with control abstraction. Scala is just such a language. It is possible to implement the actor model, a shared nothing, message based design for parallel computing, in Scala. This is not possible in Java. You can do it in Groovy, sort of, but it can be awkward. The reason for this is simple. If you have a object call method call closure (for example) the closure can return control back to the object in Scala, but only to the method in Groovy. The extra control structure coupling in Groovy makes some aspects of control abstraction awkward at best.

And then there are pattern matching (no not regexp) and case classes... The point is that there are syntactical advantages in Scala that make it possible to handle concurrent programming in a completely different, more scalable way. So it is not just about lines of code and what not, it is about being to do practical things in a better way.

Now Rick's main point in his rant, is why invest in JRuby and Scala when there is Groovy. Hopefully I've given at least one reason why Scala has potential that Groovy does not. When it comes to Ruby, the answer is less technical and more social.

On the technical side, it is very conceivable that by the end of the 2008, the absolute best way to deploy a Rails application will be to use JRuby. That is partially because of the current state of native Ruby interpreters, but also just because of how powerful the JVM has become. Sun really wants this to be the case, and here is why.

Sun knows what it takes to introduce a new language and platform and make it the de facto standard in the industry. It is very hard and expensive. They have done it once, and it cost them dearly. Java cannot stay at the top forever. They do not want to fight this battle again. However, if they can get the Rails on JRuby scenario described above to exist, then they could "stay on top" without having the fight all of the battles this time. They let the Rails community do it for them. They let guys like DHH and Martin Fowler win over the hearts and minds, while they simply concentrate on making JRuby run screaming fast.

But wait, there's more. Sun really wanted NetBeans to be the premiere Java development platform, but IBM beat them with Eclipse. They get a second chance if Ruby becomes the new de facto standard, and this time they have a head start on IBM. Sun is imagining a future where there are armies of IT developers writing Rails apps using NetBeans and deploying them to Glassfish.

Now all of the above may be possible, maybe even easier, with Groovy. But then they have to fight the language wars all by themselves. They have to win over the hearts and minds of developers to get them to use Groovy instead of C# or PHP.

That is why it makes more sense for Sun to back JRuby than to back Groovy.

That is also why you should not expect Sun to get behind Scala until they have no choice.

Friday, December 07, 2007

Rails 2.0 Released

If you are upgrading, I recommend upgrading Gems first (gem upgrade -system) and then using it to upgrade Rails (gem install rails --server http://gems.rubyonrails.org). There are some nice features. I especially like some of the Ajax security and JavaScript aggregating. The (expanded) JSON and XML support in ActiveRecord is also nice.