In favor of Ruby


Chad Wathington recently posted on the official ThoughtWorks Studios blog a post called Many Facets of Ruby. I would like to expand on some of the points on it, and how I see it. To be sure, what is posted on the TW Studios blog is the “official” ThoughtWorks views – whereas what I write in this blog is purely my own opinions, with no relationship to ThoughtWorks at all.

The point Chad writes about is that ThoughtWorks lately have been talking a lot about JRuby, in such a way that it’s easy to get the impression that we as a company have chosen one implementation over the others. As Chad writes, that’s not correct.

I’ve probably done the same thing in my blog. Obviously, I really like JRuby and hope it will work out well. I really like Rubinius effort and I predicted a while back that Rubinius may take over after MRI as the standard C Ruby implementation. But that doesn’t mean I’m not interested in the the other approaches around. MRI and YARV definitely has strong points going for them (MRI and JRuby are still the only fully working implementations of Ruby). But when IronRuby, XRuby, Rubinius, YARV, Garden Points and Cardinal is more complete, the Ruby environment will be that much richer for it.

I’m not in this game for a specific implementation. I would use Ruby no matter if there was a JRuby or not. It’s just that JRuby solves some of my problems, and allows me to hack on something that I know a segment of the Ruby user group will find useful. I’m in this for the language. I have chosen Ruby as my language, but the language is the same over the implementations. And it’s going to be really exciting in the Ruby space the next few months.



Operator Overloading in Ruby


I really like the fact that Ruby has operator overloading. In many cases this feature is not very fitting in a language, but in Ruby it definitely has its place. So what’s the difference? Why do people generally say that operator overloading in C++ is a bad thing, and that Java shouldn’t have it? I believe the main reason is static typing. When you have static typing and combine that with a verbose language, operator overloading doesn’t really fit in. You can’t create DSL looking API’s out of the language since the line noise usually make such efforts futile. And then you’re left with only the bad parts of operator overloading.

In Ruby on the other hand, it fits very well. It actually makes sense to be able to redefine and add operators since there are many places where your code can be made much more readable with it. Of course, you always have to be careful and not go over board with it, but when used riht it improves readability to a large degree. A typical example of nice use of overloading is in Hpricot:

doc/:html/:body/:p/:img

Here the division operator have been overloaded to make it possible for you to write XPath like search strings beginning on a parsed Hpricot document.

Another place I really like is in the Ruby core library where the call method is usually overloaded as []. This makes sense if you think about it – in most cases the objects you can call on will take parameters and return a result based on the parameter. This can be mapped quite neatly to an Array or Hash containing values that are returned, and in fact you can imagine swapping out this restricted usage of an Array or Hash to something that you can call things on.
If the [] method is all you used for access, duck typing makes it easy to send in a Proc instead of an Array or Hash.

Another reason using [] can be nice, is since Ruby doesn’t let you override (). If you want to emulate that kind of behavior, [] can act exactly the same if you want it to.

In the Ruby core, the more useful things that implement [] is Array and Hash, of course, UnboundMethod, BoundMethod, Proc and Continuation. This means that you can do something like proc{ puts “hello” }[] if you feel like it.

There are lots of other nice operators to overload in Ruby, though. Some of the better ones are unary + and unary -, all the common arithmetic operators, ||, &&, |, &, <, >, <=, >=, ~, =~, **, ==, === and a few others. The two things missing here is the ! and friends, and (). But of course, adding () wouldn’t really work with the Ruby language. ! on the other hand should be overridable.

So, you should use operator overloading in Ruby, but be careful that it makes sense and actually gives you a good abstraction, not just something “cool”.



Know your Regular Expression anchors


As everyone knows, regular expressions are incredibly important in many programming tasks. So it pays to know some of the particulars of the regexp syntax. One example that bit me a while back was a simple oversight – something I did know but hadn’t kept in mind while writing the bad code. Namely, the way the caret (^) works when used in a String with newlines in it. To be fair I’ve been using Java regexps for a while and that problem doesn’t exist there.

To illustrate the difference, here is a program you can run in either MRI or JRuby. If running in JRuby you’ll see that the Java version needs the flag MULTILINE to behave as Ruby does by default.

str = "one\nover\nyou"
puts "Match with ^"
str.gsub(/^o/) do |e|
p $~.offset(0)
e
end

puts "Match with \\A"
str.gsub(/\Ao/) do |e|
p $~.offset(0)
e
end


if defined?(JRUBY_VERSION)
require 'java'
regexp = java.util.regex.Pattern.compile("^o", java.util.regex.Pattern::MULTILINE)
matcher = regexp.matcher(str)
puts "Java match with ^"
while matcher.find()
p matcher
end

regexp = java.util.regex.Pattern.compile("\\Ao", java.util.regex.Pattern::MULTILINE)
matcher = regexp.matcher(str)
puts "Java match with \\A"
while matcher.find()
p matcher
end
end

So, what’s the lesson here? Don’t use caret (^) and dollar ($) if you actually want to match the beginning or the end of the string. Instead, use \A and \Z. That’s what they’re there for.



Ruby+Erlang concurrency?


I keep reading from lots of people that you can’t bolt Erlang’s concurrency model on Ruby. But is this really true? MRI already has green threads. Adding a higher level of concurrency with the basic primitives of !, recv and spawn doesn’t seem like a gigantic project. The main problem would be to prohibit access to shared memory between the spawned green threads, and avoid the GIL. But that doesn’t seem to be that large of a problem. The main question is rather if this model would fit well with the Ruby language… Since Erlang was designed from the ground up with these primitives in mind, many of the libraries and functions work well with it. For example, pattern matching work exactly the same in recv as in function dispatch or case expressions.

On the other hand, the send, recv and spawn primitives in Gambit Scheme seems to work out really well even though the language is LISP in root (or maybe that’s the reason?)

In fact, this is one of the few places where it would be harder to add something to JRuby than MRI. Since we can’t control the full stack it would be very hard to implement anything resembling Erlang processes in Java. And Java threads would almost certainly be too heavy weight for this to work. Hmm.



What about Sun’s Ruby strategy?


Wow. Today was a strange day for blog reading. I’ve already had several WTF moments. Or what do you say about 7 reasons I switched back to PHP after two years on Rails, where the first and most important reason seemed to be

IS THERE ANYTHING RAILS/RUBY CAN DO THAT PHP CAN’T DO? … (thinking)… NO.

Bloody hell. All programming languages in use today are Turing complete. Of course you can do exactly the same things in all of them. But I still don’t program in Intercal that often.

Example number two: About JRuby and CPython performance. This blog post uses the Alioth language benchmark to show us that Python’s C implementation is faster than JRuby. Of course, the JRuby version used in this comparison is 1.0, which is now almost 4 months old. Comparing the C implementation of one language with a Java implementation of another language seems kind of suspect anyway.

But these two examples is nothing compared to a post by Krishna Kotecha from yesterday. It’s called Sun’s Ruby strategy – Engage and Contain?. You should ge read it. It’s actually quite amusing. I usually don’t respond to other blog posts, and I don’t usually quote in my blog. I’ll do an except here, because there are several points in that post I want to elaborate on.

Compromise definitely seemed to be an underlying theme at RailsConf Europe. DHH’s keynote downplayed the need for evangelism – something I strongly disagree with. Rails has certainly made a lot of progress towards wider acceptance, but we’ve got a really long way to go before more companies start to adopt it, and I certainly don’t think turning down the evangelism and doing stealth deployments via JRuby is the answer.

There are really two interesting points in this paragraph. First of all the question of evangelism. I would say it’s about time to turn it down. Actually, I’ve gotten the very real impression that the wild-eyed Rails evangelism is now turning people away from Rails rather than winning more “converts”. Telling people about the advantages of Rails is still something that needs to be done, but the full fledged Rails marketing machine has already done it’s work and should be turned down a notch.

The second point Krishna sneaked in there is about JRuby “stealth deployments”. I’m pretty sure no one will ever do a real stealth deployment, and I find that concept totally wrong.

At RailsConf Europe 2007 however, Dave didn’t even specifically discuss Rails – and this seems to have been at the behest of the conference organizers. If this is the case, then the Rails community is already in trouble. Is this the price of Sun’s ’support’: that the community is no longer able to freely discuss the platform and what work needs to be done to get it accepted in the enterprise on its own terms?

Where does this particular conspiracy theory come from? Is there any evidence whatsoever that the organizers of RailsConf wanted Dave to not speak about the shortcomings of Rails? And even if that were the case, what’s there to say that Sun is the reason for this? (Couldn’t it have been IBM or ThoughtWorks, who were also Diamond sponsors?)

I have real problems with this attitude and approach. Selling Rails and Ruby, as “just a Java library” is a massive disservice to the technology, and simply means enterprise customers and decision makers won’t evaluate Ruby on its own merits.

What is important to realize is that the argument “just a Java library” will only ever be used in the case of organizations where there are good technology arguments for using JRuby on Rails, but non-technical management are making decisions based on what is most safe at the moment (see the Blub Paradox by Paul Graham). In most cases the “just a Java library” argument is useful only when talking about conservative environments who are standardized on a certain platform. And believe me, Krishna, there are many places where Java is the only allowed technology to be deployed. But in most cases JRuby will work fine for those IS departments. Is it really a disservice to the technology to make Rails and Ruby into something that can be used in even wider domains, removing cruft and bloatware at all places possible? Is it a disservice for the technology to be used in places where it would never enter without the help of JRuby?

But JRuby is not the best answer for Rails and Ruby developers.

I don’t really understand this quote. Obviously Krishna have strong opinions about the subject, but stating something as a fact without telling the reasons for it being that way doesn’t feel that interesting.

Serious Rails deployments (Mongrel not some Java Application Server) within enterprise environments may be difficult to achieve, but with the right political backing and developer persistence it can be done.

I must say I find it interesting that Mongrel is viewed as a serious deployment option when compared with a standard Java application server. The question here isn’t how we should get enterprise environments to use Mongrel; rather, we should first decide if Mongrel really is a serious enough deployment environment for enterprises.

And this will benefit the whole Rails community – not just those who tie themselves to Sun’s technology platform.

I heard this rumor about Java being Open Source… Does that still mean tying yourself to “Sun’s technology platform”?

And also, the vendor with the most to lose if Rails really does fulfill its potential in enterprise environments.

Why? What exactly does Sun lose if Rails win? Sun is using Rails and benefiting from it. And be careful about this: Rails is Rails, no matter if it runs on JRuby, MRI, YARV, Rubinius, IronRuby, Ruby.NET, XRuby, Cardinal or any other Ruby implementation now or ever. Rails is Rails.

Maybe I’ll start to believe when they start promoting Ruby on Rails at JavaOne, as opposed to promoting JRuby on Rails at RailsConf.

I guess you didn’t attend JavaOne 2007, where both JRuby on Rails and Ruby on Rails had sessions, including promoting in one of the major keynotes. Sun is serious about Java being a multilingual platform. Of course they’re spending money on getting these languages working on Java, but Sun is also giving support to both Rubinius and MRI. Would they really do that if this conspiracy theory is correct? For more information about that particular data point, take a look at Tim Bray’s blog here: Rubinius Sprint.

Much more likely I think, is that we’ll see a Java based Rails alternative that ships with some new version of Java which has been designed to incorporate features from dynamic languages like Ruby and Python.

Java will almost certainly never ship with a web framework. That said, Phobos is one of the Sun projects for web development that uses JavaScript and incorporates features from Rails and Ruby, and also Python and other languages and frameworks.

And still, Sun doesn’t seem to have a problem with Rails and Phobos living side by side. GlassFish includes support for both. And the Rails support doesn’t make any changes to Rails, it doesn’t require you to do anything extra, except that your application should run in JRuby. The latest version basically allows you to say “glassfish_rails start” while standing in your application directory.

…what compromises are we making for Sun’s involvement…

Yeah. What compromises are we making for Sun’s involvement in the community? Except handling the fact that we get more commercial backing, more money in the ecosystem, more help from Sun engineers creating high quality Ruby code, a server that happens to host the SVN server for Ruby itself, and so on? Are these contributions? Sure. Are they commitments? Yeah. Are they something that will require compromises from the community? No, not really.

Sometimes I think that many in the Open Source world still panics as soon as a big company starts to make inroads. And yes, in many cases this hasn’t worked out well. But we gotta see to the facts too. Some companies we will never be able to trust, but Sun has definitely been on the right side of the Open Source fence for a long time. Come on, people.



Should Ruby have optional typing and compiler directives?


I’m starting to miss a few Common Lisp special forms more and more. To be more specific, I miss the family of declare/declaim/proclaim. I think a version of them could actually be extremely useful for Ruby. The current approach to String encodings in 1.9.1 uses a “pragma” inside of a comment on the first line of a Ruby file, like this:

# coding=utf-8

This works fine for coding, I guess, but I would like to have something more general – something that can be used inside of code too. As a typical example of the kind of thing I would love to be able to do, here is an example of a Common Lisp implementation of fib:

(defun fib (n)
(cond
((or (eql n 0) (eql n 1)) n)
(t (+
(fib (- n 1))
(fib (- n 2))))))

As you can see, it’s the standard implementation. But, after this implementation is finished, I can continue by adding declarations:

(defun fib (n)
(declare (integer n))
(cond
((or (eql n 0) (eql n 1)) n)
(t (+
(fib (- n 1))
(fib (- n 2))))))

This will help the compiler by telling that the n-argument is always an integer. You can also add more information to the declaration:

(defun fib (n)
(declare (integer n)
(optimize (safety 0)
(speed 3)))
(cond
((or (eql n 0) (eql n 1)) n)
(t (+
(fib (- n 1))
(fib (- n 2))))))

Now we’re looking at some directives about how the compiler prioritize between safety and speed. You can also add directives for how much debug information should be retained or if the compiler should improve speed or size. All of this is interesting, but if I compile it with SBCL I’ll get a few warnings. I’ve specified I want a high level of speed and low safety, but there are many optimizations that SBCL still can’t do, so it warns about them. In most cases it’s because there is no way to see if the result of the fib-operations return numbers, floats or rationals. If fib is seen as a bottleneck, the way to fix this is to add declarations inline the code in the style of this: (the numeric (- n 1)) and so on. This will allow the compiler to generate the best code possible.

Now, these kinds of changes are quite intrusive, and they aren’t really something you want all over your code base. That’s why you can do these declarations selectively, at only the places where it makes sense from a performance perspective to do it. By doing it correctly, Common Lisp code can be compiled to be incredibly efficient and fast, but very clean since in most cases you don’t add the type declarations at all.

This is also why Common Lisp is very good for rapid prototyping. You can get something working really quickly, but you can also change the code to be efficient later on with quite small changes.

I guess you all wonder what this has got to do with Ruby. Or maybe you don’t. Anyway – I want this in Ruby, or something equivalent to it. Not necessarily the exactly same thing, but something which in a standard way can add type declarations and also other things that can be interesting to know from a compiler perspective. It needs to be a keyword with specific syntax so the information is available before runtime. It should probably be used for the encoding declarations too, so it should be possible to use either at top level, or within class declarations , or method definitions. What do I want to be able to do? Well, type declarations is the first one. The second is compiler directives that can help improve code more than is possible right now. A typical example could look like this, maybe:

declare encoding: utf-8

def test_one(first, second, *rest)
declare type: [Fixnum first, Enumerable second, Array rest]
declare return: Fixnum
declare compiler: [no-bindings, no-eval, no-closures]

puts "hello"
return 1+1
end

This code includes several things that would be very useful to know and would allow compilers like JRuby, XRuby, YARV, Rubinius and IronRuby to produce much better code. If we know that the arguments should always be specific types we can declare this and hopefully get better results. The return value is also usually the same type and declaring this can make code that uses this method more efficient. Finally, the compiler declarations will help with some of the pain points for currently compiling things efficiently. If no bindings, or evals or closures are used, the code generated will be much better.

This kind of information would be very useful not only for the compiler but also for tool support. If you know something should always be a specific type, you can add that as a declaration and things will automatically function better.

I know that this is kind of un-Ruby like, but I really believe there is great value to be had by adding this kind of declarations.



Comprehensions in Ruby


Now, this is totally awesome. Jay found a way to implement generic comprehensions in Ruby. In twenty lines of code. It’s really quite obvious when you look at it. An example:

(1..100).find_all &it % 2 == 0
%w'sdfgsdfg foo bazar bara'.sort_by(&its.length).map &it.reverse.capitalize

%w'sdfgsdfg foo bazar bara'.map &:to_sym
%w'sdfgsdfg foo bazar bara'.map &it.to_sym

Now, the last two lines are what I like the most. The Symbol to_proc tric is widely used, but I actually think the comprehension version is more readable. It’s even better if replacing “map ” with “collect”.

This is actually real fun. You can link how many methods you like – you can send arguments to the methods, you can send blocks to them, you can link and nest however you want. It apples for Arrays, Sets, Hashes – everything you can send a block to can use this, so it’s not limited to collections or anything like that.

I think it’s really, really cool, and it should be part of Facets, ActiveSupport, hell, the Ruby core library. I want it there.

Now, the only, only, only quibble I have with it… He choose to call it “The Methodphitamine”. You should actually use ‘require “methodphitamine”‘. It’s a gem. I love it. But I hate the name. So, read more in his blog, here: http://jicksta.com/articles/2007/08/04/the-methodphitamine.



New double-operators in Ruby


So, I had a great time at the London RUG tonight, and Jay Phillips managed to show me two really neat Ruby tricks. The first one is in this post, and the next one is about the second.

Now, Ruby has a limited amount of operator overloading, but that is in most cases limited by what is predefined. There is actually a category of operators that are not available be the regular syntax, but that can still be created. I’m talking about almost all the regular single operators followed by either a plus sign or a minus sign.

Right now, I don’t have a perfect example of where this is useful, but I guess someone will come up with it. You can use it in all cases where you want to be able to use stuff like binary ++, binary –, /-, *+, *-, %-, %+, %^, and so forth.

This trick makes use of the parsing of unary operators combined with binary operators. So, for example, this code:

module FixProxy; end

class String
def +@
extend FixProxy
end
alias __old_plus +
def +(val)
if val.kind_of?(FixProxy)
__old_plus(" BAR " << val)
else
__old_plus(val)
end
end
end

puts("Foo" ++ "Baz")

will actually output “Foo BAR Baz”.

I’m pretty certain someone kind find a good use for it.



London RUG tonight


Anyone showing up for the London RUG tonight? Seems like it will be interesting: Ruby2Ruby and ParseTree, and also Jay Phillips about Adhearsion (which is really cool).

I will not be presenting, so don’t worry about that. =)

Hope to see you there.



NetBeans Ruby support


It’s very nice. Each time I get an update from Tor Norbye’s blog with screenshots from the NetBeans Ruby support I see a new interesting feature. What I saw this time (here) was that the gotcha from my entry called “Ruby is hard” can now be detected by NetBeans. It’s not really too hard, since NetBeans have the parse trees. But it’s still a very nice feature to have in your editor.

But I ain’t switching from Emacs yet…