why doesn't ruby have generics?

A

Arlen Cuss

[Note: parts of this message were removed to make it a legal post.]

Hi,

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
 
F

Florian Gilcher

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


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 Gilcher
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

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

Marc Heiler

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

Robert Klemme

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
 
F

Florian Gilcher

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


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 Gilcher
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

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

Robert Klemme

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




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
 
P

Pascal Bourguignon

thufir said:
Is it because Ruby is dynamic, or something else?

Mu.

All the methods of Ruby are generic.


--
__Pascal Bourguignon__ 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.
 
J

Joseph Lenton

thufir said:
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.
 
T

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.

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
 
F

Florian Gilcher

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


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

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 Gilcher

[1]: http://en.wikipedia.org/wiki/Generics_in_Java#Type_erasure
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

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

Robert Klemme

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
http://www.cs.binghamton.edu/~mike/presentations/java-generics-cs580c-fall-2007.pdf
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
 
T

thufir

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
 
P

Phillip Gawlowski

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

Robert Dober

It wouldn't be useful to have some sort test to make sure there's not a
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
 
A

Adrian Mowat

[Note: parts of this message were removed to make it a legal post.]

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
 
K

Ken Bloom

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top