"stereotyping" (was: Re: Strong Typing (Re: Managing metadata about attribute types) )<Pine.LNX.4.44.0311171402340.1133-100000@ool-4355dfae.dyn.optonline.net> <Pine.LNX.4.44.0311181524130.2236-100000@ool-4355dfae.dyn.optonline.net>

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

···

On Fri, 21 Nov 2003 02:35:05 +0900, Sean O’Dell wrote:

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

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

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.

Hi,

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

On Wednesday 19 November 2003 12:47 pm, Yukihiro Matsumoto wrote:

In message “Re: “stereotyping” (was: Re: Strong Typing (Re: Managing > metadata about attribute types)” > > on 03/11/20, “Sean O’Dell” sean@celsoft.com writes:

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

On Wednesday 19 November 2003 01:10 pm, Austin Ziegler wrote:

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.

Funny you should mention that. =)

Sean O'Dell
···

On Wednesday 19 November 2003 01:33 pm, Gavin Sinclair wrote:

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

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

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

Sean O'Dell
···

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.

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

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.

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,

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.

···

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

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.

Hi,

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

In message “Re: “stereotyping” (was: Re: Strong Typing (Re: Managing metadata about attribute types)” on 03/11/20, “Sean O’Dell” sean@celsoft.com writes:

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

···

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.

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

···

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?


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

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

···

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?


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

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

On Wednesday 19 November 2003 12:42 pm, Maik Schmidt 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
···

On Wednesday 19 November 2003 01:01 pm, Chad Fowler wrote:

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

Hi,

···

In message “Re: “stereotyping” (was: Re: Strong Typing (Re: Managing metadata about attribute types)” on 03/11/20, Chad Fowler chad@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.

Hi,

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

On Wednesday 19 November 2003 01:38 pm, Yukihiro Matsumoto wrote:

In message “Re: “stereotyping” (was: Re: Strong Typing (Re: Managing > metadata about attribute types)” > > on 03/11/20, “Sean O’Dell” sean@celsoft.com writes:

matz@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 ======[ greg@puyo.cjb.net ]===[ http://puyo.cjb.net ]===

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

···

On Thu, 2003-11-20 at 16:42, Austin Ziegler wrote:

On Thu, 20 Nov 2003 08:53:21 +0900, Sean O’Dell wrote:

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

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.