Ruby the Rival

Chris Adamson at OnJava.com published interviews with a few language luminaries and Java developers. Inspired by Bruce Tate's book Beyond Java, Adamson argues that Ruby is poised to become Java's successor:

Bruce Tate's Beyond Java argues that Java's reign as the top enterprise development language must eventually come to an end and that, for the first time in a decade, major enterprise innovation is occurring outside of the Java realm. In the book, he looks at the unique traits that has allowed to Java to achieve its unprecedented level of success, and then considers what new languages would have to do and be to succeed Java.

Later chapters look at specific languages contending in this space, and clearly favors Ruby as the front-runner. This comes from Tate's own performance breakthroughs (fueled by Ruby on Rails), an analysis of the language, and anecdotal evidence from others who've tried the language.

Is Ruby already shaping up to succeed Java? What's broken with Java that Ruby fixes? And are the two mutually incompatible?

To survey the situation, we contacted several prominent authors, bloggers, and developers to get their takes. Their responses are reprinted in whole in this article.

The interviews are a very interesting read, and the dialogue covers a diverse range of topics. The power of Ruby on Rails is a common theme throughout, and Tate argues that Rails is the catalyst that will push Ruby into the mainstream. What I don't understand is this: if Rails will make Ruby the next Java, why didn't Zope do that for Python?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

In Defense of Zope

At the core of Zope, the object publishing is remarkably clean and easy to learn.

The additional framework layers such as Access Control were poorly documented, but it is not necessary to use it to develop your own applications.

Zope had a language stew, and some of them was to work around unprivilegied users running privileged code on the system. This again detracts from the simplest aspects of object publishing.

CMF and Plone are a programming mess because of the inversion of control and highly coupled classes that are used as the base of the framework. It is no harder than any plug-in based framework though such as Eclipse or Visual Studio.

Zope didn't do it...

... but maybe Django will?

I'm a Ruby fan myself and I'd take it over Python everytime (mostly I never really liked significant whitespace... and I'm a bit disappointed with the news of Python 3000 and very excited about Rite), but these two frameworks (Rails and Django) seem to be on the spotlight now.

the IDE is missing

There's no IDE for Ruby that's nearly as good as IntelliJ or Eclipse. Until that happens, migration from Java-land is going to be pretty limited.

why not Zope

hi there,

more than 50% of the developer population is familiar with 1 or more scripting language(javascript/php/python/ruby).

The time for scripting languages(better CPU power) seems to be new.

With AJAX, javascript features will become more popular; AND the frameworks that make AJAX "EASY" will become even more popular.

RoR seems to be going that path -- also, it has a handfull of well known developers behind it.

Also, this is the age of the Internet when something really good has a good chance of being heard.

My 2 cents.

BR,
~A

Possibly...

...because the whitespace, oddly featured OO'ness (__self__? c'mon, please!), "one way to do it", and general "in your face" attitude of many of the "Pythonistas" turns a lot of developers off.

Ruby is clean, its newsgroups are well mannered (generally), and despite pleas to the contrary, it just SEEMS like it nailed the "lispyness" aspects a lot closer than Python.

Too, it has a lot of benefit of hindsigt.

Self?

Why do you feel that "self.value" more odd than "@value"?

Your point of view is interesting, because I've always felt that whilst Ruby is more powerful, it feels messier than Python does.

__self__

He didn't say "self", he said "__self__". I think he is referring to the crappy naming scheme used for things like constructors (__init__), destructors (__del__), operator overloading (__radd__ or whatever).
Also you have to explicitly type "self" as the first parameter for any method that is part of a class, even though the method is part of a class.

See http://boo.codehaus.org/ for an alternative that corrects some of python's warts.

Ohhh

Ohhh, well, in which case I completely agree :) - those parts of Python do very much suck, along with the syntax for descriptors. Yuck!

Successors?

At least young academics starting in the company I'm working for are filled with Java+Eclipse. But I understand the need of media for hype, news, "the next big thing", language pissing etc. It's an aspect of entertainment around IT and the hysteric sociology of our business. The reason why Ruby is hyped now has nothing to do with some webframework, which might be usefull for some people but with the urgent need for hype itself. Ruby fits perfect at the moment, because it is fresh and cool - a new name, a new game. Since Java programming languages have to be pop-stars. Besides this Ruby transports other important memes that are ready for spreading: "dynamically typed languages can do it as well" and "with > 3GHz machines CPU cycles have become less important for most apps" - which is particular true for web applications.

The higher you catch the deeper you fall. Good luck for Ruby...

Kay

"The higher you catch the dee

"The higher you catch the deeper you fall"

That goes for java as well. I don't think hype is the only thing going for ruby. It's a pretty solid language with good libraries going strong each day...

comparing languages

I was just discussing with someone today, you can't trust people to compare languages. Two reasons:
- To properly understand a language is not a 3 or 6 month project, it takes years. To compare them, you need to understand both well, that takes many years.
- The comparisons are almost always too general. "What is a better langauge?" makes no sense. "What language should I use for this job?" is a question that actually has an answer.

As a result of this, we get mob mentality in programming language popularity. Ruby on Rails is a perfect example of this. Regardless of its merits in any particular area, we are getting ridiculus articles like this one. The only interviewee I agreed with was the last. I thought his distain for the questions was both obvious and very appropriate.

The economics of programming languages

The older I get, the more interested I'm getting in economics as a way of explaining things. I wish I had time to learn something about it more seriously and systematically... take what I have to say with a grain of salt.

Consider this: if it takes you or I, who have made a career out of "computer stuff", months to learn a language well, what of the "average joe" who isn't a very good programmer, or who is just learning a bit to get some job done. There are an awful lot of people out there like that. It's going to take them longer, so it's a bigger investment for them. That makes them nervous, and defensive of the investment once they've made it - they want to get the most possible out of it, and feel like they made the right choice. With most any task they face in the future, they're going to be doing it with the tool they know or not at all, rather than learning another one, and so they want to be very sure they've got something that will work for them.

It also means that they are also likely to be making the investment with even less ability to judge it than a more advanced practitioner might, so they are going to look for signals that they're making the right choice.

Viewing the situation this way lets us understand it a bit better, in my opinion.

Dynamic languages

We recently see a lot of "hype" so-called dynamic languages. Of course, it allows some easy metaprogramming, which seems to be a key part of the success with Ruby.

However, as a long-time user of statically typed languages (mostly OCaml), I'm very upset using Python or Ruby (which I both tried cause I do find them attractive) when getting many runtime errors, especially when discovering a new API -- you don't really know what a new function wants, and so on.. Experienced programmers always tell you they don't make mistakes, but well, I don't trust them :p

I believe that these languages could be less dynamic. Metaprogramming stuff could be isolated, maybe as a kind of restricted preprocessing. Eval is not so much used. And so on. This would allow static checks, but also faster execution.

I think it's a pity to see many communities who don't share anything. Some languages develop languages with wonderful inference for static type systems so it's very light to use and avoids runtime errors. Other languages do a great job on usability, syntax, expressiveness, and get huge efficient communities. But they don't share anything. Languages like Boo pretend to mix the two sides, but it's very shallow. Functions are nearly untyped (the system on infers the number of arguments), so what is called inference really doesn't deserve the name. I don't know if the recently announced C# inference does better stuff, but it's very disappointing.

Java is also 'dynamic'

The funny thing is that Java is also a 'dynamic language'. You can always use 'Object' as a type. Ok, you have to cast it to some other type before calling a method, but that don't prohibit you using it in the same way like you use language which offers only dynamic typing like languages like Ruby.

Also Java is higly reflective, has closures and with the new annotations you can also do lots of metaprogramming. So I don't really see why people are always bitching about Java being a 'static language'.

Because it is...

Why do people call java a statically typed language? Because it is. The compiler checks types at compile time, that's the definition of a statically typed language. Of course you can do a little dynamic typing using casts and reflection in Java (as you could do OOP in C, but that didn't make it an OO language), but that's nothing compared to Ruby, where you can add, remove or change methods of a class or even a single object at runtime. Just think of those famous "attr_reader/attr_writer" functions Ruby has: it's pretty much impossible to do metaprogramming like this in Java. I'm not really a fan of Ruby (it's way too perlish for my taste, never understood why people would call it "clean") but it certainly does have features Java does not.

Only if you want

The compiler only checks types where you want him too. If you use 'Object' for most types, the compiler will check this at runtime - like Ruby, Lisp etc do. Sure, static typing is the default for Java (and I think its good this way) but that doesn't mean that you can't program with dynamic typing.

So it's kind of 'best of both worlds': Use static typing for compiler type checking and 'compiler checked documentation' - and dynamic types where static typing is too limiting. Java is in no way comperable to C/C++ in this way, it goes much further.

Some time ago I've build a small framework which creates swing-guis directly from arbitrary Java classes and allows you to display and edit any Java-Object via a swing-dialog without writing any additional code. In C/C++ you have to write and use a complicated macro-based framework which emulates reflection - and it won't be compatible with legacy-code because you have to write lots of annotations for every class you define.

About 'attr_reader/attr_writer': You can do this in Java too, for example with tools like apt - which will be integrated in javac up from 1.6. You can even do it at runtime - just create the code somehow and load it at runtime via a custom classloader. Sure, it's probably easier to do in Ruby, but it's all but impossible in Java. Java tries to enforce a certain programming style and if you go against it, it will become more difficult - but it's still possible.

So I've yet no idea what missing Java-feature should stand in the way of creating something like RoR in Java too.

Nope

I don't want to be too harsh but you're just wrong according to the accepted definitions of static and dynamic.

Trying to express the following 10 lines of python code is a more than a little difficult in Java:

>>> class foo:
...     """ Create a class with one method """
...     def method(self,x): print x
... 	
>>> bar = foo() #Instantiate it
>>> bar.method(1) # use the instance
1
>>> def newmethod(self,x): print "new", x #create a new method
... 
>>> foo.newmethod = newmethod # Bind to the class (and instance as well)
>>> bar.newmethod(1) #use the new method
new 1
>>>

It'd be worth taking a serious look at a dynamic language, be it python, ruby, scheme or something else.

Sure it is

First: Thats possible because of of Pythons object system, it's not a feature of dynamic typed languages per se. And there are also things which you can't do in Python but are possible in other languages. For example with Lisp macros you can do things you're not able to do in Python. So is Lisp the only real 'dynamic' language now?

But if you want a facility like this in Java you can easily create one, you just can't use it in the same way you use normal Java methods and have to call them with something like 'call(foo, "newmethod", x)' instead (which is good according to Javas philosophy because you don't 'trick' people who are reading your code into having wrong asumptions about your code). And if you really want, you can create a new classloader which rewrites normal method-calls to the call-style above (if you can afford the loss of performance because of the now much slower method calls and the implicit casts).

Repeating it won't make it true...

First: Thats possible because of of Pythons object system, it's not a feature of dynamic typed languages per se. ...
The point is: you can change the type of an object, the interiors of a type, or the interiors of a single object in those dynamic languages. You just can't do that in java. Casting to Object doesn't change the object a bit, it only changes the type of the variable you use to point to the object, that's a huge difference, and from your previous posts I'm not sure you really got that.
But if you want a facility like this in Java you can easily create one, you just can't use it in the same way you use normal Java methods and have to call them with something like 'call(foo, "newmethod", x)'
As I said earlier, you could do OO programming in plain C using structs in structs and lots of function pointers, but that didn't make C an OO language. In the very same sense you can of course simulate dynamic behaviour in java, but that doesn't make it a dynamically typed language either. You could as well include Jython in your java app for your dynamic code, but that won't make java a dynamically typed language.
By the way: Even if you built a "dynamic-call-system" like the one above, you still couldn't change the behaviour of a plain java "String" or "Array" object (or, in fact, any object parameter you might get from some calling code outside your control), could you?
And if you really want, you can create a new classloader which rewrites normal method-calls to the call-style above
I don't really see how this should work for grant's example above, because you'll have to get your code through the javac compiler first before it ever sees your classloader, so it must be well-formed java. I don't think you could convince javac to compile code that declares a class with one method, later in the file calls another method, and even later on adds the second method. You'd probably have to rewrite the javac compiler, too. I'd argue it's no longer java then...

Dynamic language vs. dynamically-typed language

you can of course simulate dynamic behaviour in java, but that doesn't make it a dynamically typed language either.

Note that there's a distinction between a "dynamic language" and a "dynamically-typed language". Java has a number of dynamic features built-in as part of the language — such as reflection and runtime class loading — even though there's no doubt that it's a statically-typed language. Earlier in the thread, karsten_w claimed that Java was a "dynamic language". For some reasonable values of "dynamic language", that's true, although as I mentioned in another comment, there's a spectrum of language features from static to dynamic, and Java certainly isn't as dynamic as most dynamically-typed languages.

Some clarifications

First we have to differentiate between 'dynamic language' and 'dynamic typed' language. Both things are intermixed here and that creates some confusion.

Dynamic typing means that variables (or fields etc.) don't store type informations, while in static typed languages they do. In this sense Java seems to be a static typed language, but because you have the possibility to also use 'Object' as a type everywhere you want, you can remove this feature and have the same behaviour in Java too - you only have to cast before calling a method via a variable which is declared as 'Object'. Compare that to a real static typed language like Haskell: Something similar is simply impossible there. So in the strict sense Java isn't statical typed - and when it's not statical typed it have to be dynamical typed because there is no other possibility. So in Java you have the advantages of statical typing in most parts of your program, but if you need it you can also use dynamic typing.

But: 'dynamic typed' don't mean that you can change the type of an object at runtime. Thats a feature of certain object-systems.

Then we have the term 'dynamic language'. I'm not aware of a clear definition of this term so it seems that everybody use it like he wants. If you define 'dynamic language' as 'can be changed in any way you want at runtime' then Java is of course less 'dynamic' then Python. But also Python is less dynamic compared to Lisp then. In Jave you have certain dynamic features: You have comprehensive reflective features and you can create and execute new code or modify existing code at runtime (via custom classloaders). But if you want more (like in the example) you have certain limits which you can only overcome by using something like a custom calling scheme. But thats similiar in Ruby if you compare it to Lisp. So where do you draw the line between 'dynamic' and 'not-dynamic'?

you still couldn't change the behaviour of a plain java "String" or "Array" object

You need to translate Method-Signatures etc from 'String' to 'Object', calls from obj.method(...) to call(obj, "method", ...) and remove casts. But I admit that it's not really easy and has its limitations. But why do you even want to do it? To obfuscate your code by changing behaviour of well known objects? For the same reason Java don't support operator-overloading.

But for the things you need to do to create something like RoR, Java is dynamic enough.

So we agree that - java is a

So we agree that
- java is a statically typed language
- python, ruby, lisp have lots of "dynamic" features java does not have (at least not built in, anything can be simulated in a turing-complete language)?
If so, I don't see what your point was in the first place?

Also note that an important aspect about dynamically typed OO languages is "duck typing", which can only be simulated in Java using reflection.

Not totally

Java is not statically typed in the strict sense, and hence you have all posibilities you have in a 'only-dynamic'-typed language. Thats my point. Most people (I suspect you too) don't understand the implicatons of this and so I wanted to point that out. There is no limitation of Javas type system which prevents you to do anything you can do in other dynamic typed languages, you just need some additional casts. In Java its much more simple then for example in C++. Before Java 1.5 collections were fully dynamically typed - why is that even possible if Java is 'only' a statically typed language? Even with generics Java isn't statically typed in the strict sense, because there are situations where runtime type errors are possible, even if you don't use a cast (I don't consider that as good, but it shows that those 'Java isn't dynamically typed' statements simply show lack of understanding of the meaning of statically and dynamically typing).

But yes, Python, Ruby and Lisp have features, Java don't have - and Java has features those languages don't have (ok, in Lisp you can emulate them if you want). But that doesn't mean that Java isn't 'dynamic', its just a result of having different languages. Haskell is less dynamic then C++, C++ is less dynamic then Java, Java is less dynamic then Ruby and Ruby is less dynamic then Lisp. Its not a yes-or-no or black-or-white think, its a continuum.

And no, "duck typing" is not an aspect of dynamically typed languages. There are lots of dynamically typed languages which don't even have an object-system. Its an aspect of certain object systems, not of the type system. Its sad that both things are always intermixed.

There seems to be some confus

There seems to be some confusion about the term "statically typed" here: I'd suggest you read up on the definition of static vs. dynamic typing, e.g. at: http://en.wikipedia.org/wiki/Dynamic_typing#Static_and_dynamic_typing
There's also a paragraph about what's possible in dynamic languages but not in static languages and vice versa.
Since every Java bytecode instruction that calls a method needs the type where the method has been declared (which may of course be a base class or interface), the compiler has to enforce static type checking, simply because it needs to emit the type information. That's the whole point. (Well, most of it.) The fact that you can simulate different behaviour is irrelevant: you can simulate every behaviour in a turing-complete language.

About duck typing: If you have code like "obj.foo()" in a dynamically typed language, there's no type information included in the variable, so the only way to find out which method should be called is to look it up by name for this specific instance. That's called "duck typing". That's the connection between the two: If a language is dynamically typed, and supports OO, it more or less has to be duck-typed. I don't think there's an exception to that rule.

There is obviously some confusion

Dynamic languages have a very simple type-system: Every static type is 'Object'. In Java you can easily write

Object x;
x = 5;
x = "hi";

Only if you want to write maybe 'x + 10' you need casts or conversations. The difference is that in Java you need to make this conversation explizit while a language like Ruby makes it implicit (thats called coercion and has per se nothing to do with static or dynamic typing). And you can always write a 'add-with-coercion' Operator in Java, its simply not build in because the designers of Java wanted to enforce the use of static typing. So with this Operator I can write in Java:

Object x = 10;
Object y = "4";
Object z = add(x, y)

(Using 'add' instead of '+' is a result of not having operator overloading in Java, not of the type system).

Btw.: Ruby don't permit to call 5 + "hi" (like in the wikipedia example), that would give you an TypeError - but thats not because Ruby isn't dynamically typed, its because of Rubys coercion rules.

About Duck typing: I looked at http://en.wikipedia.org/wiki/Duck_typing and guess what I found: "Duck Typing in Java". How would this be possible if Java is really only statically typed? In Java every Object has a reference ('type tag') to the class (and hence the type) of the object. Thats totally similar to Ruby.

Also in your wikipedia articel they wrote:

"The presence of static typing in a programming language does not necessarily imply the absence of dynamic typing mechanisms. For example, Java is statically typed, but certain operations require the support of runtime type tests, which are a form of dynamic typing. See programming language for more discussion of the interactions between static and dynamic typing."

In other words: Java is "statically typed" and also has "a form of dynamic typing". Thats what I wrote: Java is both, "statically typed" and "dynamically typed". So you have the choice what to use depending on the situation. I consider that an advantage to being forced to rely on dynamic typing only.

Dynamic languages have a very

Dynamic languages have a very simple type-system: Every static type is 'Object'.

Personally I don't like the term "dynamic language", because I think it's somewhat ill-defined, so I'll just talk about dynamic typing.

Object x;

x = 5;

x = "hi";

Only if you want to write maybe 'x + 10' you need casts or conversations. The difference is that in Java you need to make this conversation explizit while a language like Ruby makes it implicit (thats called coercion and has per se nothing to do with static or dynamic typing).

Nope. In fact, Ruby doesn't do any coercion at all, that's the difference between the two: Consider ruby code like this:

def foo x
  x << "Hello World"
end
open("somefile.txt", "w") { |f| foo f }
foo [1,2]
foo "Some prefix: "
'x' isn't coerced to any type. A member of 'x' is being called, and what this member is is looked up at runtime. The equivalent java code would look like this:
 void foo(Object x)
 { ((SomeType)x).Add("Hello World"); }
This time, you do need coercion, and you need to explicitly specify the type you want the object coerced to.

Btw.: Ruby don't permit to call 5 + "hi" (like in the wikipedia example), that would give you an TypeError - but thats not because Ruby isn't dynamically typed, its because of Rubys coercion rules.

Create a java swing app, which outputs the result of 5+"hi" when you hit a button. Create a ruby tk app, which outputs the result of 5+"hi" when you hit a button. In java, you'll get a compile-time error, as the types are checked at compile time. In ruby, you'll get a runtime error, because the types are checked at runtime. That's the difference.

About Duck typing: I looked at http://en.wikipedia.org/wiki/Duck_typing and guess what I found: "Duck Typing in Java". How would this be possible if Java is really only statically typed? It's done through reflection. Look at the sample code.

You can implement dynamic typing behaviour in every language I know, either through custom dispatch code, reflection, tricky macros, or whatever, but that doesn't make all of these language dynamically typed: only the ones where default method calls are dispatched dynamically, and no type checks are done ahead-of-time count. Otherwise, Assembler and C would be perfect dynamically typed languages as well...

Its not just black and white

Personally I don't like the term "dynamic language", because I think it's somewhat ill-defined



I've pointed this out too. But this time I made the same mistake and used 'dynamic language' instead of 'dynamically typed language'.



In fact, Ruby doesn't do any coercion at all



Hm...

>> 2 + "3"

>TypeError: String can't be coerced into Fixnum



Looks like coercion to me...



This time, you do need coercion, and you need to explicitly specify the type you want the object coerced to.



Thats not equilvalent. The '


But in Java all Collections support 'add(Object)', so you could write a similar Function in Java without any Problem:



void foo(Object x) {

((Collection)x).add("hello world")

}



That would work for every collection or throw an cast-exception for non-collections. Like Ruby if you call 'foo(2)'. So its totally similar to Ruby.



The real difference between Java an Ruby is that Ruby methods are choosen only on their name (Thats the 'Duck typing') while in Java the Method is always choosen in the context of a certain 'namespace' called 'interface'. Both approaches have their advantages, the Java one reduces the posibility of name-clashes and increases performance, the Ruby one is more flexible in some cases. But in Java you can easily emulate 'duck typing' via reflection if you really want it. But can you emulate Javas mechanism in Ruby too?



Create a java swing app, which outputs the result of 5+"hi" when you hit a button. ...



In Java it depends on how you implement that. Both are possible.



You can implement dynamic typing behaviour in every language I know



Sure, but the difficulty and usability concerning legacy-code varies. In Java you're much more flexible than in C++. Java is much more comparable to Ruby then to C++ in this sense. In C++ you simply can't call a arbitrary method of a arbitrary object without adding lots of macros to every class before (often impossible for legacy code). In Java it's quite easy. Same goes for lots of other things. I've done C++ for years and know the huge complexity for things which are totally simple in a language like Java. Sure, some things are even simpler in Ruby - but I think that for many applications Java is 'dynamic' enough without compromising lots of performance and checking like Ruby does (I use Ruby extensivly for scripting purposes and have had lots of runtime typing errors which javac would've flagged at compile time).



I don't agree to your position that only only a language without any static typing is dynamic typed. Its simply to limiting. What about for example ActionScript2 (the Flash-Version of Javascript). If you omit type-declarations its fully dynamical typed, but if you add type annotations that compiler checks them as far as possible. Or think about the static typing libraries for Lisp: Is Lisp a suddenly a static typed language if I use such a language in a part of a program? I suggest you to stop that black and white thinking, it leads to nothing.



In Java static typing is the default, but you can use dynamic typing if you want. In ActionScript2 its the other way round. These are design decisions, resulting from the history and intended areas of application of those languages. So that old distinction between dynamic and static typing is softened for some time now. We aren't living in the old times were there only were Lisp, Cobol and Fortran.


...But in Java all Collection

...But in Java all Collections support 'add(Object)', so you could write a similar Function in Java without any Problem:

void foo(Object x) {

((Collection)x).add("hello world")

}

I guess you know the difference. You explicitly tell the compiler where (class or interface) 'add' has been declared. In a dynamic language, you don't have to. That's the difference.

The real difference between Java an Ruby is that Ruby methods are choosen only on their name (Thats the 'Duck typing') while in Java the Method is always choosen in the context of a certain 'namespace' called 'interface'. Both approaches have their advantages, the Java one reduces the posibility of name-clashes and increases performance, the Ruby one is more flexible in some cases.

Among others, yes. The former approach is called "static typing" while the later one is called "dynamic typing". That's what I've been trying to explain to you all the time...

But in Java you can easily emulate 'duck typing' via reflection if you really want it. But can you emulate Javas mechanism in Ruby too?

That's exactly the point: you'd have to emulate it! You can't just make the compiler treat all your code dynamically typed (as you can e.g. in VB), you have to use the reflection API instead of calls/variable access.

In a real static typed langua

In a real static typed language something like the above example wouldn't be possible. Show me how to do it in Haskell.

In Java the 'emulation' of duck typing it easy. You only have to use

call(obj, "methodname", p1, p2, ...)

instead of

obj.methodname(p1, p2, ...)

(and have a little 15-line method 'call' written in some Lib). Thats it. No more. In C++ you have to annotate every single method in every class with macros. Thats the difference. In Java you can call even system classes like that.

Also in Java collections are dynamically typed. You don't even have to emulate it, you can put everything in an array, a set or a map. How would this be possible if Java is statically typed?

Also show me to do that in ocamls - another real static typed language (with an object system) with comparable less effort (= without creating a new object sytstem by yourself).

So I would say in the spirit of duck typing: If a language has runtime type errors like a dynamic typed language, if you can use dynamic typing with little to no effort where you need it and if you can do all the things you can do in a dynamically typed language - just call it dynamically typed.

But I suspect that this won't convince you too, you're just to stubborn. So believe what you want while I use dynamic typing in Java while having the advantages of static typing at the same time.

Less duck spirit, please

So I would say in the spirit of duck typing: If a language has runtime type errors like a dynamic typed language, if you can use dynamic typing with little to no effort where you need it and if you can do all the things you can do in a dynamically typed language - just call it dynamically typed.

Although I generally agree with what you've been saying about Java's dynamic capabilities, it doesn't clarify anything to simply call the language as a whole "dynamically typed", as though it's completely equivalent to languages which have no static typing of terms. There are important differences — we can see one of them in the example given above:

void foo(Object x) { 
   ((Collection)x).add("hello world") 
}

This illustrates quite well that Java is a statically-typed language: it contains two annotations intended specifically to tell the compiler what the static type of a particular term is.

Also in Java collections are dynamically typed. You don't even have to emulate it, you can put everything in an array, a set or a map.
Right — a more specific statement like "Java collections are dynamically typed" is much more illuminating. It points out a way in which Java is similar to dynamically-typed languages, and different from most statically-typed languages.

How would this be possible if Java is statically typed?

It's possible because Java's class & interface hierarchies can express approximate types, such as "Object". Java is not unique among statically-typed languages in having this ability. This doesn't make the language as a whole dynamically typed.

Coming back to the example above, the fact that terms have to be annotated with types shows why Java qualifies as statically typed. Even though you can embed dynamically-typed code within Java programs, at some point you have to "pay the piper" and tell Java more specifically what the static types you're dealing with are. You don't ever have to do this in a completely dynamically-typed language — in fact, you can't do it in such languages.

I would put it this way: You

I would put it this way: You can use Java like a dynamically typed language if you want, but you have to write a bit more then in a pure dynamic language. Java is not statically typed if the strong sense, because casts or runtime type errors are not possible in a statically typed language. OTOH is Java not dynamically typed in the strong sense either because you need to cast to some type first if you want to call a method.

Dynamic typing means that every object has a 'type tag' which enables you to query the type of an object at runtime. And it means that you have the possibility to assign arbitrary objects to a variable and call methods on it. Thats all possible in Java so Java is dynamically typed. But Java is also statically typed.

And why shouldn't it be possible to be both? Dynamic and static typing are not mutual exclusive: Dynamic typing means thats its possible to deside on the dynamic type of an object at runtime and static typing means that the compiler has some knowledge about the type of an object at compile time. In the old days with Fortran on one side and Lisp on the other this distinction was simple. But those days are long gone and most languages of today are some kind of mélange of different concepts. Thats true for Ruby and its also true for Java.

It all comes down to the possibilites you have in a language. And in Java you can do everything you can do in a dynamically typed language so I consider Java dynamically typed AND statically typed, depending on how you write your code. I'm not a lawyer so I'm not interested in formalities, I just look what you can do and call it accordingly.

Also Javas concept isn't very common: Most languages are either real statically typed (like most functional languages with an ML based type system) and dont allow something like a cast or they are weak typed (like for example the C based languages where you can change the type of an object at runtime). Java is strong typed (no type changes at runtime) and allows both static and dynamic typing. In the moment I don't know of another well known language like this (ok, Lisp can do it too, but Lisp can do everything with its metaprogramming abilities). Also Javas concept to implement closures is very unique - so unique that many people don't even recognise that Java has closures.

Definitions

Java is not statically typed in the strong sense, because casts or runtime type errors are not possible in a statically typed language.

That's not true. Casting (more formally known as "ascription") is perfectly compatible with static typing, and in languages with subtyping, it can result in runtime type errors. The type system of C++ is quite similar to Java's in this respect. Would you also say that C++ is "not statically typed in the strong sense"?

Dynamic typing means that every object has a 'type tag' which enables you to query the type of an object at runtime. And it means that you have the possibility to assign arbitrary objects to a variable and call methods on it. Thats all possible in Java so Java is dynamically typed.

You don't have the possibility to assign arbitrary objects to any variable, only to variables that are statically declared as Object. You can't directly invoke arbitrary methods on those objects, as you could in a dynamically-typed language, you have to first use casts to statically tell the language what type you believe those objects are. These issues are direct consequences of the distinction between a statically-typed and a dynamically-typed language, which is why we have different terms for the two cases.

I'm not a lawyer so I'm not interested in formalities, I just look what you can do and call it accordingly.

If you use definitions that don't match what others use, it causes confusion. (As evidence, see this subthread ;) I agree with you that Java has many dynamic characteristics, including some which apply to its type system, but simply calling it the language as a whole "dynamically typed" misses an entire set of important distinctions.

Also Javas concept isn't very common: Most languages are either real statically typed (like most functional languages with an ML based type system) and dont allow something like a cast or they are weak typed (like for example the C based languages where you can change the type of an object at runtime). Java is strong typed (no type changes at runtime) and allows both static and dynamic typing. In the moment I don't know of another well known language like this (ok, Lisp can do it too, but Lisp can do everything with its metaprogramming abilities).

The C++ type system is quite similar to Java's in this respect. (I think Java's type system was based on that of C++.) It supports subtyping and casting, and downcasting can result in runtime type errors.

Even languages like Haskell and OCaml have features along similar lines: Haskell's typeclasses are very similar to Java's interfaces, and can be used to provide the same kind of polymorphism that interfaces can — see e.g. Haskell's overlooked object system for this taken to a Java-like extreme; and OCaml's structural subtyping allows methods to be invoked on objects based on the name of the method, rather than the type of the object, which is arguable more dynamic than what Java allows.

'Static typing' means that ty

'Static typing' means that types are 'static' - with other words don't change while the program is running and can be calculated by the compiler. If you use Javas dynamic typing capabilities (which results from the runtime checked downcasts) thats not the case anymore.

And no, C++ is also not static typed in the strong sense. C++ isn't even strongly typed. A programmer can write programs in C++ which are statically typed, but its on him, the language don't enforce it. C/C++ can behave like assembler considering typing if the programmer chooses so. Would you call assembler 'statical typed'? Thats this black/white thing I talked about: The simple distinction between static and dynamic typing don't works with most modern languages anymore because they allow both and it depends on the features the programmer uses.

If you declare a variable as 'Object' thats only syntax. You could also invent a special syntax and write every declaration like 'Objectx' to 'var x'. The result is similar and would looks like in only-dynamically typed languages but it would have the same semantics. Would you call a language with the first syntax 'dynamic typed' while the with 'Object' the language is 'static typed'?

About the casts: In Java a method is always bound to an interface. Without the interface you won't know what method to call. So you have to declare to which interface a method belongs. If the syntax is '((interface)obj).method()' or something like obj.interface:method is again only syntax. Just look at interfaces as namespaces for methods. Would you consider a language with a 'var' keyword and the latter calling scheme 'dynamic'?

Yes, there are different terms 'static/dynamic typing'. I don't want to get rid of this distinction, I simply think that its obvious that Java uses both kinds of typing and the programmer can choose which to use. So why not call it what it is and stop those 'Ruby is dynamic and Java is not' simplifications. If Ruby is better than Java then not because of dynamic typing (because you can use this in Java too, independent on how you call it) but because of other things. But as long as people only concentrate on this false 'Java is static typed and Ruby dynamic typed' explanation, there will be no chance to find out what the real advantages of Ruby are.

And I haven't called Java 'dynamically typed' only, I explained that it is both, depending on how the programmer uses it.

But C++ isn't that similar as you told. Sure, Javas typesystem is based on C++, but the important difference is that every class in Java inherits from 'Object'. In C++ there is no common superclass and because of this you can't do the same things as in Java. If you declare a C++-class without a virtual method the objects of the class don't even have a vtable - and no runtime type-info. So you can't use dynamic_cast on those objects. Of course you can use C++ in a way which makes it similar to Java. But that would only work if all your code is designed that way. And if you want name based dispatch (which Java can easily do with a small helper function and a different call syntax) you also need macro based annotations for each method.

About Haskell: I have to read the article before I could comment on that. About ocaml: It uses something you can call 'static duck typing': In ocamls types are defined as the set of the available methods, not as a set of interfaces. But thats determined only static and since ocaml has no downcast you can't do things like Javas dynamically typed Collections or other dynamic typed things.

Java is hybrid

I am mostly with Karsten on this one. Java is a hybrid, it is both, statically and "dynamically" typed.

As a result, it is comparably weak on both fronts: static typing enthusiasts are not happy with its type system (which is not very expressive and has a number of severe holes), and dynamic proponents are not satisfied with its dynamic features (which are not very expressive and require a lot of extra notation to be used).

Static typing, again

Maybe you're not aware of the distinction between strong and weak static typing: in strong static typed languages, the type system is so strict that every type check can be done at compile time. In a weak static typed language you usually have some kinds of type conversions that can fail at runtime, but method calls, assigments etc. are still checked at compile time. Consider your example "((Collection)x).add(y);". This line is doing two things: First, it casts the variable 'x' to the type "Collection" (this may fail at runtime). Secondly, it calls the method "add" of this type. This call 100% type checked at compile time, and cannot fail (unless of course 'add' would contain another type cast, that could of course fail).

About the casts: In Java a method is always bound to an interface. Without the interface you won't know what method to call. So you have to declare to which interface a method belongs. If the syntax is '((interface)obj).method()' or something like obj.interface:method is again only syntax. Just look at interfaces as namespaces for methods. Would you consider a language with a 'var' keyword and the latter calling scheme 'dynamic'?

There's a subtle difference here, that maybe you didn't realize yet: If I create two classes (say, A and B) in java, both having a method called "foo", I can't simply pass around objects of type A to a method that expects an object of type B and wants to call B's foo method. If I wanted that, I would have to explicitly state the "relationship" between A and B to the compiler (e.g. using an interface or abstract base class), and I have to explicitly state that I want to use the subset of methods in this interface (or of course a type that derives from that, like A and B), so the type checker can understand all the calls at compile time. This leads to code dependencies (both classes need the interface) that are not neccessary in a dynamically typed language. If the two classes come from different sources (think 3rd party code), it's quite unlikely they can get coupled in this way, so this is not just a simple syntax-issue.

Reflection is a different issue: If it was built into the language syntax (say, you could write Object x=...; x."MethodName"(1,2,3) without casts), then I'd agree with you that Java (as a programming language) would admit dynamic typing (at least to a certain degree, Ruby's type system is still a lot more flexible than that). But Java doesn't have such a syntax, so the language is still statically typed. Maybe that's a root of the confusion here: I think the term "dynamically/statically typed language" can only be applied to languages (think BNF), not to class libraries that might accompany them. In the case of Java, there's no sign of dynamic typing (or duck typing) in the language, although you can of course acchieve similar effects through libraries like the reflection API.

Concering 'strong/weak-typing

Concering 'strong/weak-typing': I agree with the wikipedia author who wrote 'However, these terms have been given such a wide variety of meanings over the short history of computing that it is often difficult to know what an individual writer means by using them.'. For me strong typing means that every object has a definite type which only depends on the object. A cast in a strong typed language only make the dynamic type known to the compiler, a cast in a weakly typed language makes other operations on a type possible.

In Ruby a method call can fail if there is no apropriate method. This test happends if someone calls the method. In Java this test happens a bit earlier at the time of cast. You may consider this as a big big difference - but since you can do the same things with both concepts I consider the difference of no real practial relevancy.

About the 'subtle' difference: It's a result of both 'foo'-methods are declared in different namespaces. You can create both statically typed languages with a Ruby-like concept (look at ocaml) or dynamic typed languages with a java-like concept.

Reflection is build in into Java (look at '.class' or instanceof). But I also consider the standard libraries part of the language. If you would take away those libs from a language like CommonLisp what would you get? Nothing. To put as much as possible into the libs and away from the language itself is considered good design by most language designers.

If all I need to have duck-typing in Java is to call methods with call(obj, "method", parms) instead of obj.method(parms) then I consider that as 'Java can do duck typing'. I know that there are differences between this approach and Rubys - but thats another topic.

Method invocations are checked in Java

In Ruby a method call can fail if there is no apropriate method. This test happends if someone calls the method. In Java this test happens a bit earlier at the time of cast.

Unfortunately(!), the latter is not true: method invocation does a dynamic check even in Java. And this check may fail (yielding a NoSuchMethodError). The prior cast only checks that the object has a class with the expected name (basically), it does not check whether that class has the same set of methods that was anticipated during compilation.

That is, Java is even more dynamic than you said - in fact, its type system generally says nothing at all about the properties of the objects at runtime. It just assigns class names, but the actual definitions of these classes might or might not coincide with anything you see at runtime.

Normally only a method-call v

Normally only a method-call via reflection can yield a NoSuchMethodError. But it can happen if the class was changed without knowledge of the compiler (wrong partial compilation, messing with bytecode etc). So the runtime has to check it again to avoid potential security breaches. But as long as a programm was correctly compiled with javac, its guaranteed that a NoSuchMethodError can't occur with a normal method call. I don't know how to avoid something like this in a system where it is possible to dynamically load code without compromising security.

But it shows once more that Java isn't as 'static' as many people think. While the syntax of Java was clearly ripped off from C++ (IMO to a to big degree) the semantics are much more influenced by Smalltalk.

"Normal"?

Depends on how you define "normal". Dynamic loading/linking is a central part of Java, but is implemented in a way that easily breaks the static type system. Same with distribution/RMI. I wouldn't consider change of a class abnormal circumstances in the Java model - it's what it is meant to support.

In principle, it is easy to avoid the problem: just check class signatures - structurally! - against the static expectations when you load them. Then only loading a class can fail (as always), but not invoking an individual method. But I guess that was deemed too expensive (I don't think it is).

(Also note that with generics, similar things can now happen in allegedly "normal" method calls.)

Generics can only create Clas

Generics can only create ClassCastExceptions, NoMethodFound won't happen with normal method calls and a well formed Java program.

If you check class signatures before execution I suspect that people would bitch about how difficult it is to implement dynamic languages in the Java VM. But with a more dynamic VM it's relativly easy to implement languages like Groovy or Jython on top of the VM.

But I think the topic really starts to get a little bit 'off' here.

...To put as much as possible

...To put as much as possible into the libs and away from the language itself is considered good design by most language designers.

That's a point I always "like" in discussions with javaists: First they start with the position "Java can do all this too", and when they accept things are not that easy, they settle to: "It's better the way Java does it anyway"... Well I guess we would all be programming Common Lisp if this would be considered "good design" by all language developers, wouldn't we?

About the 'subtle' difference: It's a result of both 'foo'-methods are declared in different namespaces. You can create both statically typed languages with a Ruby-like concept (look at ocaml) or dynamic typed languages with a java-like concept.

You really don't see the difference, do you? In Java, if javac parses a call, it emits a bytecode sequence for it. This sequence contains the information where the called method was declared (this may of course be an interface, if it was declared in an interface). To do this, it of course has to resolve this at compile time (aka static). Of course it can't always resolve which method will be called at runtime (after all, it's only a type checker, so it only checks types, and it can ensure that the type of the method called at runtime will be correct), but this is well-known in other static typed languages (e.g. C's function pointers).

Please

That's a point I always "like" in discussions with javaists: First they start with the position "Java can do all this too", and when they accept things are not that easy, they settle to: "It's better the way Java does it anyway"...

Come on, you're totally quoting him out of context, and what you read into the quote is not what he actually said.

and it can ensure that the type of the method called at runtime will be correct
No, it can't. See my other post. Unfortunately, Java is too dynamic for that, and certainly totally different from C.

So you think that a good lang

So you think that a good language should put as much as possible into the language definition and not in the libs? So I guess you're not a 'rubyist'.

Look, I'm not very interested in the theoretical properties of a programming language. I'm interested what I can do with the language and how difficult it is. If I can do something with a simple library call or if its build into the language doesn't matter as long its easy to use and flexible enough. Both ways have their advantages, but in the end it only matters what you have to do to reach some goal. If I have to put a huge amount of code into my program to be able to use dynamic typing like in C++ then I see huge a difference to a language were I only need a slightly modified method call to reach this goal.

But Java isn't even static typed from a formal point of view because you can get runtime type errors in error-free java-programs (I don't like that 'feature' myself, but its simply a fact).

In Java, if javac parses a call, it emits a bytecode sequence for it.

That's implementation and only interesting for the people who create the compiler or the vm. From the usage point of view it doesn't matter how something is implemented.

And you seem to mistake Java for C++. Javac don't resolves methods, it only checks the typing rules to ensure that the vm don't creates MethodNotFound Errors at runtime (some people like this particular feature). The method resolution is done by the vm at runtime. It's not even specified, how it exactly works (hashing, binary search, lookup tables etc.) - and it don't matters as long as it performes well.

So you think that a good lang

So you think that a good language should put as much as possible into the language definition and not in the libs? So I guess you're not a 'rubyist'.

As a matter of fact, I'm not. In my oppinion e.g. regular expressions are well placed in a library, I never liked perl's/ruby's "=~"-operators, not even mentioning those built-in "$1 / $' / $´"-variables. There are other points I don't like about ruby, but I think that's really not part of this discussion.

Look, I'm not very interested in the theoretical properties of a programming language. I'm interested what I can do with the language and how difficult it is. ...

Hmmm, a few messages earlier you were quite eager to distinguish between what python can do qua being dynamically-typed, and what it can only do because of it's python-type-system. This distinction seems fairly theoretical to me, too. I'd suggest if we apply this "pragmatic" view to java, we should also compare it "pragmatically" with ruby or python (not with the theoretical concept of "dynamic typing"). Everything else seems kind of "unfair" to me. Don't you think?

That's implementation and only interesting for the people who create the compiler or the vm. From the usage point of view it doesn't matter how something is implemented.

The point is that only a statically typed language can emit this kind of data. And of course this matters for the "usage point of view", as you'll get a compile time error if the compiler can't resolve all the details it needs to emit to bytecode.

Javac don't resolves methods, it only checks the typing rules to ensure that the vm don't creates MethodNotFound Errors at runtime (some people like this particular feature). The method resolution is done by the vm at runtime.

I think I explicitly wrote that the compiler resolves "where the method to be called was declared, not which method will be called". It clearly does that, and more often than not, you'll have to give it explicit clues about where to find the declaration.

Static types are syntactic.

If you declare a variable as 'Object' thats only syntax. You could also invent a special syntax and write every declaration like 'Objectx' to 'var x'. The result is similar and would looks like in only-dynamically typed languages but it would have the same semantics. Would you call a language with the first syntax 'dynamic typed' while the with 'Object' the language is 'static typed'?

I think this is the crux of the misunderstanding. According to commonly used terminology, I certainly would call one of those languages "dynamically typed" and the other "statically typed". When you say "that's only syntax", you miss the entire point. Static typing is all about syntax. It is about statically assigning types to syntactic terms. In Java, those static types are upper bounds on the dynamic type of the value, because of subtyping (which is why downcasts make sense). But they are still static, and they still have a purely syntactic interpretation (which is why downcasts are necessary).

(This is my only comment in this thread, I swear.)

Types are not 'syntax', they

Types are not 'syntax', they are part of the semantic of a language.

Syntactic types and splitting definitions

Matt described the standard definition of static typing, i.e. "statically assigning types to syntactic terms". The sense in which it is "syntactic" is that a static type is associated with a specific term in a program, i.e. with a piece of syntax. The static type tells you what kinds of values can flow through that term at runtime.

You wrote "If you declare a variable as 'Object' thats only syntax", but if 'Object' is one of a set of static types that your language allows you to assign to terms, and if all terms in a program must be classified with one of those static types, then you have the classic definition of static typing. So what you're characterizing as "only syntax" is an important part of what static typing is.

If your language has only one static type (known as uni-typed), then it's traditionally called a dynamically-typed language. Languages like Python, Ruby and standard Scheme all fall into this category: statically speaking, all terms have the same "universal" type which contains all other types, and there is no way to statically (i.e. syntactically) declare a more specific type for a term.

The argument in this discussion that Java is in some sense not fully statically typed may be based on accurate facts, but is not relevant. Java programs have a static type for every term, and a rich set of static types, and in that most basic and straightforward sense, it's a statically-typed language.

The only real question is whether a statically-typed language that also happens to have a universal type like 'Object' can also be called a "dynamically-typed language". The arguments for this are that it has a universal type; that values have type tags so support various dynamic operations; and that it has a mechanism for invoking methods on objects whose type is not statically known. These are all necessary features of dynamically-typed languages, and the question is whether they're sufficient. Ultimately, it's just a question of definition, and unfortunately "dynamically-typed language" has never been all that well defined, partly because there weren't previously many languages which blurred the distinction, so a precise definition wasn't as important.

One test I would propose is this: would you choose to write an entire non-trivial program in Java, using only dynamic typing, i.e. with no type declarations other than Object? If not, what does that say about Java as a dynamically-typed language?

After all, one of the strengths of dynamically-typed languages has traditionally been rapid prototyping. If "dynamic typing" in Java doesn't serve the same purpose (and I don't think it does), then we start needing more specific terms to characterize the ways in which the behavior of the traditional dynamically-typed languages differ from "hybrid" languages. In this case, the definitional argument occurs because the definition is being stretched to serve too many purposes.

Stretching forth and back

Don't forget that the term "dynamic typing" already is quite a stretch in itself. Now it's getting stretched back into the opposite direction... :)

Java out-duck-types Ruby?

Create a java swing app, which outputs the result of 5+"hi" when you hit a button. Create a ruby tk app, which outputs the result of 5+"hi" when you hit a button. In java, you'll get a compile-time error, as the types are checked at compile time. In ruby, you'll get a runtime error, because the types are checked at runtime. That's the difference.

Actually, the result of the Java program would not be an error, it would output the string "5hi". Not sure what that says about the duck-typing-ness of Java vs. Ruby. ;)

Java is *both* statically and dynamically typed.

So we agree that
- java is a statically typed language

Actually, this is the point where everybody's going wrong in this discussion, IMO. I think the right thing to say here is that Java is both statically and dynamically typed. Java calls for a compiler that statically analyzes all expressions in a program to ensure they are well typed ("static typing"), and it also calls for a runtime system where all objects carry a tag that indicates their type, which will be checked in many circumstances to catch runtime type errors ("dynamic typing"). The differences between Java and Ruby, then, are:

  1. Ruby isn't statically typed;
  2. Ruby has far more support for late binding.
That is, in Java, far more behavior is fixed at compile time than in Ruby; the methods and fields that are bound within the context of a class, for example, are closed at compile time in Java, while in Ruby, they can be changed at runtime. In the late binding front, however, Java is far ahead from other popular statically-typed languages like ML and Haskell, since it's relatively easy to load arbitrary classes not known at compile time, instantiate them and send messages to them through reflection.

Dynamic behavior in Java

I don't want to be too harsh but you're just wrong according to the accepted definitions of static and dynamic.

It's not as simple as that. Although Java is a statically-typed language, it supports a great deal of dynamic behavior. Take a look at the examples in this article, which has some nice short code examples that demonstrate dynamically adding methods to classes, copying methods from other classes, adding code to the bodies of methods, etc. Features like this are routinely used by Java systems to implement all sorts of dynamic behavior, like dynamically reloading web servlets that have been updated, dealing with persistence of classes that aren't statically known to the persistence engine, and dynamically generating user interfaces for arbitrary classes.

The static/dynamic distinction as it applies to languages, as opposed to just typechecking, is much more of a spectrum than a binary choice. Java is not as far towards the dynamic end of the spectrum as Python is, but it's much closer to it than C or C++ are, for example.

The Python example above could be implemented in Java, with two main caveats: first, you can't add a method to an existing class and existing instances, but you can clone a class, add methods to it, and use the resulting class; second, static typechecking means that you need to use a dynamic invocation API to invoke methods that weren't statically declared.

Dynamic behavior in Java

These are some interesting points, but they get into the blurry distinction between Java [the language] and Java [the runtime environment]. The code in the referenced article works by emitting bytecode at runtime. To me, we're now using Java [the runtime enviroment] to achive dynamic results, and not Java [the language]. This of course is subject to debate.

Similarly, someone could argue that because JScheme and jython are written in Java[the language], it is dynamic. I would disagree.

My simple, non-pedantic definition of a dynamic language would be a language that has the equivelent of an eval() statement. Java [the language], in conjunction with the reflection and bytcode APIs, allows you to perform some neat tricks, but it's not nearly as trivial as using an eval statement.

Dynamic behavior in Java

These are some interesting points, but they get into the blurry distinction between Java [the language] and Java [the runtime environment]. The code in the referenced article works by emitting bytecode at runtime. To me, we're now using Java [the runtime enviroment] to achive dynamic results, and not Java [the language]. This of course is subject to debate.

Dynamic languages that use bytecode achieve some of their dynamic features by "emitting bytecode at runtime". So how would you justify discriminating against Java when it comes to doing the same thing?

A fairly typical dynamic language architecture is to take a piece of source code, compile it to bytecode, and load and execute that bytecode. This is typically all hidden from the user of the language. Java makes parts of this process more explicit, but the same basic process is used in both cases.

Similarly, someone could argue that because JScheme and jython are written in Java[the language], it is dynamic. I would disagree.

That's not a similar argument at all. Features like dynamic class loading and especially reflection are part of the Java language — they require runtime support, but they're designed into the language. They don't involve implementing a different language.

My simple, non-pedantic definition of a dynamic language would be a language that has the equivelent of an eval() statement.

I prefer Guy Steele's definition, given at the Dynamic Languages Wizards Series: "A dynamic language is one that defers as many decisions as possible to runtime". I would qualify that and say that you can assess how dynamic a language is, i.e. where it fits on the static/dynamic spectrum I mentioned, by looking at how many, and which, decisions it defers to runtime. If you look at Java from this perspective, it's got quite a few dynamic features.

Java [the language], in conjunction with the reflection and bytcode APIs, allows you to perform some neat tricks, but it's not nearly as trivial as using an eval statement.

The article I linked to shows source code, represented as strings, being added to the running system. It would not be difficult to encapsulate that in an eval method, making it just as trivial to use as a built-in eval.

A dynamic object doesn't require a dynamic typing.

I didn't meant to start a troll about Java here. Instead, I wanted to say that the many hacks that "dynamic" geeks like are wrongly believed as incompatible with static checks.

I'm not an expert in object typing, but I feel that extending an object with new methods, or changing the implementation of a method (still preserving the type of the method itself) is compatible with static typing. At least if you type object by the set of their methods. Let me try.

class foo = object
method m x = print x
end
class virtual extension = object
method newm x = print "new " ; print x
end
let o = new foo
# o has type string >
let othero = o.extend(extension)
# This kind of thing doesn't exist in any static language I know, but I think it's definable as long as the extension is virtual.
# othero would have type string >
# Everything statically typed

Of course the variable "o" has still the old type, but the point is that "newo" is still the same object, if you change it's instance variables it's o's instance variables.

Well.. maybe I'm wrong and that kind of thing is impossible. But I don't see it yet, at least. Does anyone knows of safe static type systems allowing these kind of nice things ?

Dynamic typing in statically typed OO languages

I'm not sure if I got you right: You want to "change the type" of an object by exchanging the virtual method pointers, is that correct? I don't see why this shouldn't work, and I think in C++, if you know your compiler's OO memory layout, you could probably do it (depending on the implementation you might be forced to create a new virtual method table for that object, but that's certainly possible). However, the extension would be quite limited: it simply doesn't know about the extended class's members at compile time, so you'd have to use reflection to get to reach it's members. You could derive it from the class that is to be extended, but then you'll only be able to extend objects of that type and it's siblings. Either way, it's not as powerful as ruby or python's dynamic OO systems. And of course (I think this is what you meant by "virtual extensions") the extensions can't carry any new member variables, or change the type of existing ones. Adding new virtual methods is probably quite tricky, as you'll have to add them to the end of the object's VMPT, which might have different length depending on it's type, so I'm not sure how the compiler is supposed to know where these new methods will be at compile time.

I didn't meant to start a troll about Java here. Instead, I wanted to say that the many hacks that "dynamic" geeks like are wrongly believed as incompatible with static checks.
Well, assuming I got you right, they certainly are incompatible with static type checking: You'll have to rely on reflection plus lots of (more or less unsafe) casts to acchieve this, so in the end there will be little type checking left...

I've worked with both Zope and Rails...

...and I'd say that there's two advantages to the Ruby/Rails combination:

  • Richer metaprogramming in Ruby, almost to the point of having macros.
  • A file-system based store.

Ruby is a pretty acceptable LISP replacement for a lot of work. There are a lot of small domain languages, and functional code tends to look reasonable. Python's culture, on the other hand, is adamantly opposed to any further LISPishness.

Rail's decision to store files on disk--instead of keeping them in an object database--makes it easier to manage sites and do distributed development.

Postmodern languages

The main reason why Zope didn't help pushing Pythons popularity very much is quite simple and has nothing to do with the kind of whishfull thinking of self-important Lisp weenies: Zopes design philosophy is creating Web apps "out of the Web" using markup languages and templating engines, not simplifying Web programming using Python as a language. Zope was important for the Python community as a proof that large applications can be coded in a scripting language. Zope did for Python what e.g. pugs or darcs do now for Haskell: demonstrating that real world applications are feasible in a particular language. It does not mean that thousand of programmers now using Haskell to create pugs extensions for a living and are hot on learning CS for mastering their job ;)

You are of course right that Pythons culture did not intent to change the face of the language in arbitrary manner and fears to speak in line noise. It could hardly be considered as a "postmodern language" - a term coined by Larry Wall to characterise Perl. Strange enough the term fits even better to Ruby. Perl might be pluralistic in every way and absorbing different styles of programming but it is exactly this attitude that creates a very distinctive shape and the languages charme. Perls non-identity is propagated with the full pathos of identity. Ruby on the other hand is a bit of Perl, a bit of Smalltalk, a bit of Python and a bit of Lisp - it is really a crossover. This japanese politeness towards the identity of the others is both an expression of non-self and an act of aggression.

Ruby sometimes remembers me that the ultimate goal of programmers might not be creating good architecture or some "quality without a name" but strange chimaera.

Junkspace!

Modernization had a rational program: to share the blessings of science, universally. Junkspace is its apotheosis, or meltdown...

This is one of the first times I actually really want to go /. and "mod the parent up". Koolhaas musings are very relevant to PL design, well, they seem that to me ;0) :

It was a mistake to invent modern architecture for the 20th century; architecture disappeared in the 20th century; we have been reading a footnote under a microscope hoping it would turn into a novel; our concern for the masses has blinded us to People's Architecture. Junkspace seems an aberration, but it is essence, the main thing... product of the encounter between escalator and air conditioning, conceived in an incubator of sheetrock

Hmm, footnote=type theory?, hmmm, and then Java? ;-)

It goes on, and ends with...

Mankind is always going on about architecture. What if space started looking at mankind? Will Junkspace invade the body? [...snip...] Is it a repertoire of reconfiguration that facilitates the intromission of a new species into its self-made Junkbiosphere?

God is dead, the author is dead, history is dead, only the architect is left standing... an insulting evolutionary joke...

The cosmetic is the new cosmic.

He might as well have been discussing our progression from Fortran/Lisp towards the latest Microsoft Visual Studio. ;-)

What?

schluehk: "This japanese politeness towards the identity of the others is both an expression of non-self and an act of aggression."

Huh? Matz is just a funny, decent guy with a SmallTalk background. I think it's totally inappropriate to start making stereotypical generalizations about the Japanese people.

Well...

For what it's worth, I don't think Kay's comments are intended as a personal attack or an ethnic stereotype. I think they're intended as a (tongue in cheek? I can't tell...) sort of critical and cultural theoretical analysis of programming languages.

Right or wrong, the line you quote could come from any of numerous books of cultural criticism or anthropology. In fact, a quick google search turns this, which appears to be a linguistic response to exactly that line of thought. Also see one of a few books on the relationship between militaristic nationalism and religion in Japan (Rude Awakenings and Zen at War come to mind).

Now, whether or not this sort of general cultural criticism and analysis is any different from jingoistic stereotyping is, I suppose, an open question. Should it matter whether the critic is himself a member of the subject group? I'm not sure about that either...

As a US citizen, I certainly feel like I ought to acknowledge the idea that certain cultural trends may lead (unavoidably?) to unhappy outcomes. If, buried in my language and culture are tendencies which lead to suffering, imperialism, aggression, and so on, I feel like I should be open to that possibility. On the other hand, maybe I wouldn't be so quick to try to find the flaws in cultures other than my own. You know, the beam in my eye and the speck in yours, and so on.

The bottom line is that I'm sure Kay was not personally attacking Matz. And now I'm severely off-topic, but I do think these are important questions. Feel free to email me if you'd like.

Appropriate stereotypes

There had been an interview with Matz about the origins of Ruby where he commemorated Rubys anchestors, praised Larry Wall as his "personal hero", demonstrated respect for the "Lisp culture" etc. I liked his gestures very much. Instead of going the way of criticism and negation and positioning himself as an original genius he bowed before other language designers and cultures right in the same moment where he acquired their symbolic capital and leave them behind. Well, yes, it is a cultural stereotype, or a form, though a beautiful inoffensive and decent one as you say. I would never come to the idea that it is worth to liberate from this style in order to pronounce personal identity and separate the individual from his background. This is quite another stereotype which is modern romantic idealism and protestant.

Kay

Thank you for clarifying

Now that I understand your remarks better, I happily retract my earlier challenge. Thank you for responding so kindly.

While we're on the subject, I've also been impressed by Yukihiro Matsumoto. He's diplomatic enough to lecture LISP hackers on the drawbacks of macros, yet still get them to laugh at his jokes. :-)

And please don't take my criticisms of Python as an outright rejection of Guido's work. I've coded in Python for years, and contributed code to Zope. Python spans a range of styles from object-oriented to functional programming, and a range of skill levels from novice to expert. Guido did excellent work, with careful attention to the cognitive limitations of programmers.

That said, I am a LISP geek by training and culture, and I have never been entirely happy in the Python community. As you yourself admit, Python culture is rather suspicious of the things LISP programmers like to do. I'm quite happy to finally have a more appropriate outlet, actually.

Beyond the border

I try to temper my impatience at this point of discussion because I know of course about the limitations ( and benefits! ) of Pythons restrictions but I also know how to overcome them and I have a simple working model right here on my computer. Pushing Python beyond it's border was technically easier than I first thought and it could be done in a very clean fashion but how to re-inscribe unlimited freedom into something that is carefully bounded? Instead of creating a language superorganism chances are that we end up in a big ball of mud.

On the other hand what is once done cannot be undone and the Python philosophy of preventing the biggest mess is making things easy, transparent and accessible.

Kay

Maybe this is mentioned already.

I have read here about the 5 great advances of computer science in programming languages. Sadly, there is no mention of functional programming languages! I would expect point #6 to be functional programming languages, but it is not...

You know functional

You know functional languages are a type of declerative language, so its actually there on the list.