måndag, februari 25, 2008

Language design philosophy: more than one way?

When talking about how dynamic scripting languages are designed, people have a tendency to divide them into "There is more than one way to do it" and "There is one way to do it". Perl is the quintessential example of "more than one way", and Python is the opposite, going so far as to make it impossible to have your own indentation.

These different ways of doing things really divide programmers. Some hate the way Python gives you a bondage strait jacket and no scissors, while some programmers love that they don't need to make any choices and that everyone's code will be equally readable.

From a pure perspective, the Python philosophy seems to be the right one, but it just doesn't work for me. In the same way, I agree with Perl's way of doing things, but the problems that cause in most Perl code is just amazing. Sometimes it feels like the Python way is actually directly a result of someone reacting extremely badly to a Perl code base and decided to never allow that to happen in Python.

So what's the point? Well, the point is Ruby. In fact, Ruby has almost all of the flexibility of Perl to do things in different ways. But at the end of the day, none of the Perl problems tend to show up. Why is this? And why do I feel so comfortable in Ruby's "There is more than one way to do it" philosophy, while the Perl one scares me?

I think it comes down to language design. The Python approach is impossible for the simple reason that what the language designer chooses is going to be the "one way", by fiat. Some people will agree, and some will not. But what I'm seeing in Ruby is that the many ways have been transformed into idioms and guidelines. There are no hard rules, but the community have evolutionary evolved idioms that work and found out many of the ways that doesn't work. This seems to be the right way - if you do the choice as a language designer, you have actually chosen the people that will use your language: that's going to be the persons who doesn't dislike the language designers choices. But if you leave it open enough for evolutionary community design to happen you can actually get the best of both world: both a best way to do things, and something that works for a much larger percentage of the programmer world.

I have come to believe that this is one of the major reasons that Ruby feels so good to me, and is such a good language. And it's a lesson for language designers. When you choose philosophy, make sure to take the possibility of communities and idiom evolution into account.

onsdag, februari 20, 2008

SF presence

So, next week and the week after that I'll be in San Francisco. I'll participate in the ThoughtWorks code jam on Tuesday and Wednesday, and do a tech talk at Google sometime by the end of the week.

If someone is interested in meeting up, talking about JRuby, Ruby or programming languages in general, just get in touch.

lördag, februari 16, 2008

Is Groovy like Java?

I usually don't mention the G word in my blog - the results have a tendency to be less than palatable. This time I'm going to make an exception though. The reason is that this meme has been floating around as an argument for Groovy, and I really don't agree with it. In fact, the reason I'm writing about it is because I think the meme in itself generally can be bad for Groovy.

The thing I'm talking about is the saying that Groovy is just like Java. That you can start using Groovy directly without learning anything about Groovy and that basically all Java syntax is valid Groovy.

Now, the last part has never been really true, since there are a few valid Java constructs that are not supported in Groovy (anonymous classes, I'm looking at you). This might be fixed in the 1.5 version. I don't really know, but that's not the point. Since Groovy isn't using the Java parser there will always be a few small corner cases that are not valid in Groovy but Java accepts. This is not a problem, by the way. The only way it can be a problem is when you're using Groovy the wrong way, or you absolutely need to do something that Groovy doesn't support. Since one of the Groovy catch calls is that you shouldn't implement everything in Groovy, this can't really be a concern either. If you're using Groovy correctly, you should just drop down to the Java layer for that particular feature.

Now that that part is out of the way, let's take a look at the other parts of this idea. Namely that you should choose Groovy because it's just like Java, and you can start writing Java code directly in Java. These statements are definitely true, since you can absolutely pick up a language that way. In my mind, though, this misses the whole point of using another language on top of the JVM. If you're building an application and chooses to use Groovy for this instead of Java, isn't the reason that you're doing that the fact that you expect Groovy to give you something Java does not? And if that's the case, doesn't it sound like a disservice to people picking up Groovy to say that they can begin by just programming Java. There is no gain here. Really. In fact, the equivalent program in Groovy and Java will perform much worse on Groovy since there are several layers of dispatching in Groovy that you don't have in Java. The result? An application with exactly the same source code, but running 10 times slower.

Since this message is mostly used in marketing and introduction facilities, the people it's geared at are by definition newbies to the Groovy world. Many of them are totally new to dynamic languages. And the first thing they do is write Java in Groovy, find it slow and obviously, from that point don't understand why you should use Groovy. This is bad for Groovy. Groovy has some extremely powerful features and libraries that can really make your life on the JVM blissful (compared to using Java, for example). Groovy's integration with Java is top notch, which means that you can always fall back to Java when you need Java specific features. If you're using Groovy, I think you should use the full power of the language so you can actually get the full benefit of Groovy.

torsdag, februari 14, 2008

Soft and hard layers

I hadn't read this specific c2 post, but it's funny how much of what I write is just a rehash of stuff Cunningham and company came up with 15 years ago. Well. I guess that's why they're the masters and I'm not.

Incidentally, this is my 300th blog post, since starting this blog a little bit more than 2 years ago. Time rushes by, don't it?

Scala exploration status

Someone asked in a comment where my Scala exploration were going. It's a fair question.

I did a first implementation of the core of the system I was using. Most of if was tested using Specs (which incidentally is very good, and even more importantly - have a responsive creator). Now, I realized a while back that the implementation weren't really using Scala properly. I had mostly used the imperative way of doing things. So I'm planning a rewrite of these parts, using pattern matchin, case classes and more recursive algorithms correctly. It's kinda funny. I didn't expect this to happen since I have so much experience with functional languages. But apparently, the fact that Scala looks like Java in many regards makes it very easy to slip into the Java imperative mode. Not good.

Right now I'm spending some time working on the next release of JtestR, writing on a book, and doing some pesky day time work. =) Also, JRuby needs to have its 1.1 release. I expect to get back to Scala within one or two weeks, though.

Silly Io experiment

I have known for some time that Io is quite powerful as a language. I wanted to check if it was also suited for creating DSLs. Since I'm lazy I didn't want to create a new DSL just for this, so I decided to appropriate the associations language from ActiveRecord.

The process I followed was this - first come up with something that looks passably nice, then try to implement it. The only requirements was that the names of the associations were saved away somewhere, once per prototype for each model. This is the syntax I came up with (well OK, I didn't work very long on it...):
Post := IoRecord {
has many authors
belongs to blog
belongs to isp

Author := IoRecord {
has many blogs
has many posts
has one name
Actually, this looks almost readable, right? It's all valid Io code. The question is, how do we get it to do what we want? Without further ado, here's an implementation that gives us enough:
IoRecord := Object clone do(
init := method(
self belongings := list
self hasOnes := list
self hasManies := list
self hasFews := list

appender := method(msg,
blk := block(
call sender doMessage(msg) append(call message next name)
call message setNext(call message next next)
blk setIsActivatable(true)

collector := method(
meths := call argCount / 2
waiter := Object clone
for(index, 0, meths-1,
waiter setSlot(call argAt(index*2) name,
appender(call argAt(index*2+1)))

belongs := collector(
to, belongings

has := collector(
many, hasManies,
one, hasOnes

curlyBrackets := method(
current := self clone
call message setName("do")
current doMessage(call message)
Since I'm a bad person and really enjoys metaprogramming, I had to get rid of most of the duplication the first implementation contained. Let's say it like this: the first version didn't have the collector and appender methods. And boy do they make a difference. This is real metaprogramming. Actually, these two methods are actually macros, almost as powerful as Common Lisps. Notice that the words we send in to collector doesn't actually get evaluated. This is one of the reasons we don't need to use symbols - we can just take the unevaluated messages and take their name. In the appender macro we're doing something really funky where we use setNext.

The final effect of that setNext call is that in something like "has many foobar", Io will not try to evaluate foobar at all. In fact, even before Io tries this, we remove the foobar message from the chain and inserts the next message instead.

Oh, right, and the Io lexer actually inserts a synthetic message called "curlyBrackets" when it finds curly brackets. The brackets themselves actually act exactly like parenthesis. You can try this out in Io by changing the closing parenthesis to a closed curly bracket instead - Io doesn't care. Your brackets doesn't have to match up in type, just in cardinality.

Of course, this is just the beginning. Io will blow your mind.

The thing I'm finding myself missing is a good literal syntax for hashes and lists. I'm thinking about implementing something for that. Also, using atPut is starting to get annoying. I want square brackets access. Shouldn't be too hard, since Io does the same thing with square brackets as it does with curly brackets. Almost, at least.

And btw, the Io standard library... Not sure what I think about it. I miss many things from the Ruby core library actually. Now, Io combined with the Ruby libraries, that might be fun?

onsdag, februari 13, 2008

Java Annotations

I feel that a few rants are about to burst in me. Let me take this first; this is not a rant, though. Just a very large exclamation:

Java Annotations are NOT a way to implement DSLs, and will never be.

Java annotations are really nice, but seriously, they are NOT manna from heaven.

lördag, februari 09, 2008

The upcoming JtestR release

I'm spending some time working on version 0.2 of JtestR, which has the goal of rounding out the framework, adding some needed things like RSpec story support, test coverage metrics, TestNG running, groupability of tests, support for CC.rb and Expectations.

Now is the time to tell me if there's anything you are missing from JtestR that stops you from using it! Either by a comment here or by the JtestR JIRA at http://jira.codehaus.org/browse/JTESTR.


tisdag, februari 05, 2008

Ruby.NET closing down

A letter on the Ruby.NET mailing list just announced that Dr. Wayne Kelly have decided to shut down the Ruby.NET project and instead asks everyone to contribute to IronRuby.

More information can be found on the mailing list thread here.

I don't like these news at all. In many ways having a strong competitor is something that will improve the ecosystem for everyone. Now IronRuby will become the only player on the field - unless other people (like Ted Neward and David Peterson) decide to pick up Ruby.NET. I hope someone does. The .NET world will be better of for it.

The crucial question is not whether we trust John Lam about IronRuby. The question is if we trust Microsoft to do the right thing. Do we?

JNA is really, really good

The last few months JRuby have used something called JNA to introduce some functionality we couldn't do before. This mainly includes POSIX file operations of different kinds. I've just spent a few days getting a basis for UNIX Domain Sockets working in JRuby, using JNA, and I've gotta say that I'm incredibly impressed by it. For simpler function calls, it just works. For more complicated stuff you might have to set up structures and so on, but it's still incredibly slick. The best part: no native compilation needed.

Of course, this has some performance considerations, but it's still better than nothing.

fredag, februari 01, 2008

Denmark, QCon and JavaOne

Today is my last day in Sweden for a while. It's been an incredible time, and I think that my coworkers from ThoughtWorks have had a wonderful experience in Sweden. What will happen regarding a Swedish office is still up in the air, but I'm cautiously optimistic about it all. In fact, if someone knows a possible client please get in touch. =)

Next week I'm going to Denmark, visiting the castle Hindsgavl where the Danish Java User Group (JavaGruppen) is holding a conference. I will do one presentation on JRuby and one tutorial on JRuby on Rails.

The next planned event will be QCon in London where I will present about some of the more exciting upcoming features in the JVM. That's going to be great fun.

The last week in February I'll be in San Francisco, possibly helping out with some really cool ThoughtWorks events. I'll post more about that when I have the information.

I will also present at Developer Summit in April, in Stockholm.

Finally, expect me to do one presentation and one BoF at JavaOne. I might also do a talk at CommunityOne.

It's going to be a busy spring time.