Summary
As developers desire to benefit from the conciseness and features of the multitude of languages that target the JVM, the question of which of those languages to master next comes up from time to time. Frederic Daoud points out the plusses and minuses of Groovy, JRuby, and Scala, showing a small illustrative program in each.
Advertisement
The last few years saw great advances in alternative languages that target the JVM as their execution environment. JRuby, Scala, Groovy, and Jython emerged as four leading contenders to vie for the attention of developers wanting to master a second JVM language.
The benefits of learning another JVM-bound language are many, according to Frederic Daoud, who writes in a recent blog post, Groovy, (J)Ruby or Scala?:
I've tried out some Groovy, Ruby and Scala (not JRuby), and there are some nice things in there. Most interesting to me is the functional programming and object-oriented programming hybrid aspect. Being able to use existing Java libraries is a definite plus, and unless I'm mistaken ... with JRuby being available, all three languages are now more or less equal in that respect.
There would be several things to consider when choosing a language to learn, besides the language feature set itself; available tools, books, community, marketability.. but let's stick to just the language.
To illustrate the conciseness and syntax of each language, Daoud wrote a simple program in each that iterates over the lines in a set of files provided on the command line:
MAXLENGTH = 70
$*.each do |filename|
File.open(filename) do |file|
file.each_line do |line|
length = line.chomp.length
if length > MAXLENGTH
puts "#{filename} line=#{$.} chars=#{length}"
end
end
end
end
I find it interesting that for Groovy and Scala the indenting is much larger than that in Ruby. In the code you posted, it looks like Groovy and Scala indent five space in, while in Ruby, you had it indent three spaces.
Not to be a stickler, but you asked us to look at the "conciseness and syntax of each language"
The first thought that came to my mind is that the Ruby code felt less wordy and not as "horizontal". So I would say I would prefer the Ruby code.
But looking closer, if the Ruby code was indented the same amount...I would probably not think that and the ruby code would actually be more "horizontal" looking than Groovy or Scala.
I support Scala, because it's a great language, because it's fast, and because it's not "just" the reimplementation of an existing language (JRuby/Jython) or a "me too" (Groovy).
Also, it has a nice type system.
Basically, I support scala because I think scala is (or tends to be) what Java should have been or should have become.
Plus it has pattern matching, none of the others have it, to my knowledge.
import scala.io.Source val MAXLENGTH = 70 args.foreach { filename => var file = Source.fromFile(filename) var counted = file.getLines.counted counted.foreach { line => if (line.length - 1 > MAXLENGTH) { Console.println(filename + " line=" + (counted.count+1) + " chars=" + line.length) } } }
(No need for the explicit function def, and the types for the closure params can be inferred.)
Style-wise, they all look pretty much as good as each other to me, and a big improvement on Java, so selecting which language comes down to other factors such as static or dynamic typing.
In the past couple of days I have been giving JRuby some of my time, updating my libraries that depend on it like Swing and JDBC related. Before yesterday, I had never used Grizzly of Java fame, but I was interested in it and after fiddling with it a little I got it to work for me a little bit. There's still more work to do, but I am relatively happy with it, despite some "concurrency difficulties" I might have had as my other Ruby libraries that work with JRuby have not been created to work in a highly concurrent server as Java provides. :-) I am happy enough with both JRuby and Grizzly that I am posting a simple wrapper example for it in case somebody else needs some Java integration or incentive or some other use like creating a new framework specifically for JRuby with Grizzly and GlashFish or something:
def redirect url, status = nil @status = 302 prepare!{ @native.header['Location'] = url.to_s } raise RedirectException.new end
def prepare! cc = [] @cookies.each_pair{|k, v| cc << "#{k}=#{v}; path=/" } s = @body || '<html></html>' bytes = s.to_java_bytes @native.setStatus @status @native.setContentType @content_type @native.setCharacterEncoding @charset @native.setHeader 'Set-Cookie', "#{cc.join("; \n")}" if cc.size > 0 @native.setContentLength bytes.length yield if block_given? chunk = ByteChunk.new chunk.append bytes, 0, bytes.length buffer = @native.getOutputBuffer buffer.doWrite chunk, @native @native.finish end
end
class Request attr_reader :native
def initialize native super() @native = native end
def header h = {} a = @native.getMimeHeaders a.size.times{|i| k = a.getName(i).to_s v = a.getValue(i).to_s k = k.downcase.gsub(/^http_/, '').gsub('_', '-') h[k] = v } h end
def path_info @native.requestURI.to_s end
end
class PremierAdapter include Adapter
def initialize &block super() @main_block = block end
def service request, response mres = GrizzlyWrapper::Response.new(response) mreq = GrizzlyWrapper::Request.new(request) begin @main_block[ mreq, mres ] mres.prepare! rescue RedirectException #simply ignore end end
def afterService request, response request.recycle response.recycle end
I'd like to say that I am impressed with JRuby's ease of Java interface implementation, which is implemented like a Ruby mixin. I use it for Swing as well. I don't know what the future holds for JRuby, but as long as it works reliably for me I could use it more often. The compatibility with Ruby helps experimentation as I have just done. For instance, before I deleted my support for Simpleweb (as Grizzly should be better anyway), I had 4 Web servers working with JRuby (including Ruby's Mongrel and WEBrick which are supported as well - double cool).
BTW, sorry for the length of my previous message and sorry for leaving a line at the bottom ("if CommonRules.main_file?(__FILE__)") that depends on a library of mine. I tried to remove any dependencies on custom stuff and make it be runnable with pure JRuby, so the line should have been this one:
Here's a little benchmark of Grizzly with JRuby using the wrapper above and the "ab" tool:
Concurrency Level: 100 Time taken for tests: 13.752185 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 1750700 bytes HTML transferred: 410164 bytes Requests per second: 727.16 [#/sec] (mean) Time per request: 137.522 [ms] (mean) Time per request: 1.375 [ms] (mean, across all concurrent requests) Transfer rate: 124.27 [Kbytes/sec] received
Flat View: This topic has 45 replies
on 4 pages
[
1234
|
»
]