Then don’t specify a type for your arguments. Some people need
it, some people don’t.
Who needs it? And why? Immediately, the classes of applications
I do. I almost didn’t choose Ruby because of the lack of type checking.
I am primarily a C++ programmer. My guess is you’re not hearing the
argument of scores of C++/Java programmers because they’re not here,
because Ruby has zero type-checking.
Likely not. Because if you’re looking at choosing a scripting
language based on its type-checking, you’re excluding the vast
majority of modern scripting languages including Perl, Python,
JavaScript, and Ruby.
I mean that in all seriousness.
I grant that you mean that in all seriousness. But in doing so,
you’re not wanting Ruby. And I mean that in all seriousness.
Interface publication and type checking are two different things.
People don’t fiddle around arguing with others, generally, they
just walk away. I have never said a word to anyone in the Python
group about what could make Python better because there’s too much
wrong with it to begin with. That’s my opinion of Ruby right now.
I love it, but I think there are things like lack of type checking
that are making people go “ah screw it” and just move on.
Again: consider the words of Bruce Eckels. The man knows what he’s
talking about and is amazed by the power of not statically type
checking. It’s saved him loads of work. You want to add the work
back into Ruby development. Optionally, I grant, but part of what
a language designer like Matz must consider, is what changes like
you’re talking about would mean to the “culture” of the language. If
people start using an “optional” method signature mechanism for type
name enforcement, then that changes the assumed and actual
dynamicity of Ruby. I suspect that the number of people thinking “ah
screw it” are few and far between and instead are feeling liberated
from having to specify types unnecessarily.
Consider generics in Java (templates in C++). These effectively
introduce the sort of dynamicity that is found in Perl, Python, and
Ruby. Instead of having to do:
int max(int x, int y) { return x >= y ? x : y }
float max(float x, float y) { return x >= y ? x : y }
double max(double x, double y) { return x >= y ? x : y }
You can do:
def max(x, y); x >= y ? x : y; end
I know which I would prefer, and C++'s move toward generics is a
halting step toward that step.
that need this are (1) RPC-based programs that are dynamically
discoverable, and therefore need cross-language inspection and
(2) interface builders (a la Visual Basic “Property Inspectors”).
I can’t think of any other class of application that needs this
sort of meta data. I fully support being able to have this
information available, say:
Then you’re not thinking hard enough about it. I can’t force the
notion that type checking is useful if you really don’t want to
listen.
It’s not that I don’t want to listen: it’s that type checking
doesn’t help in the real world. Ruby is used in a number of real
world large-scale projects.
Doing a respond_to? for every method you need an object to
implement is tedious,
Yes, it is. That’s why I don’t do it often. I document what the
object requires and then I expect the user to follow it. This is
the heart of duck-typing: you use the object given to you. Unless
you’re doing something that requires programmatic discovery (see
my notes above), documentation is sufficient.
No, documentation is not sufficient, especially since there is so
much code out there that is NOT documented. It would be much
easier to provide a typing mechanism that could at least report
which interfaces an object provides. Developers are more likely to
take advantage of that than they are to provide documentation.
shrug If you want to think that static type checking is really
going to help, that’s your call. But it won’t.
Oops. StringIO instances respond to #select, but they’re not IO
or File objects at all. Exactly how does name checking help you
here? StringIO is a valid IO object by signature, but it’s not
“of IO”.
Well, clearly the hierarchy is not designed to report properly
which interface StringIO implements, which is sort of my point. If
there were an abstract IO interface, StringIO could declare itself
an implementation of that interface, and methods that required
that interface would then have very informative error messages for
developers who passed it an non- conforming object.
Useless runtime processing.
It saves a lot of code and headaches when you can just ask “does
this object implement this interface?”
Why do you need to ask unless you’re implementing one of the
cases that I pointed out above? Look at a lot of Ruby code out
there: it assumes that the object provided implements the
interface – and it documents it as such.
That is my point exactly. The assumption is already there. The
flexibility is already lost. You MUST provide a certain object
which provides a certain interface, or you end up with a deeply
embedded error, instead of an informative one pointing to your own
code.
Incorrect. You might want to look at various libraries to see how
they handle this stuff. Some do it through custom exceptions. Some
do it early (a la Text::Format#hyphenator=).
You might not find it useful, but others definitely do.
Mostly people new to Ruby recently from Java. Seriously.
No. People experienced in both. I’ve programmed for Ruby for a
year or so now and I still wish for some type checking now and
then, when I’m digging around in someone else’s code trying to
figure out what parameters they expected.
I tend to open the code and look at it.
I don’t take being called a C++ or Java programmer as an insult. I
take it to mean that you don’t, or haven’t, programmed in either
enough to see type checking as a blessing, not a curse.
Obviously, you’re not speaking about that which you know. I
recommend against it. I’ve done plenty of C, C++, Java, and Pascal
programming – as well as truly strongly typed languages (Ada,
PL/SQL). Ada provides type checking that is truly useful (and
exceedingly annoying because of its inflexibility), not the
half-assed crap you get in C and C++. I’ve had to write two to
twenty times the amount of code in C/C++, Java, or Pascal to do the
same amount of work in Ruby. Not only that, my Ruby handles more
types than my equivalent statically typed code.
Being able to query for the signature of an interface, with some
syntactic sugar to allow parameters to require them (optionally)
is very much, to me, The Ruby Way; fearless and visionary. This
should make everyone happy; people don’t lose their flexibility
and we get all the type checking anyone should need.
Once again: ancestry/name checking is not type checking. Neither
is method checking (#respond_to?). Ruby divorces type from class,
which is something that C++ doesn’t do, and Java users “sorta”
get if they think about interfaces.
Terminology issue. Okay, let’s call my promotion “interface
declaration.” That’s all I advocate right now.
Still don’t like it. I’d accept method signature publication that
doesn’t actually do anything except provide metadata. Anything that
does anything automatic is too high a cost on runtime and
flexibility. You’re also advocating changing the way that Ruby’s
object hierarchy works. In theory, because Rubyists don’t generally
do ancestry/name checking, this won’t break anything.
You realise, of course, that you could solve this outside of Ruby’s
core entirely:
class Foo
implements IO
end
Foo.new.implements?(IO) # => true
I’ll leave the implementation as an exercise for the reader. Done
right, you could easily add it to all of the core classes, too.
Don’t be surprised, though, if few people use it – like few people
use StrongTyping.
Anecdotally, I did some work with Ruwiki recently and Chad Fowler
created a mock object to make the Ruwiki tokenizing process think
that it was dealing with an instance of Ruwiki. That mock object
has become part of Ruwiki’s object hierarchy, although not as
Chad defined it. (I abstracted the data that Chad was using into
its own object.) If I had done ancestry checking initially, Chad
wouldn’t have been able to do this.
Ah, ancestry checking. I see where we are crossed up in this. Let
me be clearer. I only advocate “interface checking.” A class is
just one form of interface. A module is another, when it’s
mixed-in. I wholly support something like this:
class MyMockRuwikiClass interface RuwikiClass
end
Sorry, I don’t want Java. We’ve already got it and I prefer not to
use it because it requires entirely too much typing to do what
should be simple things (e.g., iterating through lists) or thinking
to do what shouldn’t be that hard (e.g., lists of heterogeneous
items). What’s the difference between “interface Ruwiki” and
“include Ruwiki” (neither of which would work, because Ruwiki isn’t
a module and is therefore unable to be included into other classes).
In fact, Chad was able to determine that there were four methods
needed. If he had attempted to include Ruwiki in his mock class, he
would have gotten tons more functionality.
Remember: the functionality had not yet been abstracted. Because I
didn’t do “interface” checking, Chad was able to Do The Smart Thing
without depending on me having Done The Right Thing to begin with.
So, although YOU might not need this, I and others do.
Why? I’m serious. It’s also a rhetorical question: why do you
need this? What about your code demands this? Is it a presumed
need, or a real need? If it’s a presumed need, YAGNI. If it’s a
real need, why not consider if your design and/or implementation
are too fragile. A need for static typing in Ruby is an indicator
of code smell. Yes, I have some smelly code that I haven’t
updated to this point.
I’ve made a pretty good analogy in another post.
If it’s the post I’m thinking of, it doesn’t stand up to the real
world.
If someone wants a scripting language that requires type
checking, use PHP. Neither Perl nor Python offer type
checking[1], although Python went through this discussion a
couple of years ago, and they apparently did decide to implement
an optional type system. The best form I found from my
perspective was PyIDL.
Wait, you don’t throw the baby out with the bath water. Ruby is
infinitely superior to PHP. It doesn’t have to become like PHP
just to get “interface declarations.”
I disagree. Ruby plus static typing – or interface checking, if you
want to call it that – isn’t a language that I’m interested in.
(And I must repeat that “interface checking” is still too kind for
it; the reality is that any sort of name checking is a promise
that’s worth less than “the check’s in the mail.”)
-austin
···
On Thu, 20 Nov 2003 05:48:37 +0900, Sean O’Dell wrote:
On Wednesday 19 November 2003 12:04 pm, Austin Ziegler wrote:
On Thu, 20 Nov 2003 02:43:31 +0900, Sean O’Dell wrote:
–
austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19
* 16.45.48