Why doesn't ruby have generics?

Is it because Ruby is dynamic, or something else?

-Thufir

Hi,

On Sat, Apr 19, 2008 at 7:58 PM, thufir [email protected] wrote:

Is it because Ruby is dynamic, or something else?

Well… there’s no explicit typing anywhere, so the concept of a
`generic’
makes no sense. Everything is generic, as far as duck-typing works.

Think of an example of a generic in C#, C++,
any-other-language-that-has-them-I-don’t-know – the code works
generically
in Ruby, too! Look up `duck typing’ to get an idea about it.

Cheers,
Arlen

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Apr 19, 2008, at 11:58 AM, thufir wrote:

Is it because Ruby is dynamic, or something else?

-Thufir

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.

Regards,
Florian G.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

iEYEARECAAYFAkgJxCEACgkQJA/zY0IIRZYhXQCcDqUzhMN7cWJoYivpAXjx8s22
ZnwAn2VxHriGauNMTNod/uNtZNh76a9+
=JY6m
-----END PGP SIGNATURE-----

Is it because Ruby is dynamic, or something else?

Maybe it first needs to be described which specific advantage a
‘generic’ type has (or would have).

On 19.04.2008 12:06, Florian G. 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.

Cheers

robert

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Apr 19, 2008, at 1:45 PM, Robert K. wrote:

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.

Cheers

robert

Yeah, thats why I was talking about “such functionality”. It would
serve the same purpose. I was not clear enough about that.

Greetings,

Florian G.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

iEYEARECAAYFAkgJ38sACgkQJA/zY0IIRZYWqACfaOXjJxZ1XqBjiTRLdQgQKjYp
ObQAoMiQmOh2xnbJPvi9bRPcxpaM3MJo
=CQU6
-----END PGP SIGNATURE-----

thufir [email protected] writes:

Is it because Ruby is dynamic, or something else?

Mu.

All the methods of Ruby are generic.


Pascal B. http://www.informatimago.com/

THIS IS A 100% MATTER PRODUCT: In the unlikely event that this
merchandise should contact antimatter in any form, a catastrophic
explosion will result.

On 19.04.2008 14:04, Florian G. wrote:

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 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

thufir wrote:

Is it because Ruby is dynamic, or something else?

-Thufir

As far as I’ve understood it, in Ruby it’s not about what the type is
but what the type can do. i.e. does it respond to a specific method. So
maybe generics in Ruby would make sense if you could restrict objects
based on what they can do. For example an array which can only hold
obejct that respond to the to_str method.

On Sun, 20 Apr 2008 07:49:02 +0900, Joseph L. wrote:

As far as I’ve understood it, in Ruby it’s not about what the type is
but what the type can do. i.e. does it respond to a specific method. So
maybe generics in Ruby would make sense if you could restrict objects
based on what they can do. For example an array which can only hold
obejct that respond to the to_str method.

Right; I’m taking a Java course which will be covering Generics and, in
Java, this a big part of the point of Generics:

an array which can only hold objects which implement a specified
interface.

-Thufir

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Apr 20, 2008, at 7:15 AM, thufir wrote:

in
Java, this a big part of the point of Generics:

an array which can only hold objects which implement a specified
interface.

-Thufir

Arrays are not the interesting thing when it comes to Generics. (As
Arrays in Java
already force every Element to be of the same type)

The interesting thing about Generics in Java (and the point where they
cannot make
sense in ruby) is that they are only checked on compile time. So, at
runtime, all
generic collections behave as a collection of Object.

The difference between Generics and Templates in C++ is that C++
generates one
Class for each used Template+Type while Java only generates one (that
actually
doesn’t care about the type anymore). This technique is called “Type
erasure”, because
the type information gets erased after it was compiled.1

All this doesn’t make any sense in Ruby, as there is no real ‘compile
time’.

Regards
Florian G.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

iEYEARECAAYFAkgLIGwACgkQJA/zY0IIRZafYwCfUgILOhKowyEzxYZ/ToTBT/1c
RLsAn2b295Qx2dDSDXcr8ZipjxeLjOQ6
=dK1x
-----END PGP SIGNATURE-----

On 20.04.2008 12:52, Florian G. wrote:

Right; I’m taking a Java course which will be covering Generics and,
in
Java, this a big part of the point of Generics:

an array which can only hold objects which implement a specified
interface.

Arrays are not the interesting thing when it comes to Generics. (As
Arrays in Java
already force every Element to be of the same type)

He probably meant ArrayList instead of array…

The interesting thing about Generics in Java (and the point where they
cannot make
sense in ruby) is that they are only checked on compile time. So, at
runtime, all
generic collections behave as a collection of Object.

The difference between Generics and Templates in C++ is that C++
generates one
Class for each used Template+Type

Templates are not restricted to classes. You can also have templated
methods. There are other differences for example partial
specialization. There are some nice articles around about the
differences, for example
http://www.mindview.net/WebLog/log-0061

while Java only generates one (that
actually
doesn’t care about the type anymore).

Actually Java generics do not generate types at all. The only thing
that they generate - if you will - are automated casts.

This technique is called “Type
erasure”, because
the type information gets erased after it was compiled.[1]

Exactly.

All this doesn’t make any sense in Ruby, as there is no real ‘compile
time’.

Absolutely.

Kind regards

robert

On Sun, 20 Apr 2008 20:45:04 +0900, Robert K. wrote:

Arrays are not the interesting thing when it comes to Generics. (As
Arrays in Java
already force every Element to be of the same type)

He probably meant ArrayList instead of array…

Yes, I did.

-Thufir

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

thufir wrote:

|
| It wouldn’t be useful to have some sort test to make sure there’s not a
| type problem ahead of time?

thing = Hash.new

thing.is_a? Array
=> false


Phillip G.
Twitter: twitter.com/cynicalryan

You yourself
Are much condemn’d to have an itching palm.
~ – William Shakespeare (1564-1616), Julius Caesar
~ – Act iv, Sc. 3
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgMXagACgkQbtAgaoJTgL+LhgCggt3iBgFcETwYPXFowUfqvvF9
Ho4AnjlTEF52ANtjlzfWa+PNUjaD4pVJ
=cBFT
-----END PGP SIGNATURE-----

On Sun, 20 Apr 2008 19:52:35 +0900, Florian G. wrote:

The interesting thing about Generics in Java (and the point where they
cannot make
sense in ruby) is that they are only checked on compile time. So, at
runtime, all
generic collections behave as a collection of Object.

It wouldn’t be useful to have some sort test to make sure there’s not a
type problem ahead of time?

-Thufir

Hi,

In a static typed languge like java, the compiler is trying to prevent
you
from making type-conversion errors although it is not always sucessful
(otherwise java would not need the ClassCastExcpetion).

You should be writing tests before your code no matter what languge you
are
using but in dynamic lanaguges like Ruby the tests are your safety net.
Are
you working with a test framework like rspec and/or Test::Unit?

Cheers

Adrian

On Mon, Apr 21, 2008 at 6:00 AM, thufir [email protected] wrote:

type problem ahead of time?

-Thufir

Well if you search the archives you will see that I made the same
suggestion some years ago. It took me some time to understand why this
is not a good idea (because I am not the youngest anymore and I had a
strong Pascal and Ada
background some Java and C experience did not help either;).

Ruby is a dynamic language and features duck typing, this changes the
whole approach to design, you just tend to forget about classes and
types, and you tend to think about behavior. Now I do not say that
sometimes defensive programming is not in order but if you want to
check if an object passed into your method has a certain behavior than
checking for it’s class simply is not the answer due to ruby’s dynamic
nature, this is the maximum I could imagine useful:

def check_some_behavior object, message, *methods
raise MyBehaviorError, message unless methods.all? { |m|
object.respond_to? m }
end

but even here I would be very, very careful, e.g.

check_some_behavior x, “must obey but does not ARRRGGG ;)”,
*MyLeanClass.instance_methods( false )

do you think this is maintainable? Imagine somebody adds a helper to
MyLeanClass or a more complex refactoring
is done, as e.g. factoring out of some of the behavior you want to
check to a mixin.

This is a dangerous straightjacket for Ruby.

Cheers
Robert


http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

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

Why would you bind to a type in a language that doesn’t really care

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 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. 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