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.

6 kommentarer:

Michael Foord sa...

You must have known I would react to this post. ;-)

The thing I love about Python is the way it *doesn't* restrict me - it is one of the 'freedom languages' not one of the bondage languages.

Of course you can't do dumb things like modify the built-in types. ;-)

You are wrong about the indentation though - you can use whatever indentation you want with Python, so long as you are consistent...

The full rendering of the Python philosophy is - 'there should be one obvious way to do it' of course.

Anonym sa...

Actually ruby has one problem (and as a language it is better than python, only keyword arguments is what i still miss in ruby):

- it is too complex.

Io language has (its weird syntax aside) the conceptual elegance of not bothering with class and modules, you simply go and model your object. In Ruby this is possible too but it never reaches the conceptual elegance of Io's model - just try to get Ruby to introspect something. In Io this is easy.

Now, a "serious" programmer has no problem, but what too many different ways are not always good if there are no valid examples.... for example @@class_vars. I think they are a misdesign. But what is even worse is the syntax rules in Ruby. This is becoming like perl (and perl is a horrible language too, only php beats perl)

Take (1..100).inject(&:+) for example.
To anyone coming to ruby anew this looks weird.
Ok 1..100 is a range, and .inject is an obscure name for some method... so what is &:+ ?

And there are countless things of these to know.

Dont get me wrong, personally I feel there SHOULD be more than one way BUT there should always be a CLEAR way to do some task.

Python's philosophy is better in theory, but in practise python shackles you, and this alone is a very good reason to not use python at all. It reminds me of some linux distributions disabling superuser login at default without asking at all.

You should always end up doing the decisions and being ABLE to do a decision. Yes, it brings greater responsibilty and may lead to pitfalls but at least you have the freedom to think and enjoy the creativity you get.

I just believe the best next generation would be one that takes from python ruby and Io, mixing concepts, blending it but also trying to stay simple enough for new people to not make their brain explode :-)

rasputnik sa...

The inject example is a little unfair - you can easily do the same thing in a few more keypresses and make it much more readable.

Ruby has decent OOP, Perls sucks. That's the difference.

thing.method is just easier to hold in your head than method(thing), since you can see at a glance all the relevant operations that thing supports. Add in blocks and iterators and you avoid a lot of wheel re-invention which clutters up most Perl code.

Anonym sa...

I suggest you all check out the philosophy of XMF which seems to have a perfect fit to get the best of both worlds.
As a language designer you can enforce idioms, guidelines and choices for the ”language” user. The “more than one way to do it” philosophy support the design of the “only way” were needed, such as bespoke DSLs, embedded sugared language extensions. Total flexibility.

XMF 2.0 is recently open sourced. Check out the resources on http://www.ceteva.com


Anonym sa...

One might envision that the same orderly idioms could have emerged from the culture around Perl. But it didn't happen that way.

So adapting a philosophy that takes community and idiom evolution into account is leaving is leaving order to hazard--unless there is something intrinsic to the Ruby language but not to Perl which would foster such a culture around it.

Anonym sa...

I don't think it's better than python. in some cases maybe...