On Sat, 19 Apr 2008 14:44:20 +0200, Robert Klemme wrote:

> On 19.04.2008 14:04, Florian Gilcher wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>> 
>> 
>> On Apr 19, 2008, at 1:45 PM, Robert Klemme wrote:
>> 
>>> On 19.04.2008 12:06, Florian Gilcher wrote:
>>>> On Apr 19, 2008, at 11:58 AM, thufir wrote:
>>>>> Is it because Ruby is dynamic, or something else?
>>>> Why would you bind to a type in a language that doesn't really care
>>>> about types? Otherwise, it is easy to implement such functionality -
>>>> just build a new kind of array that has to be constructed with a
>>>> class. Check for this class on insertion. I don't see the use,
>>>> though.
>>> That would be a type restricted Array but not a generic Array.  You
>>> cannot have generics in a language whose variables are typeless as
>>> Arlen pointed out.
>> 
>> Yeah, thats why I was talking about "such functionality". It would
>> serve the same purpose. I was not clear enough about that.
> 
> For practical purposes you are probably right.  But strictly speaking
> there is a difference: Java Generics basically are a mechanism for
> automated casting.  This is something else than restricting the type of
> items you put into a collection.  (You can sneak an Integer into a
> List<String> in Java.)
> 
> C++ templates are a completely different story - although they "look"
> pretty similar to Java's Generics.  C++ templates allow for generic
> programming which is something different altogether.
> 
> In Ruby you can do neither: you cannot cast because variables are
> typeless.  And you cannot have generic algorithms for the same reason.
> 
> Kind regards
> 
> 	robert

AFAICT, the functional difference between generics in Java and C++ are:
* In C++, you can use the generically inferred type names to construct 
new objects of those types. Multiple versions of the generic types/
algorithms are typically compiled, for dealing with objects that have the 
same interface but are not involved in an inheritance relationship. So 
the result is kinda like duck typing, but you cannot mix objects of 
different types in the same container.
* In Java, you can cast a List<SomeType> to a plain old List, and when 
you do so you lose all type checking. You can also cast a String[] to an 
Object[], in which case type checking is done at runtime. Java also 
allows (requires) constrained genericity e.g. List<SomeType extends 
SomeOtherType>. The result is less flexible than duck typing.
You also lose the C++ ability to construct new objects of the same type, 
tough you can work around this by using factories. (Class objects can be 
used in a pinch, but they're not always as flexible as you need for this 
task.)

How does ruby measure up? Ruby has duck typing.  When you look at Java 5 
Generics or C++ templates from the evolution of their languages, the 
clear idea is that you're getting more type flexibility than you had in C 
or Java<=1.4, and that these languages are trying to move in the 
direction of duck typing. In this sense, Ruby is much better (and C++ is 
better at it than Java, though C++ has the disadvantage of more compile-
time code-size blowup).

If you're looking from the perspective of what typing rules are still 
enforced, C++ has the best type enforcement, followed by Java, though I 
suspect that Java's issues there are for backward compatibility and if 
that wasn't a consideration, Java's type enforcement would be very much 
like C++'s. Ruby would be worst at type enforcement, because Ruby is 
designed with the opposite philosophy.

Ruby's duck typing can handle objects with similar interfaces which are 
not related through inheritance, because it always looks up method calls 
by name, and because there's no such thing as a "friend operator" as C++ 
has. Ruby can accomplish this aspect of C++'s template system without 
code blowup because it's method dispatch is very different than C++'s.

As for constructing objects of a given type in a generic algorithm, Ruby 
has the same limitation as Java. You need factories. Class objects can be 
used in a pinch, but ClassName.new may not always be enough to handle 
what you need.

Groovy is a language for the Java VM which has a balance between Ruby's 
duck typing, and Java's static type system and generics. It accomplishes 
this by checking everything at runtime. It may not be a bad type system. 
Most of my complaints about the language revolve around their decision to 
conflate the semantics of Ruby's Hash and OpenStruct on a single class 
fundemental class (java.util.Map) so that there's no way around the 
ambiguity.

--Ken

-- 
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/