Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)

2 views
Skip to first unread message

Sean O'Dell

unread,
Nov 19, 2003, 12:51:02 PM11/19/03
to
On Wednesday 19 November 2003 03:55 am, dbl...@wobblini.net wrote:
> On Wed, 19 Nov 2003, Thien Vuong wrote:
> >
> > Uh... If we're getting there the equivalent argument would be
> > "respond_to?" would not tell you anything except that it respond to
> > "respond_to?" :). Unless we agree on some basic contract that a method
> > need to satisfy (knowing that it could be changed - mind you), it is
> > pointless to go one way or another.
>
> OK, let me rephrase that one :-) The thing you need to know is the
> object's interface -- which, this being Ruby, has the potential to
> change. respond_to? gives you some of that information, very close to
> the moment of calling a method. kind_of? doesn't. Therefore,
> kind_of? is more remote from the problem than respond_to?

Actually, kind_of? is far more informative. kind_of? indicates that it
belongs to a pre-described interface (a contract), with a fixed collection of
methods with parameters which are also known. respond_to? only tells you an
object has a method of a certain name. In another post I just made, I gave
this example:

obj.respond_to?(:open) => true

..so how do you call open? You don't know. Now this:

obj.kind_of?(:socket) => true

..now you know it responds to open, close, read, write, select, etc. and you
know what parameters they take. By only testing respond_to? you only know
that a method is present, but you don't know what parameters it takes.

Sean O'Dell


David A. Black

unread,
Nov 19, 2003, 1:27:00 PM11/19/03
to
Hi --

On Thu, 20 Nov 2003, Sean O'Dell wrote:

> On Wednesday 19 November 2003 03:55 am, dbl...@wobblini.net wrote:
> > On Wed, 19 Nov 2003, Thien Vuong wrote:
> > >
> > > Uh... If we're getting there the equivalent argument would be
> > > "respond_to?" would not tell you anything except that it respond to
> > > "respond_to?" :). Unless we agree on some basic contract that a method
> > > need to satisfy (knowing that it could be changed - mind you), it is
> > > pointless to go one way or another.
> >
> > OK, let me rephrase that one :-) The thing you need to know is the
> > object's interface -- which, this being Ruby, has the potential to
> > change. respond_to? gives you some of that information, very close to
> > the moment of calling a method. kind_of? doesn't. Therefore,
> > kind_of? is more remote from the problem than respond_to?
>
> Actually, kind_of? is far more informative. kind_of? indicates that
> it belongs to a pre-described interface (a contract), with a fixed
> collection of methods with parameters which are also known.
> respond_to? only tells you an object has a method of a certain name.
> In another post I just made, I gave this example:

A Ruby module or class is neither a contract, nor a fixed collection.
I really don't think, for example, that what Betrand Meyer meant by
"design by contract" was Ruby classes :-)

What you're doing is pressing the closest thing Ruby has to something
that *looks* like the kind of type-checking you want (i.e., kind_of?)
into service as a type check, which it isn't.

Quite honestly, the part I don't get about all this is: why? It's not
a type check; it is not at all rigorous; and believing in it involves
sweeping under the carpet one of the central design features of Ruby.


David

--
David A. Black
dbl...@wobblini.net


Sean O'Dell

unread,
Nov 19, 2003, 1:52:30 PM11/19/03
to
On Wednesday 19 November 2003 10:27 am, David A. Black wrote:
> On Thu, 20 Nov 2003, Sean O'Dell wrote:
> > On Wednesday 19 November 2003 03:55 am, dbl...@wobblini.net wrote:
> > > On Wed, 19 Nov 2003, Thien Vuong wrote:
> > > > Uh... If we're getting there the equivalent argument would be
> > > > "respond_to?" would not tell you anything except that it respond to
> > > > "respond_to?" :). Unless we agree on some basic contract that a
> > > > method need to satisfy (knowing that it could be changed - mind you),
> > > > it is pointless to go one way or another.
> > >
> > > OK, let me rephrase that one :-) The thing you need to know is the
> > > object's interface -- which, this being Ruby, has the potential to
> > > change. respond_to? gives you some of that information, very close to
> > > the moment of calling a method. kind_of? doesn't. Therefore,
> > > kind_of? is more remote from the problem than respond_to?
> >
> > Actually, kind_of? is far more informative. kind_of? indicates that
> > it belongs to a pre-described interface (a contract), with a fixed
> > collection of methods with parameters which are also known.
> > respond_to? only tells you an object has a method of a certain name.
> > In another post I just made, I gave this example:
>
> A Ruby module or class is neither a contract, nor a fixed collection.
> I really don't think, for example, that what Betrand Meyer meant by
> "design by contract" was Ruby classes :-)

A contract is any interface, and a Ruby class is an interface. True, a Ruby
class isn't the definition of a contract, but any OO class serves the
function well enough. Despite Ruby's flexibility, at any given point, a
class implements an interface. It can be extended or changed, but it
definitely describes an interface.

> What you're doing is pressing the closest thing Ruby has to something
> that *looks* like the kind of type-checking you want (i.e., kind_of?)
> into service as a type check, which it isn't.

Yes, but no one cares if an object being passed in is really of a certain
type, all they care about is if it has the interface their method(s) need. I
don't want a type check, I just want some enforcement that an interface
exists where I need it.

> Quite honestly, the part I don't get about all this is: why? It's not
> a type check; it is not at all rigorous; and believing in it involves
> sweeping under the carpet one of the central design features of Ruby.

Because no type checking at all causes non-descriptive errors when an object
is passed to a method (2 of 1 parameters?) which expects it to have certain
methods which takes certain parameters. Either way, an error occurs, but
with some form of type checking, the programmer gets a much clearer picture
of why they can't pass in a particular object to a method without at least
some modification.

Example: you get an "object does not the :socket interface." You then say to
yourself: "Ah! This library wants something like the Socket class...okay, I
can fake that!"

It's just informational. It's just for the purpose of speeding up development
and making the code a little more robust through a good report of what is
going wrong when someone passes in an object that can't be used by the
method. It doesn't prove that an object correctly implements an interface,
and the object can definitely break the interface, but the facility would be
there for programmers who can make use of it. For those that tend to break
interfaces when programming rather than use them properly, there are always
QA jobs. =)

Sean O'Dell

Yukihiro Matsumoto

unread,
Nov 19, 2003, 2:05:07 PM11/19/03
to
Hi,

In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)"


on 03/11/20, "Sean O'Dell" <se...@celsoft.com> writes:

|A contract is any interface, and a Ruby class is an interface. True, a Ruby
|class isn't the definition of a contract, but any OO class serves the
|function well enough. Despite Ruby's flexibility, at any given point, a
|class implements an interface. It can be extended or changed, but it
|definitely describes an interface.

A class has interface; a class can be used as interface (by set of its
methods); but it should not be checked by kind_of? or anything based
on inheritance, just because it hinders flexibility of dynamic typing
so much; remember StringIO or tempfile examples.

|It's just informational. It's just for the purpose of speeding up development
|and making the code a little more robust through a good report of what is
|going wrong when someone passes in an object that can't be used by the
|method. It doesn't prove that an object correctly implements an interface,
|and the object can definitely break the interface, but the facility would be
|there for programmers who can make use of it. For those that tend to break
|interfaces when programming rather than use them properly, there are always
|QA jobs. =)

I admit type checking can gain you something, at the cost of
flexibility, which I don't want to pay in Ruby. If you prefer static
typing to dynamic typing, it's OK, there so many statically typed
languages out there. Go ahead.

matz.


Sean O'Dell

unread,
Nov 19, 2003, 2:37:50 PM11/19/03
to
On Wednesday 19 November 2003 11:05 am, Yukihiro Matsumoto wrote:
> Hi,
>
> In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing
> metadata about attribute types)"
>
> on 03/11/20, "Sean O'Dell" <se...@celsoft.com> writes:
> |A contract is any interface, and a Ruby class is an interface. True, a
> | Ruby class isn't the definition of a contract, but any OO class serves
> | the function well enough. Despite Ruby's flexibility, at any given
> | point, a class implements an interface. It can be extended or changed,
> | but it definitely describes an interface.
>
> A class has interface; a class can be used as interface (by set of its
> methods); but it should not be checked by kind_of? or anything based
> on inheritance, just because it hinders flexibility of dynamic typing
> so much; remember StringIO or tempfile examples.

But again, that flexibility is LOST when you have to pass an object to a
method that REQUIRES it to behave a certain way. The flexibility is already
gone; it wasn't eliminate by a language quirk, it was eliminated by the need
of the method being called.

> |It's just informational. It's just for the purpose of speeding up
> | development and making the code a little more robust through a good
> | report of what is going wrong when someone passes in an object that can't
> | be used by the method. It doesn't prove that an object correctly
> | implements an interface, and the object can definitely break the
> | interface, but the facility would be there for programmers who can make
> | use of it. For those that tend to break interfaces when programming
> | rather than use them properly, there are always QA jobs. =)
>
> I admit type checking can gain you something, at the cost of
> flexibility, which I don't want to pay in Ruby. If you prefer static
> typing to dynamic typing, it's OK, there so many statically typed
> languages out there. Go ahead.

No, I prefer BOTH. There are times when dynamic typing works, and times when
you need enforcement of an interface.

I'm clear on the subject of dynamic typing, and I'm not an advocate for static
typing. Being a strong advocate for one or the other is foolish, in my
opinion. Both are useful, and both can be employed here, so I BEG you to
please employ SOME form of built-in interface checking. Having absolutely NO
mechanism leaves people who need to check for certain methods and parameters
hanging in the wind.

I'm only talking about checking that a certain interface is present. Just for
the purpose of providing an informative error message when an object which
cannot fulfill the needs of a method is passed. Right now, it just explodes
with an ugly message about something that happened deep in the called method.
Something more informative would go a LONG way.

Reconsider, Matz.

Sean O'Dell

Chad Fowler

unread,
Nov 19, 2003, 2:46:51 PM11/19/03
to
On Thu, 20 Nov 2003, Sean O'Dell wrote:

# I'm clear on the subject of dynamic typing, and I'm not an advocate for static
# typing. Being a strong advocate for one or the other is foolish, in my
# opinion. Both are useful, and both can be employed here, so I BEG you to
# please employ SOME form of built-in interface checking. Having absolutely NO
# mechanism leaves people who need to check for certain methods and parameters
# hanging in the wind.
#

If you really need something that bad, how about respond_to? If you need
something more robust, then there's types.rb by Eivind Eklund.

Weirich, James

unread,
Nov 19, 2003, 2:47:29 PM11/19/03
to
> But again, that flexibility is LOST when you have to pass an
> object to a method that REQUIRES it to behave a certain way.

Using "kind_of" testing /further/ reduces flexibility by requiring
particular inheritance structures in addition to the protocol requirements.

> Having absolutely NO mechanism leaves people who need to check
> for certain methods and parameters hanging in the wind.

Can you give an example of where someone would NEED to check.

--
-- Jim Weirich / Compuware
-- FWP Capture Services
-- Phone: 859-386-8855

Sean O'Dell

unread,
Nov 19, 2003, 3:17:10 PM11/19/03
to
On Wednesday 19 November 2003 11:47 am, Weirich, James wrote:
> > But again, that flexibility is LOST when you have to pass an
> > object to a method that REQUIRES it to behave a certain way.
>
> Using "kind_of" testing /further/ reduces flexibility by requiring
> particular inheritance structures in addition to the protocol requirements.

No, the flexibility is gone already; kind_of? just provides a more informative
way to find out what went wrong.

> > Having absolutely NO mechanism leaves people who need to check
> > for certain methods and parameters hanging in the wind.
>
> Can you give an example of where someone would NEED to check.

Okay, you got it. Here's an example of how this sort of type checking would
be useful:

I am the developer of a web server library. I have written a library which
contains a class that is used as the server-end of an HTTP request. It is
essentially a socket that I use to read and write.

Now, Bob the application developer decides to use my library to write himself
a little HTTP applet. He writes a CGI method that hooks into my library and
when he runs the applet, he can pass form data to the server and his little
CGI hook does something fun.

But Bob's CGI method is not working as intended, so he decides to do some
debugging.

He decides to build the full HTTP request as a text file, and pipe the file to
the CGI method through my library by opening it with the File object and
passing a File object where I was expecting a Socket object.

The code goes BOOM. The library is trying to make calls to methods that don't
exist. Bob sees what methods are being requested, but he has no reference to
them. Nowhere does he see "I expected a Socket." It's just not there. The
calls are being made, but what are they? What interface does my library
want? He has no clue. All he sees are error messages, but since he is not
me, he doesn't know I expected a Socket object. It's never declared
anywhere.

Now, let's add in interface checking.

My methods all require that objects being passed in declare themselves with
the Socket interface signature.

Now replay the scenario.

Bob gets a message "that object does not implement the Socket interface."

Bob knows what went wrong. He looks up the Socket interface, modifies his
File object to fake the interface and provide my library with all the
read/write functions it expects, with a full reference to what parameters are
expected and so on.

This is not a complicated scenario, either. I would wager that some people
monitoring this newsgroup have actually tried to do this at some point in
their programming career, perhaps even tried it with Ruby.

Getting an error message that an object is of the type required, is VERY
useful in some places. Not always, but in some places.

Sean O'Dell

Sean O'Dell

unread,
Nov 19, 2003, 3:22:02 PM11/19/03
to

Because something of this nature should be built-in. It's faster when written
in C and doesn't have to be dynamically loaded via "require." I also don't
believe type checking is something that there should be competing libraries
for. Also, respond_to? doesn't say anything about what a method does or what
parameters it takes. Checking for an implemented interface declares all of
that.

Sean O'Dell

Maik Schmidt

unread,
Nov 19, 2003, 3:28:43 PM11/19/03
to
Sean O'Dell wrote:
> Because something of this nature should be built-in. It's faster when written
> in C
Premature optimization is the root of all evil.

> and doesn't have to be dynamically loaded via "require."

Why should everybody pay for it?

> I also don't
> believe type checking is something that there should be competing libraries
> for.

Why? Monocultures are often a bad thing.

> Also, respond_to? doesn't say anything about what a method does or what
> parameters it takes. Checking for an implemented interface declares all of
> that.

That's not true in any case. If checking for an implemented interface
was sufficient, then the interface would have to look like a Java
interface or something similar. The questionable feature that you are
asking for implies IMHO a lot more changes than we all see now. And I
cannot see a real benefit.

Cheers,

<maik/>

Yukihiro Matsumoto

unread,
Nov 19, 2003, 3:47:50 PM11/19/03
to
Hi,

In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)"
on 03/11/20, "Sean O'Dell" <se...@celsoft.com> writes:

|> A class has interface; a class can be used as interface (by set of its
|> methods); but it should not be checked by kind_of? or anything based
|> on inheritance, just because it hinders flexibility of dynamic typing
|> so much; remember StringIO or tempfile examples.
|
|But again, that flexibility is LOST when you have to pass an object to a
|method that REQUIRES it to behave a certain way. The flexibility is already
|gone; it wasn't eliminate by a language quirk, it was eliminated by the need
|of the method being called.

I'm not sure what you mean by "flexibility LOST". In your scenario in
[ruby-talk:85611], certainly it is much easier to tell that your
library is requiring Socket interface, but without that kind of
interface check, no flexibility is lost, it's little bit hard to find
out the semantics.

Maybe we are referring different "flexibility". Mine is the one that
allows replacing IO by StringIO. Currently we have no language
support to check nor enforce them, but it's still possible, not lost.

|I'm only talking about checking that a certain interface is present. Just for
|the purpose of providing an informative error message when an object which
|cannot fulfill the needs of a method is passed. Right now, it just explodes
|with an ugly message about something that happened deep in the called method.
|Something more informative would go a LONG way.
|
|Reconsider, Matz.

Reconsider what? I didn't tell you any decision yet. I'm still
the level of seeking what you mean.

matz.


Austin Ziegler

unread,
Nov 19, 2003, 3:53:07 PM11/19/03
to
On Thu, 20 Nov 2003 02:51:02 +0900, Sean O'Dell wrote:
> Actually, kind_of? is far more informative. kind_of? indicates
> that it belongs to a pre-described interface (a contract), with a
> fixed collection of methods with parameters which are also known.

Not in Ruby, it doesn't. #kind_of? tells you that it has a
particular name in its ancestry. Nothing more, nothing less.
Treating a name as a contract is improper, because that's not the
case at all.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19
* 15.50.40


Chad Fowler

unread,
Nov 19, 2003, 4:01:54 PM11/19/03
to
On Thu, 20 Nov 2003, Sean O'Dell wrote:

# On Wednesday 19 November 2003 11:46 am, Chad Fowler wrote:


# > On Thu, 20 Nov 2003, Sean O'Dell wrote:
# >

# > # I'm clear on the subject of dynamic typing, and I'm not an advocate for
# > static # typing. Being a strong advocate for one or the other is foolish,
# > in my # opinion. Both are useful, and both can be employed here, so I BEG
# > you to # please employ SOME form of built-in interface checking. Having
# > absolutely NO # mechanism leaves people who need to check for certain
# > methods and parameters # hanging in the wind.
# > #
# >


# > If you really need something that bad, how about respond_to? If you need

# > something more robust, then there's types.rb by Eivind Eklund.
#
# Because something of this nature should be built-in.

..in your minoority opinion.

# It's faster when written
# in C and doesn't have to be dynamically loaded via "require." I also don't
# believe type checking is something that there should be competing libraries
# for.

Why not? By the way, I think types.rb is the only library that actually
*does* type checking in the accurate ruby sense.

# Also, respond_to? doesn't say anything about what a method does or what
# parameters it takes. Checking for an implemented interface declares all of
# that.

As demonstrated previously in this thread, class and/or module inheritance
checking *doesn't* give you any info about what a method does or what
parameters it takes.


Austin Ziegler

unread,
Nov 19, 2003, 4:03:54 PM11/19/03
to
On Thu, 20 Nov 2003 03:52:30 +0900, Sean O'Dell wrote:
> On Wednesday 19 November 2003 10:27 am, David A. Black wrote:
>> A Ruby module or class is neither a contract, nor a fixed
>> collection. I really don't think, for example, that what Betrand
>> Meyer meant by "design by contract" was Ruby classes :-)
> A contract is any interface, and a Ruby class is an interface.
> True, a Ruby class isn't the definition of a contract, but any OO
> class serves the function well enough. Despite Ruby's flexibility,
> at any given point, a class implements an interface. It can be
> extended or changed, but it definitely describes an interface.

A class defines a collection of methods that could be called an
interface. However, an instance of a Ruby class need not implement
that interface. Again, a pathological example:

f = File.open("foo.txt")
class << f
undef write
end

The object referenced by f *is* a File, but it doesn't support
#write.

>> What you're doing is pressing the closest thing Ruby has to
>> something that *looks* like the kind of type-checking you want
>> (i.e., kind_of?) into service as a type check, which it isn't.
> Yes, but no one cares if an object being passed in is really of a
> certain type, all they care about is if it has the interface their
> method(s) need. I don't want a type check, I just want some
> enforcement that an interface exists where I need it.

Which #kind_of? does *not* do. *Why* do you want or need that
enforcement? When I first used dynamic languages, I wanted them to
act like the static languages that I worked with, but I quickly grew
out of it. I briefly experimented with #kind_of? checking in Ruby,
but found few cases where I really needed it.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19

* 15.53.42


Sean O'Dell

unread,
Nov 19, 2003, 4:08:30 PM11/19/03
to
On Wednesday 19 November 2003 12:42 pm, Maik Schmidt wrote:
> Sean O'Dell wrote:
> > Because something of this nature should be built-in. It's faster when
> > written in C
>
> Premature optimization is the root of all evil.

That doesn't follow at all. That's a severe generalization.

> > and doesn't have to be dynamically loaded via "require."
>
> Why should everybody pay for it?

Because that's where the hit should occur. If you don't need it, don't use
it.

> > I also don't
> > believe type checking is something that there should be competing
> > libraries for.
>
> Why? Monocultures are often a bad thing.

So where is the alternate implementation of the String class, or the Regexp
class?

Something this big really ought to have a stamp of approval. But that's a
stretch; it doesn't look like Matz wants anything of this nature in Ruby
anyway.

> > Also, respond_to? doesn't say anything about what a method does or what
> > parameters it takes. Checking for an implemented interface declares all
> > of that.
>
> That's not true in any case. If checking for an implemented interface
> was sufficient, then the interface would have to look like a Java
> interface or something similar. The questionable feature that you are
> asking for implies IMHO a lot more changes than we all see now. And I
> cannot see a real benefit.

It requires NO CHANGES. It's entirely optional. It's just a declaration of
an interface.

Sean O'Dell

Austin Ziegler

unread,
Nov 19, 2003, 4:10:50 PM11/19/03
to
On Thu, 20 Nov 2003 04:37:50 +0900, Sean O'Dell wrote:
> On Wednesday 19 November 2003 11:05 am, Yukihiro Matsumoto wrote:
>> A class has interface; a class can be used as interface (by set
>> of its methods); but it should not be checked by kind_of? or
>> anything based on inheritance, just because it hinders
>> flexibility of dynamic typing so much; remember StringIO or
>> tempfile examples.
> But again, that flexibility is LOST when you have to pass an
> object to a method that REQUIRES it to behave a certain way. The
> flexibility is already gone; it wasn't eliminate by a language
> quirk, it was eliminated by the need of the method being called.

This argument is circular.

> I'm only talking about checking that a certain interface is
> present. Just for the purpose of providing an informative error
> message when an object which cannot fulfill the needs of a method
> is passed. Right now, it just explodes with an ugly message about
> something that happened deep in the called method. Something more
> informative would go a LONG way.

Static typing in Ruby carries too high a performance price, because
*everything* (including class and method definitions) are executed
at runtime.

Far better to have an interface publication mechanism than static --
or "strong" typing.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19

* 16.05.20


Sean O'Dell

unread,
Nov 19, 2003, 4:16:23 PM11/19/03
to
On Wednesday 19 November 2003 12:47 pm, Yukihiro Matsumoto wrote:
> Hi,
>
> In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing
> metadata about attribute types)"
>
> on 03/11/20, "Sean O'Dell" <se...@celsoft.com> writes:
> |> A class has interface; a class can be used as interface (by set of its
> |> methods); but it should not be checked by kind_of? or anything based
> |> on inheritance, just because it hinders flexibility of dynamic typing
> |> so much; remember StringIO or tempfile examples.
> |
> |But again, that flexibility is LOST when you have to pass an object to a
> |method that REQUIRES it to behave a certain way. The flexibility is
> | already gone; it wasn't eliminate by a language quirk, it was eliminated
> | by the need of the method being called.
>
> I'm not sure what you mean by "flexibility LOST". In your scenario in
> [ruby-talk:85611], certainly it is much easier to tell that your
> library is requiring Socket interface, but without that kind of
> interface check, no flexibility is lost, it's little bit hard to find
> out the semantics.

When a method is written to use the methods of another object, and that code
is distributed as a library, the function of that method is fixed. You must
pass it an object that has the methods it requires, and those methods must
take the exact parameters it expects.

The flexibility to change the method of the object is lost. You cannot change
the parameters to the "send" method of a Socket object and pass it to a
library that uses it. You will get an error deep inside the library.

The flexibility was removed by the library developer. At the point of
calling, the object MUST conform.

> Maybe we are referring different "flexibility". Mine is the one that
> allows replacing IO by StringIO. Currently we have no language
> support to check nor enforce them, but it's still possible, not lost.

This is fine. This is what I want. If I write a method that can accept File
or StringIO, I want to write a method that asks "does this object implement
the IO interface" and if the answer is yes, then continue. Anyone can also
write a class that implements the IO interface and pass an object of that
class to my method. All I care about is "does this object implement this
interface?"

> |I'm only talking about checking that a certain interface is present. Just
> | for the purpose of providing an informative error message when an object
> | which cannot fulfill the needs of a method is passed. Right now, it just
> | explodes with an ugly message about something that happened deep in the
> | called method. Something more informative would go a LONG way.
> |
> |Reconsider, Matz.
>
> Reconsider what? I didn't tell you any decision yet. I'm still
> the level of seeking what you mean.

You said the following:

> I admit type checking can gain you something, at the cost of
> flexibility, which I don't want to pay in Ruby.

You don't want to pay the price of type checking in Ruby. My version of it is
really "interface checking," but either way what you said sounds like you've
decided you don't want to pay the price for any of this.

Sean O'Dell

Sean O'Dell

unread,
Nov 19, 2003, 4:18:01 PM11/19/03
to
On Wednesday 19 November 2003 12:53 pm, Austin Ziegler wrote:
> On Thu, 20 Nov 2003 02:51:02 +0900, Sean O'Dell wrote:
> > Actually, kind_of? is far more informative. kind_of? indicates
> > that it belongs to a pre-described interface (a contract), with a
> > fixed collection of methods with parameters which are also known.
>
> Not in Ruby, it doesn't. #kind_of? tells you that it has a
> particular name in its ancestry. Nothing more, nothing less.
> Treating a name as a contract is improper, because that's not the
> case at all.

I agree. My intention is to elevate us to something more than respond_to? and
kind_of? calls. I misused kind_of?, sorry. I meant to use an imaginary
method that says "this object implements this interface."

Sean O'Dell

Sean O'Dell

unread,
Nov 19, 2003, 4:22:57 PM11/19/03
to
On Wednesday 19 November 2003 01:01 pm, Chad Fowler wrote:
> On Thu, 20 Nov 2003, Sean O'Dell wrote:
>
> # On Wednesday 19 November 2003 11:46 am, Chad Fowler wrote:
> # > On Thu, 20 Nov 2003, Sean O'Dell wrote:
> # >
> # > # I'm clear on the subject of dynamic typing, and I'm not an advocate
> for # > static # typing. Being a strong advocate for one or the other is
> foolish, # > in my # opinion. Both are useful, and both can be employed
> here, so I BEG # > you to # please employ SOME form of built-in interface
> checking. Having # > absolutely NO # mechanism leaves people who need to
> check for certain # > methods and parameters # hanging in the wind.
> # > #
> # >
> # > If you really need something that bad, how about respond_to? If you
> need # > something more robust, then there's types.rb by Eivind Eklund. #
> # Because something of this nature should be built-in.
>
> ...in your minoority opinion.

I'm in the minority of people who are here to speak out FOR some form of type
checking. There are few here who argue my side of the issue. My feeling is,
so many here are so strongly against it that they don't bother even posting
here.

> # It's faster when written
> # in C and doesn't have to be dynamically loaded via "require." I also
> don't # believe type checking is something that there should be competing
> libraries # for.
>
> Why not? By the way, I think types.rb is the only library that actually
> *does* type checking in the accurate ruby sense.

Already answered elsewhere.

> # Also, respond_to? doesn't say anything about what a method does or what
> # parameters it takes. Checking for an implemented interface declares all
> of # that.
>
> As demonstrated previously in this thread, class and/or module inheritance
> checking *doesn't* give you any info about what a method does or what
> parameters it takes.

Actually, it tells you exactly. If a class inherits from String, you know it
has all the methods String does, and you know exactly what parameters they
take. The class developer can radicially modify those methods, and yes the
class no longer conforms to the String interface, but that's just one example
of what humans do to circumvent an enforcement mechanism. It happens; I'm
not concerned with what happens when people deliberately break the interface
implementation.

But as I've said, "interface checking" is not checking ancestry. Ancestry is
just one way a class declares that it implements an interface. It can just
as easily make that declaration without inheriting anything. I was thinking
perhaps an "interface" keyword would work to make the declaration. The class
would then be free to implement as much of the interface as it wants to, or
none of it. The declaration is just a declaration, not a guarantee or
inheritance.

Sean O'Dell


Sean O'Dell

unread,
Nov 19, 2003, 4:25:32 PM11/19/03
to

This what I'm advocating. But for simplicity, the interface descriptions can
be taken from existing classes and modules. They're already used for
inheritance and mix-ins, so it makes sense. If a class inherits from
another, you can assume it implements its interface. The methods of the
interface are never encoded in any way. The interface is just a name, a
declaration.

Sean O'Dell

Austin Ziegler

unread,
Nov 19, 2003, 4:25:49 PM11/19/03
to
On Thu, 20 Nov 2003 05:17:10 +0900, Sean O'Dell wrote:
> On Wednesday 19 November 2003 11:47 am, Weirich, James wrote:
>> Can you give an example of where someone would NEED to check.
> Okay, you got it. Here's an example of how this sort of type checking
would
> be useful:
[...]

> He decides to build the full HTTP request as a text file, and pipe the
> file to the CGI method through my library by opening it with the File
> object and passing a File object where I was expecting a Socket object.

irb(main):002:0> require 'socket'
=> true
irb(main):003:0> Socket.ancestors
=> [Socket, BasicSocket, IO, File::Constants, Enumerable, Object, Kernel]
irb(main):004:0> File.ancestors
=> [File, IO, File::Constants, Enumerable, Object, Kernel]
irb(main):005:0> Socket.methods - File.methods
=> ["pack_sockaddr_in", "do_not_reverse_lookup", "getservbyname",
"do_not_reverse_lookup=", "unpack_sockaddr_in", "socketpair",
"gethostbyname", "getaddrinfo", "pair", "getnameinfo", "gethostname",
"sockaddr_in", "gethostbyaddr"]
irb(main):006:0> Socket.instance_methods - File.instance_methods
=> ["bind", "sysaccept", "recvfrom", "accept", "listen", "connect"]

Aside from the above methods, as long as your HTTP server doesn't depend on
those items in the place where Bob would send the request (you *have*
designed
your code with appropriate separation of concerns, haven't you?), then I see
no problem.

> The code goes BOOM. The library is trying to make calls to methods that
> don't exist. Bob sees what methods are being requested, but he has no
> reference to them. Nowhere does he see "I expected a Socket."

Since Bob is a smart programmer, he'll see in his error log:

NoMethodError: undefined method `accept' for #<File:3>
from ...

Well, this means that his File object doesn't know the method #accept.
Therefore, he can open the source to your HTTP library and see "oh! this
guy's
expecting a Socket and has put accept in the wrong place!" If Bob's a really
smart programmer, he'd already know that #accept is a Socket method.

I've found bugs in libraries and bugs in my own code -- with the software
working *just as it does already*. Your scenario doesn't stand.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19

* 16.13.28

Yukihiro Matsumoto

unread,
Nov 19, 2003, 4:26:20 PM11/19/03
to
Hi,

In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)"

on 03/11/20, Chad Fowler <ch...@chadfowler.com> writes:

|Why not? By the way, I think types.rb is the only library that actually
|*does* type checking in the accurate ruby sense.

Really? As long as I checked last time, its check is done based on
"kind_of?" relation.

matz.

Sean O'Dell

unread,
Nov 19, 2003, 4:29:12 PM11/19/03
to
On Wednesday 19 November 2003 01:03 pm, Austin Ziegler wrote:
> On Thu, 20 Nov 2003 03:52:30 +0900, Sean O'Dell wrote:
> > On Wednesday 19 November 2003 10:27 am, David A. Black wrote:
> >> A Ruby module or class is neither a contract, nor a fixed
> >> collection. I really don't think, for example, that what Betrand
> >> Meyer meant by "design by contract" was Ruby classes :-)
> >
> > A contract is any interface, and a Ruby class is an interface.
> > True, a Ruby class isn't the definition of a contract, but any OO
> > class serves the function well enough. Despite Ruby's flexibility,
> > at any given point, a class implements an interface. It can be
> > extended or changed, but it definitely describes an interface.
>
> A class defines a collection of methods that could be called an
> interface. However, an instance of a Ruby class need not implement
> that interface. Again, a pathological example:
>
> f = File.open("foo.txt")
> class << f
> undef write
> end
>
> The object referenced by f *is* a File, but it doesn't support
> #write.

I agree. I don't advocate STRONG checking, just simple declarations that
"this object implements this interface" and it does, it does, if it doesn't,
it doesn't.

> >> What you're doing is pressing the closest thing Ruby has to
> >> something that *looks* like the kind of type-checking you want
> >> (i.e., kind_of?) into service as a type check, which it isn't.
> >
> > Yes, but no one cares if an object being passed in is really of a
> > certain type, all they care about is if it has the interface their
> > method(s) need. I don't want a type check, I just want some
> > enforcement that an interface exists where I need it.
>
> Which #kind_of? does *not* do. *Why* do you want or need that
> enforcement? When I first used dynamic languages, I wanted them to
> act like the static languages that I worked with, but I quickly grew
> out of it. I briefly experimented with #kind_of? checking in Ruby,
> but found few cases where I really needed it.

That's good, because you have no choice. Doing kind_of? isn't terribly
flexible. It requires inheritance, and that means people have to write
abstract classes in order to allow people to re-implement classes. I don't
advocate inheritance as a means to communication conformity with an
interface. Just a keyword that says "I implement this interface" is
perfectly acceptable.

I would also wager that if it were available, and powerful, you would return
to at least a little bit of type checking. People only miss something for so
long before they get used to not having it. Of course you don't miss it now.

Sean O'Dell

Sean O'Dell

unread,
Nov 19, 2003, 4:32:00 PM11/19/03
to

Wrong! There's no mention of the Socket object anywhere! The only way he
would know that is by searching the source code of OTHER METHODS that call
that method, then tracing back to where the object that is passed in was
created. Then he can see Socket.new.

Also, don't make the assumption that the developer automatically knows #accept
belongs to the Socket object. Your familiarity with Socket is causing you to
discount the pain a developer feels when this sort of error occurs. A
developer may know NOTHING about the Socket object and will not have a CLUE
about #accept.

> I've found bugs in libraries and bugs in my own code -- with the software
> working *just as it does already*. Your scenario doesn't stand.

Sure it does.

Sean O'Dell

Gavin Sinclair

unread,
Nov 19, 2003, 4:33:32 PM11/19/03
to
On Thursday, November 20, 2003, 6:37:50 AM, Sean wrote:

> I'm only talking about checking that a certain interface is present. Just for
> the purpose of providing an informative error message when an object which
> cannot fulfill the needs of a method is passed. Right now, it just explodes
> with an ugly message about something that happened deep in the called method.
> Something more informative would go a LONG way.

Nobody likes undescriptive error messages. You're asking Ruby to do
something about them, at a cost. I prefer to believe that the cost
should be on the library developer, who wishes to make life easier for
his clients.

class LibraryClass
def library_method
# code ...
rescue SpecificError
# handle it
rescue => err
raise LibraryError, "library_method failed: #{err.message}"
end
end

Granted, it doesn't often happen in real life, but it is better if the
library author is putting some thought into the user experience,
rather than feeling like he's jumping through hoops to keep an
interface-checker happy. A frustrated developer probably won't
produce much code; in that case, at least we'd have less cryptic error
messages, I suppose :)

I'm not completely unsympathetic to what you're saying. In fact, I'd
like to read a detailed RCR.

Cheers,
Gavin


Sean O'Dell

unread,
Nov 19, 2003, 4:35:41 PM11/19/03
to

Funny you should mention that. =)

Sean O'Dell

Yukihiro Matsumoto

unread,
Nov 19, 2003, 4:38:21 PM11/19/03
to
Hi,

In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)"
on 03/11/20, "Sean O'Dell" <se...@celsoft.com> writes:

|> library is requiring Socket interface, but without that kind of
|> interface check, no flexibility is lost, it's little bit hard to find
|> out the semantics.
|
|When a method is written to use the methods of another object, and that code
|is distributed as a library, the function of that method is fixed. You must
|pass it an object that has the methods it requires, and those methods must
|take the exact parameters it expects.
|
|The flexibility to change the method of the object is lost. You cannot change
|the parameters to the "send" method of a Socket object and pass it to a
|library that uses it. You will get an error deep inside the library.

I don't understand "the flexibility to change the method of the
object". What is that? I think it has never existed before.
We cannot lose something that has never existed.

|> |Reconsider, Matz.
|>
|> Reconsider what? I didn't tell you any decision yet. I'm still
|> the level of seeking what you mean.
|
|You said the following:
|
|> I admit type checking can gain you something, at the cost of
|> flexibility, which I don't want to pay in Ruby.
|
|You don't want to pay the price of type checking in Ruby. My version of it is
|really "interface checking," but either way what you said sounds like you've
|decided you don't want to pay the price for any of this.

You've misunderstood me. I don't want to pay "the cost of losing
flexibility", that means I don't want to make any change hindersc
"my" flexibility, which can be harmed by "type checking based on
inheritance". Since your "interface checking" do not affect
"flexibility" in bad manner, I said nothing against it.

But still, there's no known effective way to define and check
"interface" in a language so dynamic as Ruby. Long way to go.

matz.


Yukihiro Matsumoto

unread,
Nov 19, 2003, 4:45:44 PM11/19/03
to
Hi,

In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)"
on 03/11/20, "Sean O'Dell" <se...@celsoft.com> writes:

|I agree. My intention is to elevate us to something more than respond_to? and
|kind_of? calls. I misused kind_of?, sorry. I meant to use an imaginary
|method that says "this object implements this interface."

This is all cause of this long thread. I'm glad that we've finally
found out the point. Then see [ruby-talk:85641].

matz.


Sean O'Dell

unread,
Nov 19, 2003, 4:48:16 PM11/19/03
to
On Wednesday 19 November 2003 01:38 pm, Yukihiro Matsumoto wrote:
> Hi,
>
> In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing
> metadata about attribute types)"
>
> on 03/11/20, "Sean O'Dell" <se...@celsoft.com> writes:
> |> library is requiring Socket interface, but without that kind of
> |> interface check, no flexibility is lost, it's little bit hard to find
> |> out the semantics.
> |
> |When a method is written to use the methods of another object, and that
> | code is distributed as a library, the function of that method is fixed.
> | You must pass it an object that has the methods it requires, and those
> | methods must take the exact parameters it expects.
> |
> |The flexibility to change the method of the object is lost. You cannot
> | change the parameters to the "send" method of a Socket object and pass it
> | to a library that uses it. You will get an error deep inside the
> | library.
>
> I don't understand "the flexibility to change the method of the
> object". What is that? I think it has never existed before.
> We cannot lose something that has never existed.

Right now, if I inherit the File object, I can re-define the #read method to
do something other than just read (perhaps log the read action somewhere).
If I don't change the parameters, I can pass the object to other the methods
of other classes that want a File object, and they can call obj.read safely.

However, if I change the parameters that #read takes, I can no longer pass
that object to those methods. I don't have that flexibility. If I want to
pass my object, I must leave the parameters of #read the same

> |> |Reconsider, Matz.
> |>
> |> Reconsider what? I didn't tell you any decision yet. I'm still
> |> the level of seeking what you mean.
> |
> |You said the following:
> |> I admit type checking can gain you something, at the cost of
> |> flexibility, which I don't want to pay in Ruby.
> |
> |You don't want to pay the price of type checking in Ruby. My version of
> | it is really "interface checking," but either way what you said sounds
> | like you've decided you don't want to pay the price for any of this.
>
> You've misunderstood me. I don't want to pay "the cost of losing
> flexibility", that means I don't want to make any change hindersc
> "my" flexibility, which can be harmed by "type checking based on
> inheritance". Since your "interface checking" do not affect
> "flexibility" in bad manner, I said nothing against it.

You don't lose flexibility at all. Your flexibility is exactly the same.
Here, I'm going to go write an RCR and let's talk about it, I have the
feeling I'm not being understood at all.

Sean O'Dell

Charles Hixson

unread,
Nov 19, 2003, 5:09:58 PM11/19/03
to
Sean O'Dell wrote:

>On Wednesday 19 November 2003 01:01 pm, Chad Fowler wrote:
>
>
>>On Thu, 20 Nov 2003, Sean O'Dell wrote:
>>

>>...


>>
>>As demonstrated previously in this thread, class and/or module inheritance
>>checking *doesn't* give you any info about what a method does or what
>>parameters it takes.
>>
>>
>
>Actually, it tells you exactly. If a class inherits from String, you know it
>has all the methods String does, and you know exactly what parameters they

>... Sean O'Dell
>
No, you don't know that at all. It's a reasonable presumption, but any,
or all, or the methods that you think are there might have been
overridden. And might do something totally different. And this may be
for either a good reason or a silly reason.

Sean O'Dell

unread,
Nov 19, 2003, 5:25:19 PM11/19/03
to

But I would make the assumption that if they were overridden, they were
overridden properly, and that the methods my object needs are present. To
declare a certain inheritance, and then to break it, is something I don't
feel we should be enforcing. That's up to the developer if they choose to do
that. Also, if you want to enforce parameter checking, that's a whole other
ballgame to me. Not something I'm interested in; it's too intrusive.

Sean O'Dell

Weirich, James

unread,
Nov 19, 2003, 5:33:14 PM11/19/03
to
Sean O'Dell writes:

> > Actually, it tells you exactly. If a class inherits from String, you
know it
> > has all the methods String does, and you know exactly what parameters
they

Charles Hixson writes:

> No, you don't know that at all. It's a reasonable
> presumption, but any, or all, or the methods that you think
> are there might have been overridden. And might do something
> totally different. And this may be for either a good reason
> or a silly reason.

Several people have said this, and although true, this is not my main
concern and if people make an object non-LSP compliant, then they get what
they deserve.

However, my concern is the insistence that only those things that have
String in their ancestry can have string like behavior and can be passed to
functions expecting a string like object.

And this is what I thought Sean was saying (i.e. advocating ancestry
checks).

I now think what Sean is some way of "marking" a class to indicate that in
implements a particular protocol. That marking could be through
inheritance, but could also be done by some alternate mechanism.

This (IMHO) is not nearly as onerous as ancestor checking. But I'm not
convinced of its utility yet. I'll have to think about this.

Sean, did I capture your thoughts accurately? Or am I still missing
something.

Sean O'Dell

unread,
Nov 19, 2003, 5:55:16 PM11/19/03
to
Check Ruby Garden for my RCR on this subject. Comments follow, James.

On Wednesday 19 November 2003 02:33 pm, Weirich, James wrote:
> Sean O'Dell writes:
> > > Actually, it tells you exactly. If a class inherits from String, you
>
> know it
>
> > > has all the methods String does, and you know exactly what parameters
>
> they
>
> Charles Hixson writes:
> > No, you don't know that at all. It's a reasonable
> > presumption, but any, or all, or the methods that you think
> > are there might have been overridden. And might do something
> > totally different. And this may be for either a good reason
> > or a silly reason.
>
> Several people have said this, and although true, this is not my main
> concern and if people make an object non-LSP compliant, then they get what
> they deserve.

This is my feeling as well. It is, after all, The Ruby Way. At least right
now it is.

> However, my concern is the insistence that only those things that have
> String in their ancestry can have string like behavior and can be passed to
> functions expecting a string like object.
>
> And this is what I thought Sean was saying (i.e. advocating ancestry
> checks).

No, but close. I believe IF a class inherits from another class, it can
automatically be thought to implement the base class' interface. However, I
think the declaration of an interface can be made without inheritance.

> I now think what Sean is some way of "marking" a class to indicate that in
> implements a particular protocol. That marking could be through
> inheritance, but could also be done by some alternate mechanism.

Yes! That's what I mean to say. But also with that, the assumption that
classes that inherit from other classes inherit their interface. But that's
only one way to declare an object implements an interface.

> This (IMHO) is not nearly as onerous as ancestor checking. But I'm not
> convinced of its utility yet. I'll have to think about this.
>
> Sean, did I capture your thoughts accurately? Or am I still missing
> something.

Yeah, pretty accurately. My RCR, I think, makes it clearer. It's really
based on a bunch of things I've read here in this newsgroup; it's not really
my idea. More of a conglomeration of ideas. The problem, I think, is that I
jumped in with my thoughts and started off by wielding all the wrong
terminology. I should have started fresh with a new line of discussion
instead of pouncing in the middle of what was being said at the time.

One thing about what I propose is, except for the syntactic sugar for
parameters, which would be something only Matz could really implement (and I
assume it would be a bit of a pain), the rest of it is something that would
be super-easy to implement. In fact, it's probably a 10-minute coding
project. But I think it would die the death of obscurity if it weren't
built-in. Not many people would use it, but for those of us who are using
Ruby for some pretty sizable projects, they would be infinitely valuable.

Sean O'Dell


Simon Kitching

unread,
Nov 19, 2003, 5:55:48 PM11/19/03
to
On Thu, 2003-11-20 at 11:33, Weirich, James wrote:

> However, my concern is the insistence that only those things that have
> String in their ancestry can have string like behavior and can be passed to
> functions expecting a string like object.
>
> And this is what I thought Sean was saying (i.e. advocating ancestry
> checks).
>
> I now think what Sean is some way of "marking" a class to indicate that in
> implements a particular protocol. That marking could be through
> inheritance, but could also be done by some alternate mechanism.
>
> This (IMHO) is not nearly as onerous as ancestor checking. But I'm not
> convinced of its utility yet. I'll have to think about this.
>
> Sean, did I capture your thoughts accurately? Or am I still missing
> something.

Well, you certainly captured my thoughts. That's exactly what I was
suggesting with the "empty module as marker" suggestion.

Someone rightly pointed out that using modules + is_a? in this way was
probably an abuse of the intention of modules. It's just that there
isn't currently an alternative mechanism. I would personally be very
happy to have something like:

class Duck promises IBird
...
end

if someobj.has_promised(IBird)
..
end

Regards,

Simon


Greg McIntyre

unread,
Nov 19, 2003, 5:57:49 PM11/19/03
to
ma...@ruby-lang.org (Yukihiro Matsumoto) wrote:
> But still, there's no known effective way to define and check
> "interface" in a language so dynamic as Ruby. Long way to go.

I think this is fascinating stuff! Have there been any suggestions yet,
even wild stabs at it?

--
Greg McIntyre ======[ gr...@puyo.cjb.net ]===[ http://puyo.cjb.net ]===

Chad Fowler

unread,
Nov 19, 2003, 6:02:28 PM11/19/03
to
On Thu, 20 Nov 2003, Yukihiro Matsumoto wrote:

# Hi,
#
# In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)"
# on 03/11/20, Chad Fowler <ch...@chadfowler.com> writes:
#
# |Why not? By the way, I think types.rb is the only library that actually
# |*does* type checking in the accurate ruby sense.
#
# Really? As long as I checked last time, its check is done based on
# "kind_of?" relation.


Eivind's module is really a generalized checker, for which he happens to
have implemented support for kind_of? *and* respond_to? I was referring
to the respond_to? part when I said that it accurately supports type
checking.

Though I (and Eivind) don't really see much of a point in using it.

Chad


Austin Ziegler

unread,
Nov 19, 2003, 6:35:36 PM11/19/03
to
On Thu, 20 Nov 2003 06:08:30 +0900, Sean O'Dell wrote:
> On Wednesday 19 November 2003 12:42 pm, Maik Schmidt wrote:
>> Sean O'Dell wrote:
>>> and doesn't have to be dynamically loaded via "require."
>> Why should everybody pay for it?
> Because that's where the hit should occur. If you don't need it,
> don't use it.

Again: why should everybody pay for it? It's a runtime cost, not a
design time cost.

>>> I also don't believe type checking is something that there
>>> should be competing libraries for.
>> Why? Monocultures are often a bad thing.
> So where is the alternate implementation of the String class, or
> the Regexp class?

Oniguruma is being worked on -- but it's a compile-time option.
Simon Strandgaard is working on a pure Ruby regexp engine. There's a
proposal to allow MatchData to be created outside of Regexp#match
that would allow alternative implementations of regular expression
engines to be created.

> Something this big really ought to have a stamp of approval. But
> that's a stretch; it doesn't look like Matz wants anything of this
> nature in Ruby anyway.

Not quite true. Matz recognises the need for something like it (it's
in his Ruby2 presentation). At the beginning of my plunging into
this round of the discussion, I admitted the need for a few classes
of applications. But design-time/compile-time stuff isn't one of
those classes.

Static typing helps the compiler, not the developer.

>> That's not true in any case. If checking for an implemented
>> interface was sufficient, then the interface would have to look
>> like a Java interface or something similar. The questionable
>> feature that you are asking for implies IMHO a lot more changes
>> than we all see now. And I cannot see a real benefit.
> It requires NO CHANGES. It's entirely optional. It's just a
> declaration of an interface.

If it isn't like the Java/C# interface, then it's less "useful" than
what we have now in Ruby. Why? Because then it's a runtime cost
added to the program but it's merely a signal to the programmer.

To go back to your example from a different post:

class MockRuwiki
interface Ruwiki
end

This adds overhead (executing "interface Ruwiki") without enforcing
that MockRuwiki actually implements the interface. If I did:

def accept_ruwiki(foo as Ruwiki)
foo.backend
end

Then I'd happily accept your MockRuwiki but then I'd blow up because
you violated the contract anyway. How is this better than:

def accept_ruwiki(foo)
foo.backend
end

Seriously.



-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19

* 18.35.18

Sean O'Dell

unread,
Nov 19, 2003, 6:44:30 PM11/19/03
to
On Wednesday 19 November 2003 03:35 pm, Austin Ziegler wrote:
> On Thu, 20 Nov 2003 06:08:30 +0900, Sean O'Dell wrote:
> > On Wednesday 19 November 2003 12:42 pm, Maik Schmidt wrote:
> >> Sean O'Dell wrote:
> >>> and doesn't have to be dynamically loaded via "require."
> >>
> >> Why should everybody pay for it?
> >
> > Because that's where the hit should occur. If you don't need it,
> > don't use it.
>
> Again: why should everybody pay for it? It's a runtime cost, not a
> design time cost.

Because it's a feature I feel Ruby should have.

> > Something this big really ought to have a stamp of approval. But
> > that's a stretch; it doesn't look like Matz wants anything of this
> > nature in Ruby anyway.
>
> Not quite true. Matz recognises the need for something like it (it's
> in his Ruby2 presentation). At the beginning of my plunging into
> this round of the discussion, I admitted the need for a few classes
> of applications. But design-time/compile-time stuff isn't one of
> those classes.

What is -w for then?

> Static typing helps the compiler, not the developer.

What part of "I don't want static typing" didn't you understand?

Have you even read my RCR yet?

> >> That's not true in any case. If checking for an implemented
> >> interface was sufficient, then the interface would have to look
> >> like a Java interface or something similar. The questionable
> >> feature that you are asking for implies IMHO a lot more changes
> >> than we all see now. And I cannot see a real benefit.
> >
> > It requires NO CHANGES. It's entirely optional. It's just a
> > declaration of an interface.
>
> If it isn't like the Java/C# interface, then it's less "useful" than
> what we have now in Ruby. Why? Because then it's a runtime cost
> added to the program but it's merely a signal to the programmer.

You do realize we're talking about probably 20 lines of C code, plus whatever
it takes for Matz to add the syntactic sugar to parameters.

> To go back to your example from a different post:
>
> class MockRuwiki
> interface Ruwiki
> end
>
> This adds overhead (executing "interface Ruwiki") without enforcing
> that MockRuwiki actually implements the interface. If I did:
>
> def accept_ruwiki(foo as Ruwiki)
> foo.backend
> end
>
> Then I'd happily accept your MockRuwiki but then I'd blow up because
> you violated the contract anyway. How is this better than:
>
> def accept_ruwiki(foo)
> foo.backend
> end
>
> Seriously.

You are so stuck on "the cost" of this. It's such a tiny amount of code in
exchange for the ability to warn each every developer who calls your code
that you expect a certain interface from their object.

It's a LOT better. For you, who knows the contract, no, it's the same thing.
For a person using the library trying to pass in an unsuitable object, where
the documentation is lacking (and that's MOST of the code out there, MOST
code is completely undocumented) it results in an extremely useful and
time-saving error message.

Sean O'Dell

Austin Ziegler

unread,
Nov 19, 2003, 6:48:25 PM11/19/03
to
On Thu, 20 Nov 2003 06:29:12 +0900, Sean O'Dell wrote:
> I don't advocate inheritance as a means to communication
> conformity with an interface. Just a keyword that says "I
> implement this interface" is perfectly acceptable.

I've already addressed the uselessness of this. This could also be
implemented outside of the Ruby core -- even as a C extension.

> I would also wager that if it were available, and powerful, you
> would return to at least a little bit of type checking. People
> only miss something for so long before they get used to not having
> it. Of course you don't miss it now.

I don't miss it now because I am *currently* working with three
different languages on concurrent projects. Delphi (Object Pascal)
is strongly/strictly typed, and it's really infuriating because I
can't just write what I want to *do*; I have to type everything,
too. Visual Basic for Applications is optionally typed, but is much
easier to use if you do type variables. Ruby, on the other hand,
allows me to write the code that I want without having to worry
about typing at all.

The *only* place where I can foresee needing a typing mechanism in
Ruby is when I look at wrapping methods in SOAP or other RPC
mechanisms.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19

* 18.42.48


Sean O'Dell

unread,
Nov 19, 2003, 6:53:21 PM11/19/03
to
On Wednesday 19 November 2003 03:48 pm, Austin Ziegler wrote:
> On Thu, 20 Nov 2003 06:29:12 +0900, Sean O'Dell wrote:
> > I don't advocate inheritance as a means to communication
> > conformity with an interface. Just a keyword that says "I
> > implement this interface" is perfectly acceptable.
>
> I've already addressed the uselessness of this. This could also be
> implemented outside of the Ruby core -- even as a C extension.
>
> > I would also wager that if it were available, and powerful, you
> > would return to at least a little bit of type checking. People
> > only miss something for so long before they get used to not having
> > it. Of course you don't miss it now.
>
> I don't miss it now because I am *currently* working with three
> different languages on concurrent projects. Delphi (Object Pascal)
> is strongly/strictly typed, and it's really infuriating because I
> can't just write what I want to *do*; I have to type everything,
> too. Visual Basic for Applications is optionally typed, but is much
> easier to use if you do type variables. Ruby, on the other hand,
> allows me to write the code that I want without having to worry
> about typing at all.
>
> The *only* place where I can foresee needing a typing mechanism in
> Ruby is when I look at wrapping methods in SOAP or other RPC
> mechanisms.

Why only in SOAP or RPC mechanisms? What makes them different from someone
who calls into a library?

Sean O'Dell

Eric Schwartz

unread,
Nov 19, 2003, 6:56:16 PM11/19/03
to
"Sean O'Dell" <se...@celsoft.com> writes:
> It's a LOT better. For you, who knows the contract, no, it's the
> same thing. For a person using the library trying to pass in an
> unsuitable object, where the documentation is lacking (and that's
> MOST of the code out there, MOST code is completely undocumented) it
> results in an extremely useful and time-saving error message.

It's not a lot better to me, because it's inconsistent. If, as you
propose, it should work one way in some cases (the person honors the
interface) and not in others (they don't), then you're right back
where you started!

Consider:

Library A asks for interface "foo".
Library B does trickery to pretend to provide it, but only sorta
does so.
Programmer C uses Library B, only *oops* Library B forgot to
implement one method that A needs, so hey, we're right
back to status quo.

Only it's worse, because now Programmer C sees that B promised to
implement interface 'foo', and now she has to figure out where
interface 'foo' is defined (probably in Library D, which she may not
even have installed) and is even more confused than before. And I
speak as someone who is continually irritated by having to troll
through, say, cgi.rb or dbi.rb to discover there's a method that does
what I want it to.

Honestly, I think 90% of what bugs me about Ruby library interfaces
would be fixed if RDoc would dump formatted data somewhere useful, the
way perldoc does. That way, you just type 'man <class>' or at least
'rdoc <class>' (or whatever, I'm not trying to suggest a specific
implementation here), and the class' requirements are there for all to
see. This works well for Perl modules, and I think it'd work equally
well for Ruby.

-=Eric
--
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
-- Blair Houghton.

Sean O'Dell

unread,
Nov 19, 2003, 7:05:36 PM11/19/03
to
On Wednesday 19 November 2003 03:57 pm, Eric Schwartz wrote:
> "Sean O'Dell" <se...@celsoft.com> writes:
> > It's a LOT better. For you, who knows the contract, no, it's the
> > same thing. For a person using the library trying to pass in an
> > unsuitable object, where the documentation is lacking (and that's
> > MOST of the code out there, MOST code is completely undocumented) it
> > results in an extremely useful and time-saving error message.
>
> It's not a lot better to me, because it's inconsistent. If, as you
> propose, it should work one way in some cases (the person honors the
> interface) and not in others (they don't), then you're right back
> where you started!

That's just how Ruby is, though. When you get an object, you never know what
you're going to get with it. It's completely open-ended. This is just one
way to clear the air. In exceptional cases like half-implemented interfaces,
you're going to get the same old errors you always got. My feeling is, the
higher the quality of object you have, the better your errors. If you are
inheriting from a well-developed class, it will implement the interface
fully. If you inherited from a class that was written by a guy who had to
take a CompSci class on this way to earning an agricultural degree, you're
probably going to see the old Ruby error you get when you pass a method an
unsuitable object.

> Consider:
>
> Library A asks for interface "foo".
> Library B does trickery to pretend to provide it, but only sorta
> does so.
> Programmer C uses Library B, only *oops* Library B forgot to
> implement one method that A needs, so hey, we're right
> back to status quo.

Perhaps comment in the RCR that you don't think interfaces should carry
through inheritance. I feel they should.

> Only it's worse, because now Programmer C sees that B promised to
> implement interface 'foo', and now she has to figure out where
> interface 'foo' is defined (probably in Library D, which she may not
> even have installed) and is even more confused than before. And I
> speak as someone who is continually irritated by having to troll
> through, say, cgi.rb or dbi.rb to discover there's a method that does
> what I want it to.

How does Ruby work right now? Better than that?

> Honestly, I think 90% of what bugs me about Ruby library interfaces
> would be fixed if RDoc would dump formatted data somewhere useful, the
> way perldoc does. That way, you just type 'man <class>' or at least
> 'rdoc <class>' (or whatever, I'm not trying to suggest a specific
> implementation here), and the class' requirements are there for all to
> see. This works well for Perl modules, and I think it'd work equally
> well for Ruby.

But extensions written in C would be tricky. I don't think just fixing the
documentation mechanism is all there is to this. To me, the issue isn't
precise documentation as much as just getting a heads up most of the time
when I've bad an unsuitable object to a method.

Sean O'Dell


Eric Schwartz

unread,
Nov 19, 2003, 7:16:06 PM11/19/03
to
"Sean O'Dell" <se...@celsoft.com> writes:
> On Wednesday 19 November 2003 03:57 pm, Eric Schwartz wrote:
>> It's not a lot better to me, because it's inconsistent. If, as you
>> propose, it should work one way in some cases (the person honors the
>> interface) and not in others (they don't), then you're right back
>> where you started!
>
> That's just how Ruby is, though. When you get an object, you never
> know what you're going to get with it.

Exactly! And if you sorta-promise something, and you only
sorta-deliver on it, you get more confused than if you *know* you're
promised nothing.

> It's completely open-ended. This is just one way to clear the air.

But it doesn't clear the air, it only pretends to, and only in some
cases.

> In exceptional cases like
> half-implemented interfaces, you're going to get the same old errors
> you always got.

But with Ruby, it's not exceptional to only half-implement interfaces.
In fact, it's probably the default-- with duck typing, you only
implement enough to do the job. I haven't seen enough other code to
know for sure, but I think you're being biased by your C++/Java
background to expect complete interface implementations more often
than no.

>> Only it's worse, because now Programmer C sees that B promised to
>> implement interface 'foo', and now she has to figure out where
>> interface 'foo' is defined (probably in Library D, which she may not
>> even have installed) and is even more confused than before. And I
>> speak as someone who is continually irritated by having to troll
>> through, say, cgi.rb or dbi.rb to discover there's a method that does
>> what I want it to.
>
> How does Ruby work right now? Better than that?

Yes, because at least right now Programmer C won't waste all that time
trying to figure out what 'foo' is, whether or not Library B
implemented all of it, and whether that's even relevant to the problem
at hand. She'll dive right into library C's code and check it out,
which will save her much more time getting to the right answer.

>> Honestly, I think 90% of what bugs me about Ruby library interfaces
>> would be fixed if RDoc would dump formatted data somewhere useful, the
>> way perldoc does. That way, you just type 'man <class>' or at least
>> 'rdoc <class>' (or whatever, I'm not trying to suggest a specific
>> implementation here), and the class' requirements are there for all to
>> see. This works well for Perl modules, and I think it'd work equally
>> well for Ruby.
>
> But extensions written in C would be tricky.

They're not tricky in Perl right now, and they're used all the time.
Writing structured documentation isn't hard, and in fact, Perl
libraries have some of the best documentation I've found, regardless
of the languages they're written in.

> I don't think just fixing the
> documentation mechanism is all there is to this. To me, the issue isn't
> precise documentation as much as just getting a heads up most of the time
> when I've bad an unsuitable object to a method.

If I get an error in a call to a library, be it C, Java, Perl, or
Ruby, the first thing I do is look up where in my code it happened,
and then check the documentation of the method or class I'm using at
that point, and see if it documents what the problem is. Currently,
this is harder in Ruby than it needs to be, but when that's fixed,
there will be a relatively brief period of time where documentation
patches will be flying around left and right, and then it'll be a
doddle.

What you're asking for (currently) misses the spirit and attitude of
the language, so it's not surprising that people are reacting badly to
it. You might just as well head over to comp.lang.python and tell
them that any sensible language wouldn't require significant
indentation, and create a PCR (or whatever it's called) to "fix" that.

Austin Ziegler

unread,
Nov 19, 2003, 7:21:25 PM11/19/03
to
On Thu, 20 Nov 2003 06:32:00 +0900, Sean O'Dell wrote:
> On Wednesday 19 November 2003 01:25 pm, Austin Ziegler wrote:
>> Since Bob is a smart programmer, he'll see in his error log:
>>
>> NoMethodError: undefined method `accept' for #<File:3> from ...
>>
>> Well, this means that his File object doesn't know the method
>> #accept. Therefore, he can open the source to your HTTP library
>> and see "oh! this guy's expecting a Socket and has put accept in
>> the wrong place!" If Bob's a really smart programmer, he'd
>> already know that #accept is a Socket method.
> Wrong! There's no mention of the Socket object anywhere! The only
> way he would know that is by searching the source code of OTHER
> METHODS that call that method, then tracing back to where the
> object that is passed in was created. Then he can see Socket.new.

Not really. Since Ruby is open source, he can add a quick debug
print:

def foo(arg)
$STDERR.puts arg.inspect
:
:
end

He runs the library normally and he'll see that the incoming
argument is a Socket. But there's also a neat

The other point that I'll make is that I've had to deal with very
similar debugging mechanisms in C, C++, and PL/SQL.

> Also, don't make the assumption that the developer automatically
> knows #accept belongs to the Socket object. Your familiarity with
> Socket is causing you to discount the pain a developer feels when
> this sort of error occurs. A developer may know NOTHING about the
> Socket object and will not have a CLUE about #accept.

I'm actually not that familiar with Socket at all. I just did what
any Ruby developer can do in irb and discovered that Socket knows
about #accept.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19

* 19.21.09

Chad Fowler

unread,
Nov 19, 2003, 7:23:56 PM11/19/03
to
On Thu, 20 Nov 2003, Sean O'Dell wrote:

# On Wednesday 19 November 2003 03:57 pm, Eric Schwartz wrote:
# > "Sean O'Dell" <se...@celsoft.com> writes:
# > > It's a LOT better. For you, who knows the contract, no, it's the
# > > same thing. For a person using the library trying to pass in an
# > > unsuitable object, where the documentation is lacking (and that's
# > > MOST of the code out there, MOST code is completely undocumented) it
# > > results in an extremely useful and time-saving error message.
# >
# > It's not a lot better to me, because it's inconsistent. If, as you
# > propose, it should work one way in some cases (the person honors the
# > interface) and not in others (they don't), then you're right back
# > where you started!
#
# That's just how Ruby is, though. When you get an object, you never know what
# you're going to get with it. It's completely open-ended. This is just one
# way to clear the air.

But what Eric is correctly saying is that this doesn't clear the air. It
pollutes it with potential lies.

To Glenn Vanderburg's point, objective-c does interface checking in a way
that actually checks the interface--by grouping selectors into something
called an interface and then creating code that requires that the
*selectors are implemented*. This "interface Blah" idea you've proposed
isn't any better than checking for class, which I believe 99.9+% of us
believe does *not* guarantee an interface at all.

Classes and modules are convenient groupings of behaviors. They are
neither declarations nor contracts that guarantee that such behaviors will
persist in the objects that inherit from/include them.

#

# > Only it's worse, because now Programmer C sees that B promised to
# > implement interface 'foo', and now she has to figure out where
# > interface 'foo' is defined (probably in Library D, which she may not
# > even have installed) and is even more confused than before. And I
# > speak as someone who is continually irritated by having to troll
# > through, say, cgi.rb or dbi.rb to discover there's a method that does
# > what I want it to.
#
# How does Ruby work right now? Better than that?

Yes. Because objects don't lie about what their capabilities are. They
either respond_to? or they don't. class, module, or your "interface" have
nothing to do with the "contract" of the object.

Sean O'Dell

unread,
Nov 19, 2003, 8:05:46 PM11/19/03
to
On Wednesday 19 November 2003 04:21 pm, Austin Ziegler wrote:
> On Thu, 20 Nov 2003 06:32:00 +0900, Sean O'Dell wrote:
> > On Wednesday 19 November 2003 01:25 pm, Austin Ziegler wrote:
> >> Since Bob is a smart programmer, he'll see in his error log:
> >>
> >> NoMethodError: undefined method `accept' for #<File:3> from ...
> >>
> >> Well, this means that his File object doesn't know the method
> >> #accept. Therefore, he can open the source to your HTTP library
> >> and see "oh! this guy's expecting a Socket and has put accept in
> >> the wrong place!" If Bob's a really smart programmer, he'd
> >> already know that #accept is a Socket method.
> >
> > Wrong! There's no mention of the Socket object anywhere! The only
> > way he would know that is by searching the source code of OTHER
> > METHODS that call that method, then tracing back to where the
> > object that is passed in was created. Then he can see Socket.new.
>
> Not really. Since Ruby is open source, he can add a quick debug
> print:
>
> def foo(arg)
> $STDERR.puts arg.inspect
>
>
> end
>
> He runs the library normally and he'll see that the incoming
> argument is a Socket. But there's also a neat

Not if it was installed as root and he's not root.

> The other point that I'll make is that I've had to deal with very
> similar debugging mechanisms in C, C++, and PL/SQL.
>
> > Also, don't make the assumption that the developer automatically
> > knows #accept belongs to the Socket object. Your familiarity with
> > Socket is causing you to discount the pain a developer feels when
> > this sort of error occurs. A developer may know NOTHING about the
> > Socket object and will not have a CLUE about #accept.
>
> I'm actually not that familiar with Socket at all. I just did what
> any Ruby developer can do in irb and discovered that Socket knows
> about #accept.

How did you do that without knowing it was Socket to begin with? Armed only
with the knowledge that the error was a call to #accept, how did you deduce
it was the Socket object the method expected?

Sean O'Dell

Sean O'Dell

unread,
Nov 19, 2003, 8:17:36 PM11/19/03
to
On Wednesday 19 November 2003 04:22 pm, Eric Schwartz wrote:
> "Sean O'Dell" <se...@celsoft.com> writes:
> > On Wednesday 19 November 2003 03:57 pm, Eric Schwartz wrote:
> >> It's not a lot better to me, because it's inconsistent. If, as you
> >> propose, it should work one way in some cases (the person honors the
> >> interface) and not in others (they don't), then you're right back
> >> where you started!
> >
> > That's just how Ruby is, though. When you get an object, you never
> > know what you're going to get with it.
>
> Exactly! And if you sorta-promise something, and you only
> sorta-deliver on it, you get more confused than if you *know* you're
> promised nothing.
>
> > It's completely open-ended. This is just one way to clear the air.
>
> But it doesn't clear the air, it only pretends to, and only in some
> cases.

But, as with Ruby's dynamic typing, that's good enough. Having strong typing
wasn't the boom everyone thought it was. Ruby's success is proof of that.
It follows then that an interface declaration system would work the same way.
It would just fine, and in those instances where it doesn't, they're
exceptions and the developer will just have to deal with it the way we deal
with dynamic typing issues now. The interface declaration system is just
another way to help them, it's not a guarantee of perfection.

> > In exceptional cases like
> > half-implemented interfaces, you're going to get the same old errors
> > you always got.
>
> But with Ruby, it's not exceptional to only half-implement interfaces.
> In fact, it's probably the default-- with duck typing, you only
> implement enough to do the job. I haven't seen enough other code to
> know for sure, but I think you're being biased by your C++/Java
> background to expect complete interface implementations more often
> than no.

This is why I feel the worry over half-implemented interfaces is unfounded.
This isn't a static typing system, it's just a declaration system.

> >> Only it's worse, because now Programmer C sees that B promised to
> >> implement interface 'foo', and now she has to figure out where
> >> interface 'foo' is defined (probably in Library D, which she may not
> >> even have installed) and is even more confused than before. And I
> >> speak as someone who is continually irritated by having to troll
> >> through, say, cgi.rb or dbi.rb to discover there's a method that does
> >> what I want it to.
> >
> > How does Ruby work right now? Better than that?
>
> Yes, because at least right now Programmer C won't waste all that time
> trying to figure out what 'foo' is, whether or not Library B
> implemented all of it, and whether that's even relevant to the problem
> at hand. She'll dive right into library C's code and check it out,
> which will save her much more time getting to the right answer.

To you, it's easier to dig around in someone else's code than simply read an
error message? I guess I'm a bit out of touch with that method of
development. To me, digging around in the source code comes only when I
don't understand what the error message is telling me.

> What you're asking for (currently) misses the spirit and attitude of
> the language, so it's not surprising that people are reacting badly to
> it. You might just as well head over to comp.lang.python and tell
> them that any sensible language wouldn't require significant
> indentation, and create a PCR (or whatever it's called) to "fix" that.

What I think is that so many people have expounded for so long on dynamic
typing that it's hard to admit that perhaps there's a benefit to something
resembling type checking. Apparently there is too much invested in dynamic
typing to compromise.

I give up here, if that's the case. I never close my mind to anything, and it
seems that most people here are simply closed to the idea of anything
resembling type checking.

Sean O'Dell

Mark Wilson

unread,
Nov 19, 2003, 9:27:32 PM11/19/03
to

On Nov 19, 2003, at 4:16 PM, Sean O'Dell wrote:

> [snip]

> You said the following:
>
>> I admit type checking can gain you something, at the cost of
>> flexibility, which I don't want to pay in Ruby.
>
> You don't want to pay the price of type checking in Ruby. My version
> of it is
> really "interface checking," but either way what you said sounds like
> you've
> decided you don't want to pay the price for any of this.

While I could be wrong, my interpretation of what matz said is that he
doesn't want to pay the price _in_ Ruby. Where else might this go?
Perhaps a virtual machine, an optimizing compiler, a run time
environment?

Regards,

Mark

Michael Campbell

unread,
Nov 19, 2003, 9:54:25 PM11/19/03
to
> Well, I'm a senior developer/team leader. I have been considering
moving
> the team from "c" to ruby. However I have doubts that the
lower-level
> programmers can handle development without any type-checking
support. So
> we will probably move to either Java or c#.

What do you think you need to protect them /from/, exactly?


__________________________________
Do you Yahoo!?
Free Pop-Up Blocker - Get it now
http://companion.yahoo.com/

Michael Campbell

unread,
Nov 19, 2003, 10:01:40 PM11/19/03
to
Sean O'Dell wrote:

> That's my experience. I love Ruby, but I just don't see a large
team working
> together without at least SOME form of type checking.

Does smalltalk have it? (Genuinely asking, I was under the
assumption
it did not, but I don't know smalltalk.) I do believe there have
been
some historically large smalltalk projects in the past, no?

>>However I have noticed that I need to "read the source" far more
often
>>than with Java libraries, and correctly interpreting the source
requires
>>experience.
>
> Thank you, that was my point. It's far easier to read the method
definition
> and see the types than to dig around in code. Good for smallish
projects,
> not efficient nor safe for large team projects.

I might note here that the fact he has to read the source wasn't
attributed to the fact there were no types listed. (It might have
been, but you're presuming it was, and I see no evidence of that
based
on the quote.)

>>I would love to do a comparative experiment myself; one team with
Java
>>and one with Ruby. Just not sure the boss would fund it :-)
>
>
> This was my point, too. At least with some type checking you could
show that
> Ruby would be at least as safe as Java, but with all the freedom of
Ruby.
> It's a win-win. Hard to argue against.

You're making the presumption here that type checking can be
correlated with "safety", which I'm not sure has been shown yet.

Sean O'Dell

unread,
Nov 19, 2003, 10:06:16 PM11/19/03
to
On Wednesday 19 November 2003 07:01 pm, Michael Campbell wrote:
> Sean O'Dell wrote:
> >
> > This was my point, too. At least with some type checking you could
>
> show that
>
> > Ruby would be at least as safe as Java, but with all the freedom of
>
> Ruby.
>
> > It's a win-win. Hard to argue against.
>
> You're making the presumption here that type checking can be
> correlated with "safety", which I'm not sure has been shown yet.

It's associated with "understanding" which is usually the predicate of
"safety." Understanding what a method expects helps you to call it properly.

Sean O'Dell

T. Onoma

unread,
Nov 19, 2003, 10:09:04 PM11/19/03
to
> While I could be wrong, my interpretation of what matz said is that he
> doesn't want to pay the price _in_ Ruby. Where else might this go?
> Perhaps a virtual machine, an optimizing compiler, a run time
> environment?

which makes me wonder why euphoria's system hasn't been picked up on.
?

-t0

David Naseby

unread,
Nov 19, 2003, 10:11:20 PM11/19/03
to
>-----Original Message-----
>From: Sean O'Dell [mailto:se...@celsoft.com]
>> You're making the presumption here that type checking can be
>> correlated with "safety", which I'm not sure has been shown yet.
>
>It's associated with "understanding" which is usually the predicate of
>"safety." Understanding what a method expects helps you to
>call it properly.
>
Understanding can be accomplished through investigation (irb, unit-tests)
and documentation, in addition to, or as an alternative to, type checking.

I'd encourage library developers to work on unit tests and documentation,
which aid me as a library consumer, as opposed to ramped up guard clauses,
which just get in my way as a library consumer.

David.

Michael campbell

unread,
Nov 19, 2003, 10:15:04 PM11/19/03
to
Sean O'Dell wrote:

>>You're making the presumption here that type checking can be
>>correlated with "safety", which I'm not sure has been shown yet.
>
> It's associated with "understanding" which is usually the predicate of
> "safety." Understanding what a method expects helps you to call it properly.

How do the smalltalkers manage?

T. Onoma

unread,
Nov 19, 2003, 10:34:32 PM11/19/03
to
matz wrote:

> But still, there's no known effective way to define and check
> "interface" in a language so dynamic as Ruby. Long way to go.

i disagree. you just require the proper reflection.

-t0

Austin Ziegler

unread,
Nov 19, 2003, 10:42:49 PM11/19/03
to
On Thu, 20 Nov 2003 08:53:21 +0900, Sean O'Dell wrote:
> Why only in SOAP or RPC mechanisms? What makes them different from
> someone who calls into a library?

SOAP, for example, is meant for use by a variety of different
languages and rather expects type mechanisms, mostly because it was
first designed for languages that require static typing. I can
either build the SOAP description manually or have meta-information
available.

This is why I want an informative mechanism that's easier to use
than Ryan Pavlik's metadata module.

I don't really want a "prescriptive" mechanism -- it makes the interface
too brittle. If I wanted something like that, I think that I'd want
something like the rudimentary DbC stuff that Dave & Andy put together.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19

* 22.28.43

T. Onoma

unread,
Nov 19, 2003, 10:48:07 PM11/19/03
to
> ma...@ruby-lang.org (Yukihiro Matsumoto) wrote:
> > But still, there's no known effective way to define and check
> > "interface" in a language so dynamic as Ruby. Long way to go.
>
> I think this is fascinating stuff! Have there been any suggestions yet,
> even wild stabs at it?
>
> --
> Greg McIntyre ======[ gr...@puyo.cjb.net ]===[ http://puyo.cjb.net ]===

hellooooooo...............?

T. Onoma

unread,
Nov 19, 2003, 10:52:33 PM11/19/03
to
Simon:

> class Duck promises IBird
> ...
> end
>
> if someobj.has_promised(IBird)
> ..
> end

promises are made to be broken

Best Regards,
t0

Austin Ziegler

unread,
Nov 19, 2003, 10:56:16 PM11/19/03
to
On Thu, 20 Nov 2003 10:17:36 +0900, Sean O'Dell wrote:
> On Wednesday 19 November 2003 04:22 pm, Eric Schwartz wrote:
>> But it doesn't clear the air, it only pretends to, and only in
>> some cases.
> But, as with Ruby's dynamic typing, that's good enough. [...] It

> follows then that an interface declaration system would work the
> same way. [...]

An interface declaration system is useless unless it's used. I
frankly don't see ever using it in my libraries.

> This is why I feel the worry over half-implemented interfaces is
> unfounded. This isn't a static typing system, it's just a
> declaration system.

The same is achieved through Ruby without an unnecessary declaration
system.

> What I think is that so many people have expounded for so long on
> dynamic typing that it's hard to admit that perhaps there's a
> benefit to something resembling type checking. Apparently there is
> too much invested in dynamic typing to compromise.

Incorrect.

> I give up here, if that's the case. I never close my mind to
> anything, and it seems that most people here are simply closed to
> the idea of anything resembling type checking.

Wrong. The reasons for not thinking that your proposal is useful
have been discussed several times. It is not a value-add. If there's
going to be an interface declaration system, it should be (a) easy
to use, and (b) optionally enforce the contract. Your system doesn't
do (b) and that makes it even worse because it's got a nonzero
mental cost when the alleged promise is broken.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.19

* 22.56.08

Simon Kitching

unread,
Nov 19, 2003, 11:38:16 PM11/19/03
to
On Thu, 2003-11-20 at 16:52, T. Onoma wrote:
> Simon:
>
> > class Duck promises IBird
> > ...
> > end
> >
> > if someobj.has_promised(IBird)
> > ..
> > end
>
> promises are made to be broken

Yes, that's why I chose the word!

As Sean O'Dell has said, the point is to communicate intentions, not to
absolutely forbid people from doing things.

So I see it as acceptable for someone to write a class that "promises"
to behave like a bird, but doesn't really (or extends an existing
class). The author has made the decision. But they were immediately
*aware* that the called method expected a bird, and presumably very
carefully investigated the implications of breaking the expected
behaviour.

In Ruby you certainly should be able to bypass anything if you wish -
it's the language philosophy and wouldn't be Ruby without it.

Maybe we should be using the term "type hinting" rather than "type
checking"? That's certainly what I'm talking about, and pretty sure it
is what Sean O'Dell is talking about too. Hints to the programmer
reading the code, hints to code doing "reflection" type operations,
hints available to the runtime environment when generating error
messages. But nothing compulsory, nothing "forcibly checked" - well,
unless the user *wants* it checked.

eg (wild speculation here)

ruby foo.rb
==> just as now, no typechecking of any sort. No performance hit.
On error, the metadata about method parameters may be used to
provide improved error messages. There will be minor memory usage
increase due to the metadata stored - should be very small though.

ruby --type-warn foo.rb
==> generates warnings on possible violations, typically used during
debugging or uat phases. A performance hit of 10% or so expected and
acceptable in this situation

and maybe..

ruby --type-check foo.rb
==> strict type-checking, with errors reported on typecheck failures.
Available to those who want it, and are willing to wear the
performance hit. Some libraries may not work in this mode.

--

T. Onoma, do you actually have a concrete proposal related to type info?

The duck_signature method you mention is a syntax for consulting type
info, assuming it has somehow been gathered. I haven't seen an email by
you that suggests how that type info might have been acquired in the
first place, or how it is stored...

Cheers,

Simon

Clifford Heath

unread,
Nov 19, 2003, 11:49:13 PM11/19/03
to
Michael campbell wrote:
> How do the smalltalkers manage?

Couldn't say for sure, but I've never known a smalltalker who
worked as part of a team on a project of extended duration...
I'm sure that says something.

Simon Kitching

unread,
Nov 20, 2003, 12:08:51 AM11/20/03
to
On Thu, 2003-11-20 at 16:42, Austin Ziegler wrote:
> On Thu, 20 Nov 2003 08:53:21 +0900, Sean O'Dell wrote:
> > Why only in SOAP or RPC mechanisms? What makes them different from
> > someone who calls into a library?
>
> SOAP, for example, is meant for use by a variety of different
> languages and rather expects type mechanisms, mostly because it was
> first designed for languages that require static typing. I can
> either build the SOAP description manually or have meta-information
> available.

Plus the fact that when you're passing data rather than object
references (which is the case with any remote invocation), you need to
do one of the following:
(a)
expect exactly the same class at the other end,
(b)
serialize the class (executable code) and send it along with the data,
(c)
serialize the object's data in such a way that *equivalent* types can be
instantiated at the other end.

Option (c) is the usual approach. However this implies that you need to
know the "type" of the data, so that an equivalent can be created at the
receiving end.

Even when doing Ruby->Ruby remote invocations, I presume that type
information is required. Any of the "distributed ruby" people here care
to comment?

I presume that even things like developing Gnome components via Bonobo
(which uses ORBIT) require strictly typed interfaces, whether the
component being interacted with is remote or in-process?


> I don't really want a "prescriptive" mechanism -- it makes the interface
> too brittle. If I wanted something like that, I think that I'd want
> something like the rudimentary DbC stuff that Dave & Andy put together.

Does anyone have a URL to "the rudimentary DbC stuff"?

Cheers,

Simon


Michael Campbell

unread,
Nov 20, 2003, 12:26:39 AM11/20/03
to
Clifford Heath wrote:


About them, or you? =)

Sean O'Dell

unread,
Nov 20, 2003, 12:31:37 AM11/20/03
to
On Wednesday 19 November 2003 07:56 pm, Austin Ziegler wrote:
> On Thu, 20 Nov 2003 10:17:36 +0900, Sean O'Dell wrote:
> > On Wednesday 19 November 2003 04:22 pm, Eric Schwartz wrote:
> >> But it doesn't clear the air, it only pretends to, and only in
> >> some cases.
> >
> > But, as with Ruby's dynamic typing, that's good enough. [...] It
> > follows then that an interface declaration system would work the
> > same way. [...]
>
> An interface declaration system is useless unless it's used. I
> frankly don't see ever using it in my libraries.

Thus the optional component of the RCR.

> > This is why I feel the worry over half-implemented interfaces is
> > unfounded. This isn't a static typing system, it's just a
> > declaration system.
>
> The same is achieved through Ruby without an unnecessary declaration
> system.

No, it is not. Methods have no way of informing anyone of their needs
currently. Not without a lot of messy code.

> > What I think is that so many people have expounded for so long on
> > dynamic typing that it's hard to admit that perhaps there's a
> > benefit to something resembling type checking. Apparently there is
> > too much invested in dynamic typing to compromise.
>
> Incorrect.

No, I think I got it right.

> > I give up here, if that's the case. I never close my mind to
> > anything, and it seems that most people here are simply closed to
> > the idea of anything resembling type checking.
>
> Wrong. The reasons for not thinking that your proposal is useful
> have been discussed several times. It is not a value-add. If there's
> going to be an interface declaration system, it should be (a) easy
> to use, and (b) optionally enforce the contract. Your system doesn't
> do (b) and that makes it even worse because it's got a nonzero
> mental cost when the alleged promise is broken.

Read the RCR. It's entirely optional, and it's extremely simple. Too simple,
as someone pointed out.

Sean O'Dell

Sean O'Dell

unread,
Nov 20, 2003, 12:33:24 AM11/20/03
to

This is precisely what I am talking about. On the nose.

Sean O'Dell

Michael Campbell

unread,
Nov 20, 2003, 12:39:08 AM11/20/03
to

>>>What I think is that so many people have expounded for so long on
>>>dynamic typing that it's hard to admit that perhaps there's a
>>>benefit to something resembling type checking. Apparently there is
>>>too much invested in dynamic typing to compromise.
>>
>>Incorrect.
>
>
> No, I think I got it right.

The exact opposite might be said from someone with a largely dynamic
typing background. "What I think is that so many people have [used]
static typing for so long that it's hard to admit that perhaps
there's
a benefit to [not relying on it]. Apparently there is too much
invested in static typing to compromise."

That doesn't sound to me too far off the mark either.

Simon Kitching

unread,
Nov 20, 2003, 12:40:04 AM11/20/03
to
On Thu, 2003-11-20 at 15:54, Michael Campbell wrote:
> > Well, I'm a senior developer/team leader. I have been considering
> moving
> > the team from "c" to ruby. However I have doubts that the
> lower-level
> > programmers can handle development without any type-checking
> support. So
> > we will probably move to either Java or c#.
>
> What do you think you need to protect them /from/, exactly?

No, it's more to protect me!

It's to protect me from questions like:

"Hey, what kind of object is this method expecting? It isn't documented
anywhere and I can't understand the source code".

"Hey, I'm getting this message from the XXX library about do_foo not
existing on parameter bar. I must be doing something wrong. How do I fix
it?"

"Hey, I'm supposed to fix this library method. What parameters are
people allowed to pass to it?"

and the corollary question:

"Hey, your team isn't making much progress on this project, despite this
Ruby language you suggested. Why shouldn't I fire you?"

Michael Campbell

unread,
Nov 20, 2003, 12:54:10 AM11/20/03
to
Simon Kitching wrote:


> No, it's more to protect me!

*chuckle*

> It's to protect me from questions like:
>
> "Hey, what kind of object is this method expecting? It isn't
documented
> anywhere and I can't understand the source code".
>
> "Hey, I'm getting this message from the XXX library about do_foo
not
> existing on parameter bar. I must be doing something wrong. How do
I fix
> it?"
>
> "Hey, I'm supposed to fix this library method. What parameters are
> people allowed to pass to it?"
>
> and the corollary question:
>
> "Hey, your team isn't making much progress on this project, despite
this
> Ruby language you suggested. Why shouldn't I fire you?"


I think it would be very illustrative to turn one of these guys loose

on a project with ruby and see what you get. You might be
presupposing problems will exist where they won't... or not. Won't
know till you try it though.

In very few cases have I just not found documentation where I needed
it; I haven't had to go into src code much at all (I can't really
remember a specific time, actually), and my only consternation so far

has been what I would consider dubious design choices, not typing
issues.

Ruby is the first language I've used that has this sort of typing, so

I'm still feeling my way around a bit, but I haven't found it a
hinderance in any way. (Nor, might I add, have I found this
wonderous
freedom that's been espoused, but I don't think I'm writing idiomatic

ruby yet, either; I suspect my ruby has a decided perl or java "feel"

to it still.)

Still, I've been programming professionally for close to 20 years
now,
so I do feel I have a handle on /some/ of the basics.

David Naseby

unread,
Nov 20, 2003, 1:02:17 AM11/20/03
to
>-----Original Message-----
>From: Simon Kitching [mailto:si...@ecnetwork.co.nz]
>> What do you think you need to protect them /from/, exactly?
>
>No, it's more to protect me!
>
>It's to protect me from questions like:
>
>"Hey, what kind of object is this method expecting? It isn't documented
>anywhere and I can't understand the source code".

If the developer of the library was crap enough to leave the library
completely undocumented, what makes you think she will put in (optional)
type clauses?

>
>"Hey, I'm getting this message from the XXX library about do_foo not
>existing on parameter bar. I must be doing something wrong.
>How do I fix
>it?"

"Hey, I'm getting this message from the XXX library about parameter bar not
implementing the interface FooDoer. How do I fix it?" I really don't see
what's unclear about the exact error message, and why a more obfuscated
"interface" makes it clearer. This question is followed up with "What does
the FooDoer interface have to implement?". If the library developer was that
crap with documentation, why is the interface going to be more documented
than an exact message failure is self-documenting???

>"Hey, I'm supposed to fix this library method. What parameters are
>people allowed to pass to it?"

"Hey, this library method expects a
SomeLibrary::Interfaces::IFooUndocumented interface passed to it. What
parameters does IFooUndocumented expect?". An undocumented library is crap.
A documented library is good. This whole thread is trying and IMO failing to
suggest that type-checking, or type-verification, or something, will somehow
replace or compliment bad documentation.

>and the corollary question:
>
>"Hey, your team isn't making much progress on this project,
>despite this
>Ruby language you suggested. Why shouldn't I fire you?"
>

Can't answer this one at all :)

David.

T. Onoma

unread,
Nov 20, 2003, 1:04:29 AM11/20/03
to
Simon,

> As Sean O'Dell has said, the point is to communicate intentions, not to
> absolutely forbid people from doing things.

yes, i understood that the first time. (sorry, i just spent a couple of hours reading through hugely verbose posts that tended toward repetition)



> So I see it as acceptable for someone to write a class that "promises"
> to behave like a bird, but doesn't really (or extends an existing
> class). The author has made the decision. But they were immediately
> *aware* that the called method expected a bird, and presumably very
> carefully investigated the implications of breaking the expected
> behaviour.

you see the the problem you have with such an appraoch is perceisly that there is no quality assurance, which defeats the purpose. the real acid is in the testing. so, at best, your talking good docs here, becuase this won't buy you anything except more keystrokes.

> In Ruby you certainly should be able to bypass anything if you wish -
> it's the language philosophy and wouldn't be Ruby without it.

agreed

> Maybe we should be using the term "type hinting" rather than "type
> checking"? That's certainly what I'm talking about, and pretty sure it
> is what Sean O'Dell is talking about too. Hints to the programmer
> reading the code, hints to code doing "reflection" type operations,
> hints available to the runtime environment when generating error
> messages. But nothing compulsory, nothing "forcibly checked" - well,
> unless the user *wants* it checked.

again, docs. why have "hints" hard coded? next thing you know we'll have to have DRM in our code. ;) beyond that youre taking .kind_of?, or better, respond_to? validation code checks, which is fine as far as it goes (see euphoria below). but what ruby really needs is a real dynamic type system which requires real code reflection, as suggested by #duck_signature.

> eg (wild speculation here)
>
> ruby foo.rb
> ==> just as now, no typechecking of any sort. No performance hit.
> On error, the metadata about method parameters may be used to
> provide improved error messages. There will be minor memory usage
> increase due to the metadata stored - should be very small though.
>
> ruby --type-warn foo.rb
> ==> generates warnings on possible violations, typically used during
> debugging or uat phases. A performance hit of 10% or so expected and
> acceptable in this situation
>
> and maybe..
>
> ruby --type-check foo.rb
> ==> strict type-checking, with errors reported on typecheck failures.
> Available to those who want it, and are willing to wear the
> performance hit. Some libraries may not work in this mode.

essentially you have proposed the euphoria type system, which i think is a good system and dosen't require a whole new Edifice of Implication.

> T. Onoma, do you actually have a concrete proposal related to type info?
>
> The duck_signature method you mention is a syntax for consulting type
> info, assuming it has somehow been gathered. I haven't seen an email by
> you that suggests how that type info might have been acquired in the
> first place, or how it is stored...

the first part of how it is aquired was actually a code challenge i put out to fellow rubists, but either no one saw it or...or they just think i never have anything good to say. i don't know. not only was i trying to show what such a type system might consist of, but also demonstrate some limitation of ruby itself, that might be of interest in ruby2: b/c duck_signature CAN'T be done in pure ruby (at least not without a "reparse the_file_i_am.rb" hack) although i would love to see someone prove me wrong!

subsequently, the signiture is just arrays of arrays. once aquired it would be possbile to campare the requirements of a caller to the interface that the callee provides. some rough psuedo:

class TheUnknown
def init(x, y)
puts x.to_i
puts y + x
end
def whip(a)
puts a.whip
end
end
class MySomething
def to_i; 4; end
def whip; puts 'whipped!'; end
end
r = TheUknown.new
e = MySomething.new
r.duck_doable?(e) # => {:init=>[true, false], :whip=>[true]}

the implemenation of such a scheme would be via assessing intersection of duck_signature arrays. and of course there are plenty of other mechinisim that can be designed around the idea. even the Promises notion, but with real promises, not hints. mind you there never is such a thing as a perfect solution. what if .to_i returned a string? somewhere along the line its up to the low-level designers to implement correct/standard semantic execution, but the high-level coder should be able to tap into the "bottom rung" as a LCD for type correlation.

perhaps we can head this thing off at the pass, if you provide your prefered psudeo code for "Promises", i'll work on how duck_signature can be used to provide a corollary to it.

and thank you, thank you, thank you! for actually giving me a moment of your time.
-t0

T. Onoma

unread,
Nov 20, 2003, 1:14:03 AM11/20/03
to
Simon,

> Plus the fact that when you're passing data rather than object
> references (which is the case with any remote invocation), you need to
> do one of the following:
> (a)
> expect exactly the same class at the other end,
> (b)
> serialize the class (executable code) and send it along with the data,
> (c)
> serialize the object's data in such a way that *equivalent* types can be
> instantiated at the other end.
>
> Option (c) is the usual approach. However this implies that you need to
> know the "type" of the data, so that an equivalent can be created at the
> receiving end.
>
> Even when doing Ruby->Ruby remote invocations, I presume that type
> information is required. Any of the "distributed ruby" people here care
> to comment?

there is another way, the classes can be substantiated only on the remote end and all messages are routed to the remote object. the local "subscriber" only needs to know basic types and mechanics of invocation. so no definite type system in needed. this is extremely network intensive though.

-t0

Austin Ziegler

unread,
Nov 20, 2003, 1:19:29 AM11/20/03
to

I did. It adds no value over and above what Ruby already has and
uses. You can say that the error messages will be better, but I
disagree. How is saying that "I expect a Socket" any better than
saying "I don't know how to deal with #accept"?

And *that*, Sean, is fundamentally why I disagree with this
proposal. It doesn't add value, and it makes promises that it can't
even come close to keeping.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada

software designer * pragmatic programmer * 2003.11.20
* 01.16.12


Austin Ziegler

unread,
Nov 20, 2003, 1:22:18 AM11/20/03
to
On Thu, 20 Nov 2003 14:39:08 +0900, Michael Campbell wrote:
> The exact opposite might be said from someone with a largely
> dynamic typing background. "What I think is that so many people
> have [used] static typing for so long that it's hard to admit that
> perhaps there's a benefit to [not relying on it]. Apparently there
> is too much invested in static typing to compromise."
>
> That doesn't sound to me too far off the mark either.

What's interesting is that I haven't opposed the idea of type
introspection on methods -- I've advocated it for certain classes of
applications. I haven't even really opposed contract assurance
(e.g., Design by Contract).

I *have* opposed type checking that does neither.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20

* 01.19.59


Joel VanderWerf

unread,
Nov 20, 2003, 1:24:15 AM11/20/03
to
Michael Campbell wrote:
> Simon Kitching wrote:
>
>
>
>>No, it's more to protect me!
>
>
> *chuckle*
>
>
>>It's to protect me from questions like:
>>
>>"Hey, what kind of object is this method expecting? It isn't
>
> documented
>
>>anywhere and I can't understand the source code".
>>
>>"Hey, I'm getting this message from the XXX library about do_foo
>
> not
>
>>existing on parameter bar. I must be doing something wrong. How do
>
> I fix
>
>>it?"
>>
>>"Hey, I'm supposed to fix this library method. What parameters are
>>people allowed to pass to it?"
>>
>>and the corollary question:
>>
>>"Hey, your team isn't making much progress on this project, despite
>
> this
>
>>Ruby language you suggested. Why shouldn't I fire you?"
>
>
>
> I think it would be very illustrative to turn one of these guys loose
>
> on a project with ruby and see what you get. You might be
> presupposing problems will exist where they won't... or not. Won't
> know till you try it though.

That kind of experience would be interesting to hear about.

Another factor that might help: supposing you have a comprehensive test
suite and a test-first policy, you have another way of fielding
developer questions besides digging through source or looking at
(possibly out-of-sync) documentation: just tell your colleagues to look
at the tests.

If you consider the specification of your software to be the test suite,
then that is where you should look when you want to know "what kind of
object is this method expecting" or "what parameters...".

I've never worked with a group this way, but that's often the way it
works when I've forgotten how my own code behaves. When I'm confused, I
look at the canonical examples that are guaranteed to work because the
tests all pass. If there's not enough information there, then there
should be more tests. This is really more useful than static typing,
since it can also tell me which situations lead to which exceptions, or
other complex input-output relationships that are not explained by just
knowing input and output types.

Austin Ziegler

unread,
Nov 20, 2003, 1:27:50 AM11/20/03
to
On Thu, 20 Nov 2003 14:40:04 +0900, Simon Kitching wrote:
> On Thu, 2003-11-20 at 15:54, Michael Campbell wrote:
>> Simon Kitching wrote:
>>> Well, I'm a senior developer/team leader. I have been
>>> considering moving the team from "c" to ruby. However I have
>>> doubts that the lower-level programmers can handle development
>>> without any type-checking support. So we will probably move to
>>> either Java or c#.
>> What do you think you need to protect them /from/, exactly?
> No, it's more to protect me!

There are alternative mechanisms for doing that, though.

> It's to protect me from questions like:
>
> "Hey, what kind of object is this method expecting? It isn't
> documented anywhere and I can't understand the source code".
>
> "Hey, I'm getting this message from the XXX library about do_foo
> not existing on parameter bar. I must be doing something wrong.
> How do I fix it?"

If this is in a core or extension library, this is a problem. If,
however, it's in a library written by your team, this is a huge
problem. Some of this could be fixed by tests.

> "Hey, I'm supposed to fix this library method. What parameters are
> people allowed to pass to it?"

Where's the design document? Where's the test cases? Why isn't the
library method documented in the first place?

> and the corollary question:
> "Hey, your team isn't making much progress on this project,
> despite this Ruby language you suggested. Why shouldn't I fire
> you?"

I think that's an unnecessary fear. Honestly.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20

* 01.22.39


Austin Ziegler

unread,
Nov 20, 2003, 1:54:24 AM11/20/03
to
On Thu, 20 Nov 2003 14:08:51 +0900, Simon Kitching wrote:
> On Thu, 2003-11-20 at 16:42, Austin Ziegler wrote:
>> On Thu, 20 Nov 2003 08:53:21 +0900, Sean O'Dell wrote:
>>> Why only in SOAP or RPC mechanisms? What makes them different from
>>> someone who calls into a library?
>> SOAP, for example, is meant for use by a variety of different
>> languages and rather expects type mechanisms, mostly because it
>> was first designed for languages that require static typing. I
>> can either build the SOAP description manually or have
>> meta-information available.
> Plus the fact that when you're passing data rather than object
> references (which is the case with any remote invocation), you
> need to do one of the following: (a) expect exactly the same class
> at the other end, (b) serialize the class (executable code) and
> send it along with the data, (c) serialize the object's data in
> such a way that *equivalent* types can be instantiated at the
> other end.

You're right.

> Even when doing Ruby->Ruby remote invocations, I presume that
> type information is required. Any of the "distributed ruby" people
> here care to comment?

Drb uses Marshal#dump and Marshal#load. YAPC uses YAML which has
type markers.

>> I don't really want a "prescriptive" mechanism -- it makes the
>> interface too brittle. If I wanted something like that, I think
>> that I'd want something like the rudimentary DbC stuff that Dave
>> & Andy put together.
> Does anyone have a URL to "the rudimentary DbC stuff"?

http://www.pragmaticprogrammer.com/ruby/downloads/dbc.html

There are other discussions, too.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20

* 01.49.54


Yukihiro Matsumoto

unread,
Nov 20, 2003, 2:37:02 AM11/20/03
to
Hi,

In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)"

I didn't really get you. Could you explain what "the proper
reflection" is?

matz.


Julian Fitzell

unread,
Nov 20, 2003, 2:47:34 AM11/20/03
to

Wow! That's quite the troll! - I think I'll bite.

As a smalltalker who has been working on the same project in a team at
work for 9 months and who has been contributing to open source projects
as part of rather large distributed teams for several years, I can
assure you that the fact that you've never met any smalltalkers who have
done so reflects more on who you've met than on who is out there.

I quick scan of http://www.whysmalltalk.com/production/index.htm gives
you some idea of some of the many large scale applications deployed
using Smalltalk. These applications are used by companies like Chrysler
and FedEx as well as many large banks, insurance companies, etc. I
think we can safely assume that these applications are developed by more
than a single individual and over an extended duration.

To touch on the broader issue, I don't need a static type to know what a
method expects. My method parameter might be called aWidget, for
example which tells me it is expecting something that behaves like a
widget. Then if I need more clarification, I can look at the code
(which is probably no more than 5-10 lines - smalltalk methods are
usually that short) and see what methods are called on it. Then I know
it's expecting an object that responds to those methods. If for some
reason, it still wasn't clear, I could easily put in a comment
explaining what was expected but I can't think of a time recently where
that has been necessary.

I can't say I've ever run into cases in Smalltalk where I can't
understand what a method expects because I don't have static typing.
And I'd laugh at anyone who claims Java code (for example) is easier to
read than Smalltalk - I don't need a Javadoc equivalent in Smalltalk to
understand the code.

Julian


T. Onoma

unread,
Nov 20, 2003, 4:10:56 AM11/20/03
to
matz:

yes. there are variouz levels of reflection (or introspection). ruby has very good reflection for OO metaphor. you can examine inside objects, etc. but it has poor method reflection. you can't easily look at what a method is made of. if you recall from my RCR, as imperfect as it is, it did suggest having methods indexed as arrays of statements (atomic lambdas?) these would of course be nested by scope. anyway, that is another form of reflection.

the type system that you are seeking, suitable to the dynanicism of ruby, can only really come from the proper type of reflection. for ruby that is duck type reflection. -- being able of "ask" a method what it would do with the objects passed to it, the result is a method's duck type signature.

def whatiwould(x, y=0)
x.to_i
y.succ
y + 1
end

method(:whatiwould).duck_signature # -> [ [ 'to_i' ], [ 'succ', '+' ] ]

this tells you what methods the parameters must respond_to.

def shouldi(couldi)
if method(:whatiwould).duck_signature[0].all? {|x| couldi.respond_to?(x.intern)}
whatiwould(couldi)
else
raise "i cannot"
end
end

that's the general idea anyway. the difficulty lies in accounting for type conversions in the execution stream. but it is not insurmountable. and of course making some sugar so that it is nice.

there would be other method instrospection methods too. like array of default values, etc.

-t0

Michael Campbell

unread,
Nov 20, 2003, 9:35:17 AM11/20/03
to
Austin Ziegler wrote:


> Michael Campbell noted, if a library writer isn't going to document
> their code, what makes you think that they're going to put
interface
> validation in there?

That observation was astute, but sadly I cannot take credit; it was
someone respondonding to my devil's advocate, open-ended "what do you

want to protect them from" question.

Michael Campbell

unread,
Nov 20, 2003, 9:37:12 AM11/20/03
to
Thien Vuong wrote:

>> I don't think that it's totally useless. I do think that it's of
>> extremely limited utility.
>>
>
> Could you give me an example of what is considered a good use then?
> Given the presumption that object classification and knowledge is
bad,

Has that BEEN a given?

Chad Fowler

unread,
Nov 20, 2003, 11:58:11 AM11/20/03
to
qyyOn Thu, 20 Nov 2003, Sean O'Dell wrote:

#
# A contract is any interface, and a Ruby class is an interface. True, a Ruby
# class isn't the definition of a contract, but any OO class serves the
# function well enough. Despite Ruby's flexibility, at any given point, a
# class implements an interface. It can be extended or changed, but it
# definitely describes an interface.
#
# Because no type checking at all causes non-descriptive errors when an object
# is passed to a method (2 of 1 parameters?) which expects it to have certain
# methods which takes certain parameters. Either way, an error occurs, but
# with some form of type checking, the programmer gets a much clearer picture
# of why they can't pass in a particular object to a method without at least
# some modification.

#
# Example: you get an "object does not the :socket interface." You then say to
# yourself: "Ah! This library wants something like the Socket class...okay, I
# can fake that!"


Or how about:

blah.rb:7:in `example_method': undefined method `drive' for "car":String
(NameEr
ror)
from blah.rb:10

Is there ever a chance you wouldn't understand what that means?
Personally, I would see that message, open up blah.rb, look at line 10

Or
#
# It's just informational. It's just for the purpose of speeding up development
# and making the code a little more robust through a good report of what is
# going wrong when someone passes in an object that can't be used by the
# method. It doesn't prove that an object correctly implements an interface,
# and the object can definitely break the interface, but the facility would be
# there for programmers who can make use of it. For those that tend to break
# interfaces when programming rather than use them properly, there are always
# QA jobs. =)
#
# Sean O'Dell
#
#


Chad Fowler

unread,
Nov 20, 2003, 11:59:00 AM11/20/03
to

Excuse that last post. It was an abandoned one that ended up getting
accidentally sent.

Chad

On Thu, 20 Nov 2003, Chad Fowler wrote:

# qyyOn Thu, 20 Nov 2003, Sean O'Dell wrote:
#

# #

# # A contract is any interface, and a Ruby class is an interface. True, a Ruby

# # class isn't the definition of a contract, but any OO class serves the
# # function well enough. Despite Ruby's flexibility, at any given point, a
# # class implements an interface. It can be extended or changed, but it
# # definitely describes an interface.


# #
# # Because no type checking at all causes non-descriptive errors when an object

# # is passed to a method (2 of 1 parameters?) which expects it to have certain
# # methods which takes certain parameters. Either way, an error occurs, but
# # with some form of type checking, the programmer gets a much clearer picture
# # of why they can't pass in a particular object to a method without at least
# # some modification.
#
#
#
# #

# # Example: you get an "object does not the :socket interface." You then say to

# # yourself: "Ah! This library wants something like the Socket class...okay, I
# # can fake that!"
#
#
# Or how about:
#
# blah.rb:7:in `example_method': undefined method `drive' for "car":String
# (NameEr
# ror)
# from blah.rb:10
#
# Is there ever a chance you wouldn't understand what that means?
# Personally, I would see that message, open up blah.rb, look at line 10
#
# Or
# #

# # It's just informational. It's just for the purpose of speeding up development

# # and making the code a little more robust through a good report of what is
# # going wrong when someone passes in an object that can't be used by the
# # method. It doesn't prove that an object correctly implements an interface,
# # and the object can definitely break the interface, but the facility would be
# # there for programmers who can make use of it. For those that tend to break
# # interfaces when programming rather than use them properly, there are always
# # QA jobs. =)


# #
# # Sean O'Dell
# #

# #
#
#


Sean O'Dell

unread,
Nov 20, 2003, 12:35:05 PM11/20/03
to

Yes, because I don't know what sort of object has the #drive method. It's not
an object I am familiar with, and I don't even know what #drive is supposed
to do. An error message that like just says to me "something is very wrong,
and you don't know what."

Opening up the source and looking at the line won't necessarily tell you
anything. You could be there for awhile looking around trying to figure out
what the code does. It's not an efficient way to debug at all.

Sean O'Dell

Thien Vuong

unread,
Nov 20, 2003, 1:11:52 PM11/20/03
to

Michael Campbell wrote:
> Thien Vuong wrote:
>
>
>>>I don't think that it's totally useless. I do think that it's of
>>>extremely limited utility.
>>>
>>
>>Could you give me an example of what is considered a good use then?
>>Given the presumption that object classification and knowledge is
>
> bad,
>
> Has that BEEN a given?

Sorry I spoke (wrote) too soon. No it is not.

But every attempts to present intended/documented uses of kind_of? has
been assailed as bad. So I just wanted to see if I could solidify the
opposite arguments in concrete example.

But I got nit :) - no real answer

Thien

Michael Campbell

unread,
Nov 20, 2003, 2:07:05 PM11/20/03
to
Sean O'Dell wrote:

> No has to just do it. But when people ask for something, it gets
annoying to
> hear over and over "but why but why but why." Why is not an
appropriate
> question anymore.

It might not be appropriate to you because you seem to feel that
there
have been answers to it already.

I'm guessing here that the people that ask now either haven't
accepted
that the answers that have been given to be valid.

Austin Ziegler

unread,
Nov 20, 2003, 2:15:02 PM11/20/03
to
On Fri, 21 Nov 2003 02:35:05 +0900, Sean O'Dell wrote:
> Yes, because I don't know what sort of object has the #drive
> method. It's not an object I am familiar with, and I don't even
> know what #drive is supposed to do. An error message that like
> just says to me "something is very wrong, and you don't know
> what."

Forgive me for being boggled, Sean. That's typically the third thing
that I do (after looking to see if I've done anything stupid and
then looking in the documentation) and what I encourage developers
under my supervision to do.

> Opening up the source and looking at the line won't necessarily
> tell you anything. You could be there for awhile looking around
> trying to figure out what the code does. It's not an efficient way
> to debug at all.

Ever used RogueWave tools.h++? It's not really well documented, and
I've had to open its source more than once in my career. This is an
*expensive* commercial package. I don't know what platform you
typically develop for, but this is *common* in Unix development.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20

* 13.55.55


Sean O'Dell

unread,
Nov 20, 2003, 2:24:59 PM11/20/03
to
On Thursday 20 November 2003 11:15 am, Austin Ziegler wrote:
> On Fri, 21 Nov 2003 02:35:05 +0900, Sean O'Dell wrote:
> > Yes, because I don't know what sort of object has the #drive
> > method. It's not an object I am familiar with, and I don't even
> > know what #drive is supposed to do. An error message that like
> > just says to me "something is very wrong, and you don't know
> > what."
>
> Forgive me for being boggled, Sean. That's typically the third thing
> that I do (after looking to see if I've done anything stupid and
> then looking in the documentation) and what I encourage developers
> under my supervision to do.
>
> > Opening up the source and looking at the line won't necessarily
> > tell you anything. You could be there for awhile looking around
> > trying to figure out what the code does. It's not an efficient way
> > to debug at all.
>
> Ever used RogueWave tools.h++? It's not really well documented, and
> I've had to open its source more than once in my career. This is an
> *expensive* commercial package. I don't know what platform you
> typically develop for, but this is *common* in Unix development.

Never heard of it, but I assume it's a C++ library? Do the type declarations
help you figure it out at all? Do you open the .h files usually or go
straight to analyzing the .cpp source code itself and look right past the
function declarations?

Sean O'Dell

Sean O'Dell

unread,
Nov 20, 2003, 2:44:02 PM11/20/03
to
On Thursday 20 November 2003 11:07 am, Michael Campbell wrote:
> Sean O'Dell wrote:
> > No has to just do it. But when people ask for something, it gets
>
> annoying to
>
> > hear over and over "but why but why but why." Why is not an
>
> appropriate
>
> > question anymore.
>
> It might not be appropriate to you because you seem to feel that
> there
> have been answers to it already.
>
> I'm guessing here that the people that ask now either haven't
> accepted
> that the answers that have been given to be valid.

When people give their reasons, that's it. That's the reason. The line of
questioning tends to go like this:

Q = random programmer questioner
A = Ruby community answerer

Q: Does Ruby have type checking?

A: No.

Q: I need type checking. Will it ever have type checking?

A: Maybe, but we can't figure out how to do it right now so our official
answer is that you don't need it. If we figure it out, then your needs will
be considered valid. Why do you need type checking anyway?

Q: Because we find it helps us control our large team projects.

A: I don't agree that it helps you control your large team projects. Can you
offer more evidence?

Q: Okay. We have to look to code quite often in lieu of project documentation,
and normally we look to the description of classes, and the declarations of
function parameters to determine how to make calls and to understand how
classes are designed that are unfamiliar to some of the programmers on the
team. Type checking would help us to know what parameters are used by
certain methods at-a-glance, which saves us from having to spend time
studying source code to figure things out.

A: We always just read the source code, so that should be good enough for you.
Perhaps if you gave us another reason.

Q: Okay. When an unsuitable object is passed to a method, and that method
tries to call a method of the object that either doesn't exist or has a
different number of parameters than expected, an error occurs deep inside the
method and it's tedious figuring out how to fix what went wrong. Some form
of type checking would help us recognize our mistakes faster.

A: We always just read the source code where the error occured, unless it's a
C-extension object, so that should be good enough for you. Perhaps another
reason would convince us.

Q: Gee, alright, but I'm running out of reasons.

A: Thus you are close to realizing the friviolity of your request. If you had
a sufficient quantity of reasons, you could argue indefinitely, and therefore
win the argument. The fact that you are running out of reasons and are
leaving the discussion indicates that perhaps you don't really know what you
need. The Great Ziegler knows what you need. Or would you prefer to
continue discussing this?

Q: Huh? Okay, I think. Uhm ... well, we've been pushing to use Ruby on some
of our projects for a long time here, and the higher ups aren't crazy about
Ruby for a couple of reasons, and one of them is type checking. See, they
used to be programmers and they still know a lot about what we do, and they
also know the value of type checking, but they're not quite as willing as we
are to experiment a little. I think they may have a lot of money sunk into
the company or something. Just for the sake of argument, to promote its use,
having any form of type checking, even if it's completely circumventable,
would give us a way to assuage our superiors that Ruby would not become an
unmanagable tangle.

A: We have heard that argument before, and we will laugh at you now as we have
laughed at others before. HA HA! Don't try the pointy-haired boss argument
with us, apprentice. Away with you now! To Smalltalk or Python, we care
not! At least until we figure out how to implement some form of type
checking that we're satisfied is strict enough to crack diamonds on, then you
may return and we will gladly accept all of your arguments.

Okay, I'm just jabbing now. But in all seriousness, it really sounds like the
message around here is: "we don't want type checking, but we're trying to
figure out how to implement it, and so far we have rejected some attempts
because they were too soft for us because while we're really into no typing
at all, when we do implement type checking, it must be super-rigorous or not
at all, and until then your arguments for why you need type checking are
completely beneath contempt, although if we do ever figure out how to
implement a super-rigorous type checking system, then we'll give you what
you've been asking for."

Sean O'Dell

Austin Ziegler

unread,
Nov 20, 2003, 2:55:18 PM11/20/03
to

That you haven't heard of it strongly suggests you don't do Unix
development, but I could be wrong. (RogueWave tools.h++ has been at
two different Unix development sites that I've worked in since the
mid 90s.)

I view little difference between opening a .h file and opening a
.cpp file -- in Ruby, they're one and the same. I start with the .h
file, but move to the .cpp file as necessary.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20

* 14.46.56


Sean O'Dell

unread,
Nov 20, 2003, 3:08:39 PM11/20/03
to
On Thursday 20 November 2003 11:55 am, Austin Ziegler wrote:
> On Fri, 21 Nov 2003 04:24:59 +0900, Sean O'Dell wrote:
> > On Thursday 20 November 2003 11:15 am, Austin Ziegler wrote:
> >> Ever used RogueWave tools.h++? It's not really well documented,
> >> and I've had to open its source more than once in my career. This
> >> is an *expensive* commercial package. I don't know what platform
> >> you typically develop for, but this is *common* in Unix
> >> development.
> >
> > Never heard of it, but I assume it's a C++ library? Do the type
> > declarations help you figure it out at all? Do you open the .h
> > files usually or go straight to analyzing the .cpp source code
> > itself and look right past the function declarations?
>
> That you haven't heard of it strongly suggests you don't do Unix
> development, but I could be wrong. (RogueWave tools.h++ has been at
> two different Unix development sites that I've worked in since the
> mid 90s.)
>
> I view little difference between opening a .h file and opening a
> .cpp file -- in Ruby, they're one and the same. I start with the .h
> file, but move to the .cpp file as necessary.

No, you're correct. The only development I've done on unix was on Sun OS back
in 91 or 92 with my shell account at Netcom. I programmed in C on it, but
nothing very unixy ... no threads, no devices, etc. Just ordinary
shell-utility-type development. Commands I piped stuff to.

The .h file is very informative, and not at all the same as searching around
for Ruby methods. If it is to you, then you're that sort of person ... it
isn't even close to me.

Sean O'Dell

Austin Ziegler

unread,
Nov 20, 2003, 3:28:46 PM11/20/03
to
Okay. I'm going to respond to this and then I'm going to stop. This
is getting stupid because someone has decided to take things
personally and use strawmen and ad hominem attacks instead of reason
and logic.

On Fri, 21 Nov 2003 04:44:02 +0900, Sean O'Dell wrote:
> Q: Does Ruby have type checking?
> A: No.

Incorrect. Ruby *does* have type checking. It's not name-based type
checking or static type checking or even the ability to enforce
types in method signatures, but Ruby is a strongly, dynamically
typed language.

> Q: I need type checking. Will it ever have type checking?
> A: Maybe, but we can't figure out how to do it right now so our
> official answer is that you don't need it. If we figure it out,
> then your needs will be considered valid. Why do you need type
> checking anyway?

Incorrect. Ruby *may* provide optional signature specification in
the future. Many people are unconvinced that it's necessary.
Especially since that there's alternatives that are better (unit
testing; DbC).

> Q: Because we find it helps us control our large team projects.
> A: I don't agree that it helps you control your large team
> projects. Can you offer more evidence?

Fweeep! Foul on O'Dell! Introduction of circular argument and
misrepresentation of discussion. The question asked was *how* it
helps you control your large team projects. That question has not
been clearly answered by you, although Thien did answer it -- and he
was given what options Ruby *does* offer (not counting rdoc).

> Q: Okay. We have to look to code quite often in lieu of project
> documentation, and normally we look to the description of
> classes, and the declarations of function parameters to
> determine how to make calls and to understand how classes are
> designed that are unfamiliar to some of the programmers on the
> team. Type checking would help us to know what parameters are
> used by certain methods at-a-glance, which saves us from having
> to spend time studying source code to figure things out.
> A: We always just read the source code, so that should be good
> enough for you. Perhaps if you gave us another reason.

Again, an improper representation to both the question and the
answer. Opening a .h file is no different than opening the source.
You say you do Java as well as C++, right? There *are* no .h files,
and opening a .java file gives you the source as well. The same
applies to Ruby.

> Q: Okay. When an unsuitable object is passed to a method, and that
> method tries to call a method of the object that either doesn't
> exist or has a different number of parameters than expected, an
> error occurs deep inside the method and it's tedious figuring
> out how to fix what went wrong. Some form of type checking
> would help us recognize our mistakes faster.
> A: We always just read the source code where the error occured,
> unless it's a C-extension object, so that should be good enough
> for you. Perhaps another reason would convince us.

Third foul! Strawman on the floor. This differs not at all from the
situation from C++ or Java.

> Q: Gee, alright, but I'm running out of reasons.
> A: Thus you are close to realizing the friviolity of your request.
> If you had a sufficient quantity of reasons, you could argue
> indefinitely, and therefore win the argument. The fact that you
> are running out of reasons and are leaving the discussion
> indicates that perhaps you don't really know what you need. The
> Great Ziegler knows what you need. Or would you prefer to
> continue discussing this?

Fourth foul -- stooping to personal attacks.

I'm going to ignore the rest of your diatribe, because it's even
less reasoned than the above.

Good bye, Mr O'Dell. Continue using Ruby, or not. Don't pretend that
name checking is even remotely the same as type checking or
interface guarantee. Half-promises are worse than no promises at
all.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20

* 15.28.36

Sean O'Dell

unread,
Nov 20, 2003, 4:10:12 PM11/20/03
to

Whatever you say Ziegler.

Sean O'Dell

Yukihiro Matsumoto

unread,
Nov 20, 2003, 4:13:15 PM11/20/03
to
Hi,

In message "Re: "stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types)"
on 03/11/20, "T. Onoma" <tran...@runbox.com> writes:

|the type system that you are seeking, suitable to the dynanicism of ruby, can only really come from the proper type of reflection. for ruby that is duck type reflection. -- being able of "ask" a method what it would do with the objects passed to it, the result is a method's duck type signature.
|
| def whatiwould(x, y=0)
| x.to_i
| y.succ
| y + 1
| end
|
| method(:whatiwould).duck_signature # -> [ [ 'to_i' ], [ 'succ', '+' ] ]
|
|this tells you what methods the parameters must respond_to.

Interesting. To tell the truth, I thought it as an typing in Ruby
before. But I'm afraid this feature requires definite flow analysis,
which is nearly impossible in the language like Ruby.

def whatiwould(x, flags)
if flags
x = Regex.new(x.join("|"))
end
x.match(@str)
end
method(:whatiwould).duck_signature # -> [['join','match'], []] # no!

That's one of the reason there is no non-functional type inference
language.

matz.


Clifford Heath

unread,
Nov 20, 2003, 6:40:17 PM11/20/03
to
Julian Fitzell wrote:
> Wow! That's quite the troll! - I think I'll bite.

Sorry, it probably was a bit OTT. Interesting though that most of the
apps listed are either inhouse dev't or products sold to generate
support (customisation) revenue - like large trading apps for example.

My experience is with designing and extending large software products
(>1MLOC) over dozens of upgrade cycles and six+ years, where you gather
a large base of legacy code and entrenched design faults, with a need
for backward compatibility and migration at every release, with teams
of 10-30 engineers (not super-large, but enough that central review and
control is quite hard), most of whom have been working on the product
for less than half its life. I've done this three times now.

9 months on a project doesn't really count. Problems arise over 9 years
when you can't provide hands-on support for customer upgrades. I can't see
how I'd do that with any fully dynamic language without even optional
typing. Not Ruby, definitely not Smalltalk, though both are superlative in
some fields. That doesn't mean I'm happy with the languages I *have* used
however, I think the computer language field has a *long* way to go yet.
Wish I had time to write Rite :-) Ruby's so good, and Rite is such a good
opportunity for significant further improvement.

> If for some
> reason, it still wasn't clear, I could easily put in a comment
> explaining what was expected but I can't think of a time recently where
> that has been necessary.

That is indeed the mark of a good language - it communicates by itself
without the need for comments. However, the lack of method typing in
both R&S limit the amount of information that can be included without
adding comments, and that's a pity when so much else is right. Note that
it's only partly about what the compiler can check, it's mainly about
what the human can apprehend.

Clifford.

Julian Fitzell

unread,
Nov 20, 2003, 7:55:33 PM11/20/03
to
Clifford Heath wrote:
> Julian Fitzell wrote:
>
>> Wow! That's quite the troll! - I think I'll bite.
>
>
> Sorry, it probably was a bit OTT. Interesting though that most of the
> apps listed are either inhouse dev't or products sold to generate
> support (customisation) revenue - like large trading apps for example.

Well, I've never had a discussion about this that has changed the minds
of either party, so I'm weary of carrying on much longer and I certainly
stop short of trying to convince you - but I figure I might as well put
the counterarguments out in the open for those who may be reading.

> My experience is with designing and extending large software products
> (>1MLOC) over dozens of upgrade cycles and six+ years, where you gather
> a large base of legacy code and entrenched design faults, with a need
> for backward compatibility and migration at every release, with teams
> of 10-30 engineers (not super-large, but enough that central review and
> control is quite hard), most of whom have been working on the product
> for less than half its life. I've done this three times now.

People often say that Smalltalk is never successfully used for "large"
projects, but they usually mean "large" in the sense of code size as
opposed to large in the sense of amount of functionality. In my
opinion, no language is ever used successfully for "large" projects when
using the former definition. In my experience, writing in Smalltalk
produces code that has the same functionality as Java with a tenth of
the volume of code. Our project is an enterprise level application for
a university community of 30,000 people; many of the large smalltalk
applications out there are being used in similar environments and have
been around for more than 6 years.

This doesn't in any way prove that static typing is evil or even worse,
but the statement that "large" projects can't be done in a
non-statically-typed language is pretty flawed, in my opinion.

> 9 months on a project doesn't really count. Problems arise over 9 years
> when you can't provide hands-on support for customer upgrades. I can't see
> how I'd do that with any fully dynamic language without even optional
> typing. Not Ruby, definitely not Smalltalk, though both are superlative in
> some fields. That doesn't mean I'm happy with the languages I *have* used
> however, I think the computer language field has a *long* way to go yet.
> Wish I had time to write Rite :-) Ruby's so good, and Rite is such a good
> opportunity for significant further improvement.

I really don't understand your statement that "I can't see how I'd do
that with any fully dynamic language". That statement seems to depend
on the assumption that there is some problem with dynamic typing which
is exactly the point being debated in this thread (though not, really,
the point of my response, which was just to point out that Smalltalkers
do in fact work in teams over extended periods of time).

>> If for some reason, it still wasn't clear, I could easily put in a
>> comment explaining what was expected but I can't think of a time
>> recently where that has been necessary.
>
>
> That is indeed the mark of a good language - it communicates by itself
> without the need for comments. However, the lack of method typing in
> both R&S limit the amount of information that can be included without
> adding comments, and that's a pity when so much else is right. Note that
> it's only partly about what the compiler can check, it's mainly about
> what the human can apprehend.

Again, I don't really see how it limits the amount of information that
can be included. Is "someMethod: fooString" really any less clear a
declaration that "someMethod(String foo)" ? The difference to the human
reader seems pretty minimal. In fact, to a human reader, why would it
even matter if it had to be expressed in a comment instead of as a type?

The point of the compiler enforcement really is the crux of the matter
in my opinion. Some people like the basic security of static checking,
but it gets in your way every time you want to change a type (you have
to go change all the methods that take that as a parameter) even though
the behaviour or interface is the same. You need to spend a lot of time
up front making sure your types and interfaces are correct so you don't
have to go through making changes like that later. You have to always
worry about casting when you take objects out of an array (assuming
we're talking about Java anyway) and you can have a runtime type error
anyway if the object doesn't cast correctly.

To many of us, the increased plasticity allows us to more easily
refactor and to make the code reflect what we mean as we develop rather
than bending to the will of a compiler. This, in my opinion, leads a
cleaner system that is easier to understand, less likely to contain
bugs, and easier to find bugs in when they do occur. Others may
disagree, but this is my experience.

And I will also say (though has little more merrit than you saying you
don't know any Smalltalkers who work in teams on large projects) that
the vast majority of people I have talked to who have used dynamic and
static typing swear by dynamic typing.

Not the most compelling argument, but like I said, I'm not trying to
tell anyone else they can't use static typing. All I'm saying is:

a) I don't want to use it; and
b) I don't experience any of the problems, when using dynamic typing,
that people who like static typing say I should be experiencing.

Julian

Clifford Heath

unread,
Nov 20, 2003, 8:30:33 PM11/20/03
to
Julian Fitzell wrote:
> Well, I've never had a discussion about this that has changed the minds

I'm not the religious type, and I appreciate you taking the time to
write, and in fact I agree with a lot of what you say, including about
Java. Although I've only done smaller projects using it I agree that a
lot of things about it are windy and annoying, and lack of proper
generics makes it less type-safe than promoted. C# has most of the same
problems, but it'll be interesting to see how generics change that.

> In my opinion, no language is ever used successfully for "large" projects
> when using the former definition.

Well, that's probably a fair generalisation over the industry, but my
experience is different - all three products on which I've worked (C,
C++, C#, with Perl, Ruby, Java and horrors! VBScript in parts) are/were
large in most relevant senses, including extent and depth of maintenance
over time by a changing team. It's really the human factors that allow
or deny success in this kind of project.

> Our project is an enterprise level application for a university community
of > 30,000 people; many of the large smalltalk applications out there are
being > used in similar environments and have been around for more than 6 years.

One customer, right? Try doing that with fifty customers, all on different
old versions, all abusing the system in different ways that the designers
didn't intend, and all wanting their issues attended to without having to
take the hit for an upgrade to the most recent version.

Your comments on refactoring are well-taken, but I feel would be solved
better by better tool support in a more strongly-typed language. To safely
refactor in any language, you must be confident of limiting side effects.
A dynamic language just makes side effects will occur at runtime instead
of compile time - and if your test suite doesn't give very high code
coverage how will you know that the system can be released. Remember, you
can't just patch it after it's in production because it's not just one
local customer, it's dozens.

How often during your time on this project have you needed to quickly patch
a critical error recently introduced into production? That sort of thing is
simply impossible in our product environment, and would guarantee business
failure almost immediately.

> I really don't understand your statement...

Perhaps what I've said clarifies it a bit.

Clifford.

Austin Ziegler

unread,
Nov 21, 2003, 1:44:58 AM11/21/03
to
On Fri, 21 Nov 2003 10:33:39 +0900, Clifford Heath wrote:
> Your comments on refactoring are well-taken, but I feel would be
> solved better by better tool support in a more strongly-typed
> language. To safely refactor in any language, you must be
> confident of limiting side effects. A dynamic language just makes
> side effects will occur at runtime instead of compile time - and
> if your test suite doesn't give very high code coverage how will
> you know that the system can be released. Remember, you can't just
> patch it after it's in production because it's not just one local
> customer, it's dozens.

Um. Sorry, but type signatures don't promise you that side effects
are limited to compile-time. Only testing will do that. Which brings
you right back to the advantages of dynamic languages as opposed to
static type signatures.

-austin
--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada

software designer * pragmatic programmer * 2003.11.21
* 01.43.11


Clifford Heath

unread,
Nov 21, 2003, 3:09:17 AM11/21/03
to
Austin Ziegler wrote:
> Um. Sorry, but type signatures don't promise you that side effects
> are limited to compile-time.

That's true, but they help by catching some cases. Said cases are
more likely to occur in some programs and human environments than
others. Whether Ruby should be used in environments where these
errors are common and avoidable seems to be the main bone of contention.
Optional typing (whether static, dynamic, or some combination) would
increase the range of purposes for which Ruby is suitable. You might
not want that, but I do.

> Which brings you right back to the advantages of dynamic languages
> as opposed to static type signatures.

No it doesn't. It leaves you with no guarantee, but more confidence.
But there are no guarentees anyhow - even if the software works as
designed, nothing says it meets the user's need. Nothing's certain in
life, instead we must live within certain confidence levels. Static
typing can improve confidence levels. So can thorough testing.
Nothing about the absence of static typing can yield these particular
improvements - though individual languages may have (mostly) unrelated
other features which do, including reduced verbosity.

Clifford.

Austin Ziegler

unread,
Nov 21, 2003, 9:21:47 AM11/21/03
to
On Fri, 21 Nov 2003 17:13:36 +0900, Clifford Heath wrote:
> Austin Ziegler wrote:
>> Um. Sorry, but type signatures don't promise you that side
>> effects are limited to compile-time.
> That's true, but they help by catching some cases.

I don't find that they catch *useful* cases, but rather cases where
work had to be done to accommodate the static typing system in the
first place.

> Said cases are more likely to occur in some programs and human
> environments than others.

I would agree, but I think that our definitions for such programs
and environments are radically different. Mine would be the
"absolutely must never fail" embedded code for heart monitors and
such. Typical business apps are *not* those environments. There are
good reasons for thinking this, too, that I'll describe below.

> Whether Ruby should be used in environments where these errors are
> common and avoidable seems to be the main bone of contention.
> Optional typing (whether static, dynamic, or some combination)
> would increase the range of purposes for which Ruby is suitable.
> You might not want that, but I do.

Frankly, Ruby is already suitable to those non-"absolutely must
never fail" environments. What's not happening is that people aren't
feeling comfortable with their own developers' capabilities -- and,
I think, are underestimating them. Question: what is the purpose of
software in a business environment? Answer: serving business
purposes. Question: how much C++ or Java code actually *serves*
business purposes? Answer: It depends...

The situation is somewhat better now in C++ than it used to be (with
the STL), but I know that significant portions of the production-
level C++ code that I've worked with and on that deal with memory
management and other overhead details. In some cases, as much as
*half* of the code was needed for wrangling with the language. In
Java, it's even worse, especially if you're using J2EE. There's a
book that advocates using Ruby for those environments where
management has been convinced to use J2EE or .NET that covers this
50 - 75% overhead code: _Code Generation in Action_.

What if your developers could write directly to the business
requirements without having to worry about language overhead? With
Ruby -- and other strongly-typed dynamic languages -- they can. Joel
Spolsky (www.joelonsoftware.com) wrote CityDesk, a desktop-based
content management system, in Visual Basic with Visual C++
performing necessary performance improvements or other things that
can't be done in VB. It's easily one of the best -- and most
responsive -- programs I've ever used on Windows.

He did this because in VB he was able to write closer to his
business requirements without having to deal with the overhead (both
mental and codewise) of C++. Joel's a bright man. I think that his
lesson learned in this is *generally applicable* and is applicable
to Ruby's situation as well.

>> Which brings you right back to the advantages of dynamic
>> languages as opposed to static type signatures.
> No it doesn't. It leaves you with no guarantee, but more
> confidence.

Often it's false confidence, Clifford. If static typing actually
gave you anything of value, people wouldn't have to resort to tricks
like (void *). As Bruce Eckels pointed out in the article I found
earlier[1], when he tried some stuff in Python, he found that he no
longer had to upcast. His class hierarchy was made simpler.

Note that strongly and explicitly typed languages like Ada aren't
actually as frustrating as C++, because they make you think about
how your types are used, rather than sometimes doing things
implicittly.

> But there are no guarentees anyhow - even if the software works as
> designed, nothing says it meets the user's need.

Again, I think that if we consider how much code is framework code
in C, C++, and Java, all of the supposed advantages of statically
typed languages disappear under the productivity killing crush.

> Nothing's certain in life, instead we must live within certain
> confidence levels. Static typing can improve confidence levels. So
> can thorough testing. Nothing about the absence of static typing
> can yield these particular improvements - though individual
> languages may have (mostly) unrelated other features which do,
> including reduced verbosity.

I'm not the only one who thinks that dynamically typed languages are
at least as suitable as statically typed languages for business
applications:

http://www.osteele.com/archives/2003/08/test_versus_type.html

As Oliver Steele points out, the productivity boost *has been shown
in research*!

-austin
[1] http://www.mindview.net/WebLog/log-0025


--
austin ziegler * aus...@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.21

* 09.21.33

It is loading more messages.
0 new messages