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

In summary, “interface checking” (not static type checking we had seen

before) is a good thing. But I’m not sure it’s good enough to put in

the future Ruby, where API document might help, and where we have two

challenges above.

matz, how do you define “interface”? In sean’s case, class and/or module
were sufficient to define interface. This is majorly what I take issue
with. If “interface” is really a collection of “respond_to?”
requirements, then I can start to stomach the idea of it being added to
Ruby (I believe you were proposing something similar in your RubyConf
presentation). Have a look at Sean’s RCR at RubyGarden. It includes the
following:

No, class/module were NEVER enough. I’ve made two proposals (one RCR and post
new idea posted here), and neither of them used class/module except as a
proposed way to indicate an interface was implemented. But class and module
has nothing, at its heart, to do with it, I just put them up there to show
one way to do it. It was primarily an “interface id tagging system” and the
tags could be stuck onto objects in any fashion: by the class they came from,
by an explicit declaration, through a method call, or through some sort of
object-to-interface mapping system.

The point of the RCR was, there was no interface definition, it was just an
interface id tag system. Class and module were just one way of showing how
it could work.

Read on, and let’s skip the RCR I proposed. I see now that people want
something more fulfilling than a simple empty promise than the interface id
tagging system was providing.

class MyClass end

The above class implicity declares “I implement the MyClass interface.”
Pretty simple.

He goes on to say the same re: inheritance and module inclusion.

Do you consider these to define “interface”? I don’t.

True, my RCR did not define an interface, and by design. I was under the
impression that type checking was unwanted and so I came up with a very loose
design. It was intentional.

Read my post in this newsgroup/mailinst list titled “New Type Checking System
Idea.” This, I think, is much closer to what people are asking for.

As an aside, I am curious why you and Ziegler and several others participate
in this way. Rather than beating people up for their ideas, why don’t you
point out how they could be improved, or come up with your own ideas? I
can’t deny that no one liked my RCR, but in the process I really feel
attacked, and badly. Can’t you guys figure out some other way to export your
ideas rather than holding them private and then just swatting away anything a
person has to say on the subject? What are your ideas for something like
this? Post them up … let’s hear a proposal. I promise, I will be kinder
to you than you were to me.

Sean O'Dell
···

On Thursday 20 November 2003 02:40 pm, Chad Fowler wrote:

On Fri, 21 Nov 2003, Yukihiro Matsumoto wrote:

Hi,

matz, how do you define “interface”? In sean’s case, class and/or module
were sufficient to define interface. This is majorly what I take issue
with. If “interface” is really a collection of “respond_to?”
requirements, then I can start to stomach the idea of it being added to
Ruby (I believe you were proposing something similar in your RubyConf
presentation).

I just don’t know. Only things I can tell you now are:

  • Types (or “interfaces” to avoid confusion) must be independent
    from class/module, otherwise they will be misused too often. Note
    that Sean himself once failed to distinguish these two.

  • Thus I refuse at least part of his RCR, which use class/module to
    define interface. Interfaces should be defined explicitly.

  • I’m sure I don’t fully understand his new proposal in
    [ruby-talk:85888], but if it is statically checked at compile time
    as he explained, I wonder how much it is effective. We have many
    cases where that kind of “static interface check” would not cover,
    thus make it “false promise”. I still need to examine his
    proposal to make the final decision.

  • The appearance matters. I think the code example in the proposal
    does not look like Ruby:

    class Stdin
    def Boolean eof?
    return is-at-end-of-file
    end
    def Integer read(Integer maxbytes)
    return bytes-read
    end
    end

    I’m not sure how to design the interface syntax in the Ruby Way.

    					matz.
    
···

In message “Re: “stereotyping” (was: Re: Strong Typing (Re: Managing metadata about attribute types) )” on 03/11/21, Chad Fowler chad@chadfowler.com writes:

Because the checks are only done when methods are added to the class, which
mostly means when the class is loading. Whenever a check for interface
compliance is done, it’s really just asking an object “do you fully implement
this interface” and there are no calculations are performed. The object
either carries a compliance flag or it doesn’t. The compliance flag is
assigned as soon as the last method required by the interface is loaded.

Once a class is loaded, of course methods can be re-implemented, and objects
can also re-implement the methods, so if the class or object has an interface
requirement, the method will be checked at that time for compliance with the
interface, but after that no calculations are performed; only the compliance
flag is checked.

Sean O'Dell
···

On Thursday 20 November 2003 02:20 pm, Zach Dennis wrote:

Sean,

Actually, the new proposal only checks at compile-time, when a class which
implements an interface is loaded, and whenever methods are added to the
class.

How can this be done efficiently with Ruby’s dynamic nature at compile
time?

I’m going to go read your proposal now. =)

On Thursday 20 November 2003 02:40 pm, Chad Fowler wrote:

> On Fri, 21 Nov 2003, Yukihiro Matsumoto wrote:

>

>

> # In summary, “interface checking” (not static type checking we had seen

> # before) is a good thing. But I’m not sure it’s good enough to put in

> # the future Ruby, where API document might help, and where we have two

> # challenges above.

>

>

>

> matz, how do you define “interface”? In sean’s case, class and/or module

> were sufficient to define interface. This is majorly what I take issue

> with. If “interface” is really a collection of “respond_to?”

> requirements, then I can start to stomach the idea of it being added to

> Ruby (I believe you were proposing something similar in your RubyConf

> presentation). Have a look at Sean’s RCR at RubyGarden. It includes the

> following:

···

On Fri, 21 Nov 2003, Sean O’Dell wrote:

No, class/module were NEVER enough. I’ve made two proposals (one RCR and post

new idea posted here), and neither of them used class/module except as a

proposed way to indicate an interface was implemented. But class and module

has nothing, at its heart, to do with it, I just put them up there to show

one way to do it. It was primarily an “interface id tagging system” and the

tags could be stuck onto objects in any fashion: by the class they came from,

by an explicit declaration, through a method call, or through some sort of

object-to-interface mapping system.

The point of the RCR was, there was no interface definition, it was just an

interface id tag system. Class and module were just one way of showing how

it could work.

Read on, and let’s skip the RCR I proposed. I see now that people want

something more fulfilling than a simple empty promise than the interface id

tagging system was providing.

>

> class MyClass

> end

>

> The above class implicity declares “I implement the MyClass interface.”

> Pretty simple.

>

>

> He goes on to say the same re: inheritance and module inclusion.

>

> Do you consider these to define “interface”? I don’t.

True, my RCR did not define an interface, and by design. I was under the

impression that type checking was unwanted and so I came up with a very loose

design. It was intentional.

Read my post in this newsgroup/mailinst list titled "New Type Checking System

Idea." This, I think, is much closer to what people are asking for.

As you understand now, my problem with your old proposal was primarily
that it provided an empty promise. I feel like that would have muddied
things up for both people like me, who have come from the static typing
world and slowly understood how to work in the dynamic way, and for people
who actually want something that makes them feel safer.

Your new proposal is less ambiguous, and therefore (IMO), better. I still
don’t like it, but I’ll save the reasons for a later post.

As an aside, I am curious why you and Ziegler and several others participate

in this way. Rather than beating people up for their ideas, why don’t you

point out how they could be improved, or come up with your own ideas? I

can’t deny that no one liked my RCR, but in the process I really feel

attacked, and badly. Can’t you guys figure out some other way to export your

ideas rather than holding them private and then just swatting away anything a

person has to say on the subject? What are your ideas for something like

this? Post them up … let’s hear a proposal. I promise, I will be kinder

to you than you were to me.

I attempted to point via Glenn Vanderburg’s suggestion to Objective C.
I mentioned several times and in several ways that “respond_to?” is more
important than any kind of “kind_of?” (no pun intended), which was an
attempt at constructive criticism. It only seemed to add fuel to the
fire, unfortunately. I’m sorry we hurt your feelings. I never want
people to feel badly. But, in retrospect, you did a little swatting yourself
(and early on). (Before many of us jumped in with the tone you’re
referring to). It’s really a matter of how you choose to interpret the
tone of a message.

I don’t believe any of us have held our views in private and waited to
swat. I believe that the majority of people who come into the Ruby
community looking for this kind of functionality are fresh-out-of-Java and
looking to make Ruby fit the Java way of thought. I experienced the same
thing myself 3 years ago, when I started programming in Ruby. But, over
time I let Ruby shape my way of thinking. I was bothered by this nagging
desire to implement interfaces which are supported via “contracts” that
can be snapped together like lego bricks (hi Shashank!). But, I let
myself set that nagging feeling aside for a while and just go with the
flow. Eventually, I found that in going back to Java or C#, I was often
seriously annoyed by the typing systems these languages had to offer. And
more often than not, I find the interface checking concept to actually eat
up my productivity.

I do still construct interfaces and do things contractually when I program
in Java. But sometimes something wonderfully dynamic pops out (at least
in as much as this is possible in Java). And, I think, “Wow. I never
would have thought of that before.”

So, now about these proposals you would rather see us come up with:
my proposal is that we fully drop the type-checking idea. This is my idea
for something like this. “respond_to?” is enough. My motivation and
rationale are that we may provide so much of a crutch to new Rubyists that
they will never learn the lessons that Ruby has to teach, and they will
never program in The Ruby Way.

A somewhat happy compromise would be to create a mechanism for automating
respond_to? checking (and probably even “declaration”). But I don’t think
it should look at all like classes or modules. That would further
confuse an already confused generation of Ruby programmers (especially
those to come). I don’t know what it should look like, but that’s largely
because I don’t see a need for it, and therefore don’t sit around
imagining what it should look like. I know I don’t want Ruby to look like
this:

public class Person implements Animal
{
public static String greet(Animal a) throws IDoNotLikeYouException
{

}
}

And, your most recent proposal, while an improvement over the previous one
still comes uncomfortably close.

Anyway, I think this thread has gone on way too long * 2. It’s obviously
a topic that both new and old Rubyists get passionate over. I’m looking
forward to seeing where Matz takes it. Judging by what he said in his
RubyConf presentation, I’m sure it will be the best of both worlds.

Chad

Hi Sean,

The ruby code below illustrates some of my views on type/interface
checking. First of all I’m not that fond of interface checking using
respond_to? for several reasons. The simplest - and least debateable one -
being that it fails when any method_missing trick is used. Second, saying
that any object responding_to? the method quack means the object can quack
like a duck is stereotyping as well. If an object has this method, it
doesn’t guarantee it can quack like a duck. If an object doesn’t have this
method, it doesn’t mean it can’t quack like a duck. Of course while ruby
does provide a method to abstract an actual type from having a certain
name among the names of its ancestors, it doesn’t abstract the actual type
from having certain names among its implemented methods. This is just a
thought that’s been bugging me for a while now, mainly because of stuff
like name clashes, and the “what’s in a name” phrase (a quack sounds the
same by any other name). Recently, as I was reading up on my Haskell
knowledge, something struck me. In Haskell you can specify a number of
types, and specify a number of functions that work with this type
(although it is not an OO language, it allows for OO-like stuff, but not
the usual syntax). The types can also be encapsulated. However there is no
inheritance among types. Now this is where Haskell classes come in. They
are much like interfaces, saying that some type in that class responds to
some functions. Any type that wants to belong to a class needs to provide
an implementation for each of the functions of that class - and here’s the
cool part - without a necessary correspondence between the name of the
function in the class and the name of the function in the type. For
example a type could implement a function “doSomeQuacking”, a class could
require a function “quack”, and so one could specify that the function
"quack" from that class should really call “doSomeQuacking” on the type.
Also a type like CharlatanDuck below could belong to class Duck as well as
class Quack, both having a function quack. There’s no problem with
ambiguity since asking a CharlatanDuck to quack in its role of Duck, it
will quack like a duck, and in its role as Quack, it will quack like a
quack. BTW, remark that Haskell’s classes are truly classifications based
on functionality, which is better naming than ruby’s classes which refer
to a code vehicle. Anyway, it’s just a feature I’d personally like to see
in ruby too if type checking makes it there, but I’d make it optional too.
Note that although the type checking in Haskell is static, if you’d get
your interface checking through, something likewise could be added for
free (in terms of run time overhead) if you’d want, despite the fact that
ruby is dynamically typed. It’s just an idea that will also be shot down
because of increases in number of lines, because of limited useability and
because it’s not needed (but just for the sake of argumentation,
technically no one really needs ruby either, it’s just more convenient for
some people than other languages, or a matter of taste, principle, etc.)
As for increase in number of lines for type checking in general; if it
saves documentation because it’s self-documenting - not to mention that
the documentation is guaranteed to be consistent with the behavior - and
if it saves some checks of your own - suppose the same set of checks, or a
subset, etc. occur in several methods - and if it saves some testing, it
could be a gain, right? But that needs to be proven still…

Having used the occasion to put forth yet another stupid idea, I’ll get to
your proposal… Momentarily you can’t work the ObjectProxy below with
your technique, or anything that includes a method_missing technique. I
have no idea how to merge that into your technique since it requires
analyzing the body of the method_missing method and anything it calls,
which for one thing is an undecideable problem, but also it needs to be
redone as code changes. Maybe you should provide some way of delegating
the interface check, e.g., to $obj in the example below, but then you’d
give the programmer control and he or she can lie about what interfaces
are implemented. Personally, I find that not so much a problem because the
only effect is that it backfires on the one who lies. It is a problem if
the idea of the interface is used when interfacing with other languages,
but I guess I don’t do that often. But since your interface check is just
a check (and a cheap one :slight_smile: for the moment, I guess this is no issue
(yet). Note that you can’t simply have the ObjectProxy declare the
interfaces it implements because we don’t know what kind of object will be
behind it - it’s a matter of flexibility.

Another thing; since methods can be removed and added, maybe it’s
interesting to also be able to add or remove the notification that you
intend to implement an interface. As such, no dynamism is lost there. But
it’s an extra complication :frowning:

Last thing (unless I come up with something else before I send this mail);
you should probably also provide a way of declaring superinterfaces and
subinterfaces. Suppose someone provides an interface InputOutput which
provides methods for inputting and outputting (what else?). If some method
only uses the input part of the interface, you want to declare a
superinterface Input of InputOutput. I call it a superinterface since an
InputOutput can pass for an Input, but not the other way around. You’d
also want to declare subinterfaces, e.g., a StringInputOutput which offers
some additional functionality to InputOutput. Either you’d need to make
interfaces open, then you can just get by with declaring subinterfaces,
or otherwise you need both subinterfaces and superinterfaces. (At least
one programming language I know of can do both subclassing and
superclassing, so it’s perfectly possible). Just for all clarity, making a
superinterface to an existing interface can happen when that existing
interface is in a library and you can’t modify it (because it’s closed).
Then instead of saying in the existing interface what the superinterface
is, you’d say in the superinterface that the interface from the library is
a subinterface.

OK, head is empty now.

BTW, I really admire you for still being here after all the heat :slight_smile:

Peter

PS: To everyone: I want to make this very clear; I’m not taking a stance
here whether type checking should happen or not. But I do think it’s an
interesting experiment, whether you’d want it or not, and whether that is
for legitimate or illegitimate reasons. It’s already pretty clear who
wants it and who does not. I think it’s interesting, and only if we let
Sean work this through, we’ll find out about the true value. It’s not as
if we can change his mind anyway :slight_smile: Be like Matz and give him a chance!

···

class ObjectProxy

def initialize(obj)
$obj = obj
end

alias_method :method_missing_old, :method_missing

def method_missing(s, *args)
if $obj.respond_to?(s)
print "start of call to #{s.id2name}\n"
result = $obj.send(s, *args)
print "end of call to #{s.id2name}\n"
result
else
method_missing_old(s, args)
end
end

end

class Duck

def quack
print "quack quack!!!\n"
end

end

class DuckTapedDuck

def doSomeQuacking
print "quack quack!!!\n"
end

end

class Quack

def quack
print "quack potion!!! quack pills!!! all very cheap, works better
than the real stuff!\n"
end

end

class CharlatanDuck

def quack
print "want me to quack like a duck, or quack like a quack?\n"
end

end

p Duck.new.respond_to?(:quack)
Duck.new.quack # a duck can quack like a duck
p Quack.new.respond_to?(:quack)
Quack.new.quack # a quack can quack like a quack, but can’t quack as a duck
p CharlatanDuck.new.respond_to?(:quack)
CharlatanDuck.new.quack # ambiguous request
p DuckTapedDuck.new.respond_to?(:quack)
DuckTapedDuck.new.doSomeQuacking # and still I can quack like a duck
p ObjectProxy.new(Duck.new).respond_to?(:quack)
ObjectProxy.new(Duck.new).quack # and still I can quack like a duck
p ObjectProxy.new(Duck.new).respond_to?(:doSomeQuacking)
ObjectProxy.new(Duck.new).doSomeQuacking # fails, this time rightly so

Hi,

matz, how do you define “interface”? In sean’s case, class and/or module
were sufficient to define interface. This is majorly what I take issue
with. If “interface” is really a collection of “respond_to?”
requirements, then I can start to stomach the idea of it being added to
Ruby (I believe you were proposing something similar in your RubyConf
presentation).

I just don’t know. Only things I can tell you now are:

  • Types (or “interfaces” to avoid confusion) must be independent
    from class/module, otherwise they will be misused too often. Note
    that Sean himself once failed to distinguish these two.

I agree, but since classes and interfaces are often synonymous, there could,
possibly, be an alternative mechanism to describing interfaces that used
class definition in some way.

  • I’m sure I don’t fully understand his new proposal in
    [ruby-talk:85888], but if it is statically checked at compile time
    as he explained, I wonder how much it is effective. We have many
    cases where that kind of “static interface check” would not cover,
    thus make it “false promise”. I still need to examine his
    proposal to make the final decision.

Please ask me questions. I’m terrible about making my own new ideas known
because I don’t anticipate how clearly they will be received.

The way “false promise” was used before, a class could say “I implement this
interface” and then NOT implement it, making the statement a lie. In my new
proposal, there is no way to make that statement. If a class declares “I
implement this interface” it is marked as “incomplete” and the declaration is
essentially hidden until the last method fulfills the interface requirement.
The class makes the statement, but that is basically ignored until
fulfillment is complete, and then the class can generate objects which
contain a flag for that interface.

  • The appearance matters. I think the code example in the proposal
    does not look like Ruby:

    class Stdin
    def Boolean eof?
    return is-at-end-of-file
    end
    def Integer read(Integer maxbytes)
    return bytes-read
    end
    end

    I’m not sure how to design the interface syntax in the Ruby Way.

That was just an example, I threw that in quickly. Perhaps the interface
requirements would appear in the interface definition, but they would not be
repeated when the class actually defined the method.

Sean O'Dell
···

On Thursday 20 November 2003 06:47 pm, Yukihiro Matsumoto wrote:

In message “Re: “stereotyping” (was: Re: Strong Typing (Re: Managing > metadata about attribute types) )” > > on 03/11/21, Chad Fowler chad@chadfowler.com writes:

As you understand now, my problem with your old proposal was primarily
that it provided an empty promise. I feel like that would have muddied
things up for both people like me, who have come from the static typing
world and slowly understood how to work in the dynamic way, and for people
who actually want something that makes them feel safer.

There are ways to demonstrate that while maintaining an air of dignity in
participation. Let’s drop it though. I think just by mentioning it, things
have straightened out a bit, so let’s just work civilly on this. If anyone
chooses to play rough from here on out, let them be noted and ignored.

Your new proposal is less ambiguous, and therefore (IMO), better. I still
don’t like it, but I’ll save the reasons for a later post.

I look forward to your comments in more detail.

I attempted to point via Glenn Vanderburg’s suggestion to Objective C.
I mentioned several times and in several ways that “respond_to?” is more
important than any kind of “kind_of?” (no pun intended), which was an
attempt at constructive criticism. It only seemed to add fuel to the
fire, unfortunately. I’m sorry we hurt your feelings. I never want
people to feel badly. But, in retrospect, you did a little swatting
yourself (and early on). (Before many of us jumped in with the tone you’re
referring to). It’s really a matter of how you choose to interpret the
tone of a message.

I didn’t see this as a proposal or a refinement of one, but perhaps there is
something to what you’re saying.

Looking at respond_to? over kind_of?, I agree, when there is nothing better.
respond_to? tells you that something exists, which says something far more
definite than kind_of? really does (although you can make assumptions).

But there’s more you COULD know, and it in the end what we get will probably
appear more like kind_of? than respond_to?. An interface is very closely
related to a class, and the test for whether or not an object implements an
interface will probably be something like implements?, which is a broad
statement about an objects abilities, much like kind_of? causes people to
make broad assumptions about object abilities.

Interfaces are described in a similar way to classes, and quite often, in
practice, classes and interfaces end up being synonymous. One without the
other is an exception rather than the rule, at least. So while I agree that
respond_to? is more informative than kind_of?, in the end, a good interface
query system is going to look a heck of a lot like kind_of?

I don’t believe any of us have held our views in private and waited to
swat. I believe that the majority of people who come into the Ruby
community looking for this kind of functionality are fresh-out-of-Java and
looking to make Ruby fit the Java way of thought. I experienced the same
thing myself 3 years ago, when I started programming in Ruby. But, over
time I let Ruby shape my way of thinking. I was bothered by this nagging
desire to implement interfaces which are supported via “contracts” that
can be snapped together like lego bricks (hi Shashank!). But, I let
myself set that nagging feeling aside for a while and just go with the
flow. Eventually, I found that in going back to Java or C#, I was often
seriously annoyed by the typing systems these languages had to offer. And
more often than not, I find the interface checking concept to actually eat
up my productivity.

Here’s where we agree. I think Java’s use of interfaces is a waste of time in
MANY places, but not every place. The right tool for the right job. I hate
that Java won’t let me just do stuff. I hate that Ruby won’t let me enforce
types. Why? Because in both cases, I’m not given much of a choice.

I do still construct interfaces and do things contractually when I program
in Java. But sometimes something wonderfully dynamic pops out (at least
in as much as this is possible in Java). And, I think, “Wow. I never
would have thought of that before.”

Me too! But instead of switching languages, what if you could develop
something in Ruby like usual, then as a project started to get larger and
more complicated, or as people were added to the project who might not fully
understand all your classes, wouldn’t it be nice to say “okay kids, before
you go muddying up this project, here’s a couple rules for you. never pass
anything but this type here. and this type here.” So except for the places
where you think you ought to provide a little guidance, leave the rest of it
wide open as usual.

A somewhat happy compromise would be to create a mechanism for automating
respond_to? checking (and probably even “declaration”). But I don’t think
it should look at all like classes or modules. That would further
confuse an already confused generation of Ruby programmers (especially
those to come). I don’t know what it should look like, but that’s largely
because I don’t see a need for it, and therefore don’t sit around
imagining what it should look like. I know I don’t want Ruby to look like
this:

public class Person implements Animal
{
public static String greet(Animal a) throws IDoNotLikeYouException
{

}
}

And, your most recent proposal, while an improvement over the previous one
still comes uncomfortably close.

The problem I have with automating respond_to? is it sounds like something
that would happen constantly at runtime when type checking was needed. That
places more burden on the engine than I think people would be happy with. I
personally wouldn’t be thrilled with all that activity at each call to a
method with type requirements.

In my last proposal, you can ignore it and develop like usual, or you can get
REALLY STRICT like Java and go nuts with it, or you can just sort of apply it
here and there as needed.

I think at first, something like this would look scary but I think after
awhile a pattern of usage would settle in and people would find what’s
comfortable.

Anyway, I think this thread has gone on way too long * 2. It’s obviously
a topic that both new and old Rubyists get passionate over. I’m looking
forward to seeing where Matz takes it. Judging by what he said in his
RubyConf presentation, I’m sure it will be the best of both worlds.

To me, it’s only recently that I’ve had any epiphanies about how it might
work, so it’s still a pretty new discussion to me. I still want to hammer
out some ideas, because I really think there could be a win-win way to do
this.

Sean O'Dell
···

On Thursday 20 November 2003 03:41 pm, Chad Fowler wrote:

[…highly informative paragraph removed for brevity…]

I am not sure exactly how Haskell works, but it sounds like perhaps
fulfillment could occur through a form of aliasing, although calls could
still be made to the method required by its original name. Calls doing that
would actually route through the aliased method. Since this only involves
the interface mechanism, and would be just another method to Ruby, this could
work, sure.

It could look like:

class AnyClass
def method(parameters) implements someothermethod
end

… which would allow someothermethod to be fulfilled in the interface
requirement, but the method would actually be called method. You could call
either and get the same method. Until the method was subbed later on by its
real name, in which case method would just be a method (and would still
exist).

Having used the occasion to put forth yet another stupid idea, I’ll get to
your proposal… Momentarily you can’t work the ObjectProxy below with
your technique, or anything that includes a method_missing technique. I

Interfaces allow that, but wouldn’t be able to provide for it. You could
certainly still handle method_missing calls for methods that are outside the
scope of an interface because an object would only need to fulfill an
interface, not be strictly bounded by it. I doubt we could create an
interface mechanism that actually made use of method_missing, though. I
think when it comes to interfaces, things get a little bit strict. But the
freedom is still there to work outside of them. If a class can’t implement a
method without handling it through a call to method_missing, I think we have
to say that method cannot fulfill an interface.

Another thing; since methods can be removed and added, maybe it’s
interesting to also be able to add or remove the notification that you
intend to implement an interface. As such, no dynamism is lost there. But
it’s an extra complication :frowning:

I think when it comes down to the nuts and bolts of it, those sorts of things
are cool ideas to patch in down the road. I think the basics of it will
work, and this sort of thing will crop up now and again, but Matz or someone
would be able to zip in a patch to do that pretty easily.

Last thing (unless I come up with something else before I send this mail);
you should probably also provide a way of declaring superinterfaces and
subinterfaces. Suppose someone provides an interface InputOutput which
provides methods for inputting and outputting (what else?). If some method

There are two ways this is partially covered:

One, and I know this is the “not my job” answer: interfaces should be
well-defined enough to separate Input from Output to begin with. I think
with poorly designed interfaces, you’re going to have trouble.

Two, interfaces can be subbed in my proposal, so you could subclass an IO
string interface from a base IO interface.

But as to superclassing, since the original interface designer lumped Input
and Output into one interface, what you are really talking about is bypassing
the interface requirements that methods might have. Instead of looking at it
as superclassing an interface, look at it as shoving any old object past a
requirement. I think there should be a mechanism for that as well.
Flexibility should always be paramount.

Unless I misunderstood your use of superclassing the interface. Correct
please if I’m wrong.

BTW, I really admire you for still being here after all the heat :slight_smile:

I wouldn’t be if I thought perhaps I couldn’t tackle the problem. I’ve
written several different script language incarnations, and I know the trick
is to keep the back-end as simple as possible. No matter how cool any system
might be on paper, if it’s hard enough on the back-end, it will perform
poorly and break a lot. I’m trying to keep Matz’ workload in the forefront
of my mind while working through this.

Sean O'Dell
···

On Thursday 20 November 2003 05:51 pm, Peter wrote:

Hi,

  • Types (or “interfaces” to avoid confusion) must be independent
    from class/module, otherwise they will be misused too often. Note
    that Sean himself once failed to distinguish these two.

I agree, but since classes and interfaces are often synonymous, there could,
possibly, be an alternative mechanism to describing interfaces that used
class definition in some way.

Possible.

Please ask me questions. I’m terrible about making my own new ideas known
because I don’t anticipate how clearly they will be received.

The way “false promise” was used before, a class could say “I implement this
interface” and then NOT implement it, making the statement a lie. In my new
proposal, there is no way to make that statement. If a class declares “I
implement this interface” it is marked as “incomplete” and the declaration is
essentially hidden until the last method fulfills the interface requirement.
The class makes the statement, but that is basically ignored until
fulfillment is complete, and then the class can generate objects which
contain a flag for that interface.

At least I need to take time to sit down and read your article
carefully first.

  • The appearance matters. I think the code example in the proposal
    does not look like Ruby:

That was just an example, I threw that in quickly. Perhaps the interface
requirements would appear in the interface definition, but they would not be
repeated when the class actually defined the method.

I understand it’s not your point. It’s my job to design the syntax
fit with other part of Ruby.

All in all, I’m wondering trade-offs about this proposal.

						matz.
···

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

I keep getting hung up on this point. Are you proposing an entire
parallel type hierarchy based on interfaces, or are you going to let
normal ruby ‘types’ be used as arguments? And if the latter, what’s to
define those types?

martin

···

Sean O’Dell sean@celsoft.com wrote:

something in Ruby like usual, then as a project started to get larger and
more complicated, or as people were added to the project who might not fully
understand all your classes, wouldn’t it be nice to say “okay kids, before
you go muddying up this project, here’s a couple rules for you. never pass
anything but this type here. and this type here.” So except for the places
where you think you ought to provide a little guidance, leave the rest of it
wide open as usual.

This is, I think, the clearest I can make the new proposal tonight:

Perhaps tomorrow I can clean it up some more, when my eyes don’t hurt as much,
and after Ziegler points out how wrong it is and how pointless even trying is
and how it’s all just pointy-haired twaddle to be immediately made obsolete
by an eval statement.

Sean O'Dell
···

On Thursday 20 November 2003 07:58 pm, Yukihiro Matsumoto wrote:

At least I need to take time to sit down and read your article
carefully first.

I am not sure exactly how Haskell works, but it sounds like perhaps
fulfillment could occur through a form of aliasing, although calls could
still be made to the method required by its original name. Calls doing that
would actually route through the aliased method. Since this only involves
the interface mechanism, and would be just another method to Ruby, this could
work, sure.

It could look like:

class AnyClass
def method(parameters) implements someothermethod
end

… which would allow someothermethod to be fulfilled in the interface
requirement, but the method would actually be called method. You could call
either and get the same method. Until the method was subbed later on by its
real name, in which case method would just be a method (and would still
exist).

Actually it’s rather an application of the adapter pattern, which is an
interface problem and which could benefit from support in interface
declaration. But my problem rather lies in the fact that two libraries
both expect an object to have a method with a certain name - but the same
for both - but they expect different behavior from it. You can always
rename your own methods, but not those that a library expects. (Though you
can “adapt” those a library offers through something like aliasing).

Interfaces allow that, but wouldn’t be able to provide for it. You could
certainly still handle method_missing calls for methods that are outside the
scope of an interface because an object would only need to fulfill an
interface, not be strictly bounded by it. I doubt we could create an
interface mechanism that actually made use of method_missing, though. I
think when it comes to interfaces, things get a little bit strict. But the
freedom is still there to work outside of them. If a class can’t implement a
method without handling it through a call to method_missing, I think we have
to say that method cannot fulfill an interface.

My point is just that the wolves will pick on this because it decreases
flexibility in the sense that any method which expects an object
implementing a certain interface can’t be passed such a proxy. If it’s
just your own code, you can just decide not to use the interface (which is
basically what you say above, right? Or only use part of it), but anyone
using your interfaces in a library API would restrict the flexibility for
the users. Basically implementing an interface is saying that you are duck
typing, but the check doesn’t manage all of duck typing.

I think when it comes down to the nuts and bolts of it, those sorts of things
are cool ideas to patch in down the road. I think the basics of it will
work, and this sort of thing will crop up now and again, but Matz or someone
would be able to zip in a patch to do that pretty easily.

Well, just saying it would be nice to think of this possibility up front,
that it’s possible and easy to do. I’m sure Matz is a much better
programmer than anyone of us, but not all is easily done.

There are two ways this is partially covered:

One, and I know this is the “not my job” answer: interfaces should be
well-defined enough to separate Input from Output to begin with. I think
with poorly designed interfaces, you’re going to have trouble.

OK, this is where I don’t agree with you. If you don’t allow refining the
granularity (which superinterfacing is supposed to do), you’ll always end
up being less flexible than duck typing as it is now. This has nothing to
do with poor design. A good design is flexible, maintainable, adaptable,
but it can’t provide for all future needs. Can you guarantee that if you
write an interface, that it’s the smallest useable subset of
functionality?

Two, interfaces can be subbed in my proposal, so you could subclass an IO
string interface from a base IO interface.

But as to superclassing, since the original interface designer lumped Input
and Output into one interface, what you are really talking about is bypassing
the interface requirements that methods might have. Instead of looking at it
as superclassing an interface, look at it as shoving any old object past a
requirement. I think there should be a mechanism for that as well.
Flexibility should always be paramount.

Unless I misunderstood your use of superclassing the interface. Correct
please if I’m wrong.

I will. Suppose someone design a library with Input and Output as provided
interfaces. Then classes will emerge that implement these interfaces,
right. The separation in Input and Output is based on the functionality of
the library, logically, right? When I use this library, and I would need
only an interface that only requires a subset of say the Input interface.
This is possible, right? I have several options. Either I create my own
interface with a subset of the methods of the Input interface, but then
any class implementing this Input interface can’t be passed as something
implementing your interface, or at least not as such, while duck typing
allows for this. If you allow for superinterfacing (i.e., defining a
subset of methods in a separate interface), you have this flexibility
automatically.

I wouldn’t be if I thought perhaps I couldn’t tackle the problem. I’ve
written several different script language incarnations, and I know the trick
is to keep the back-end as simple as possible. No matter how cool any system
might be on paper, if it’s hard enough on the back-end, it will perform
poorly and break a lot. I’m trying to keep Matz’ workload in the forefront
of my mind while working through this.

I know, I’ve been thinking about this as well when this thread started and
I am convinced as well that it isn’t very hard to pull off.

Peter

The syntax of the interface description isn’t really that important; it’s
something that can be bantered around for awhile, I just showed one possible
way to define them. But yes, I would like to see class and interface as two
separate things, in parallel, but not perfectly synchronized, at least in
concept (although for eloquence, they could be joined syntactically). The
idea is not to constrain classes themselves except to require them to adhere
to the interfaces they proclaim to implement.

Normal Ruby types are so dynamic, I don’t think you could ever base type
checking on them. Not without excessive runtime overhead. I could be wrong,
but that just seems like such a dark, ugly alleyway. Types, as required by
method parameters in my proposal, would be interface names, and objects
passed to those methods must completely fulfill the interface required.

Sean
···

On Thursday 20 November 2003 05:02 pm, Martin DeMello wrote:

Sean O’Dell sean@celsoft.com wrote:

something in Ruby like usual, then as a project started to get larger and
more complicated, or as people were added to the project who might not
fully understand all your classes, wouldn’t it be nice to say “okay kids,
before you go muddying up this project, here’s a couple rules for you.
never pass anything but this type here. and this type here.” So except
for the places where you think you ought to provide a little guidance,
leave the rest of it wide open as usual.

I keep getting hung up on this point. Are you proposing an entire
parallel type hierarchy based on interfaces, or are you going to let
normal ruby ‘types’ be used as arguments? And if the latter, what’s to
define those types?

That’s enough, Sean. Everyone knows now that you’re a spoiled little
brat who doesn’t like being shown that he’s wrong or ignorant. You
can stop being an ass and embarrassing yourself.

You’ve also convinced me – far more than you ever had before –
that you don’t know what you’re talking about. After all, it’s
more important to try to insult me than to actually accomplish
anything. Isn’t it?

You’ve put together multiple proposals, one of which was badly
flawed. I’ve poked huge holes in the first, and pointed out that
there’s a fundamental misunderstanding in the second. Nothing more,
nothing less. Just because you decided to take my poking holes in
your ideas personally doesn’t mean that you have to make an ass of
yourself.

-austin

···

On Fri, 21 Nov 2003 14:50:27 +0900, Sean O’Dell wrote:

On Thursday 20 November 2003 07:58 pm, Yukihiro Matsumoto wrote:

At least I need to take time to sit down and read your article
carefully first.
This is, I think, the clearest I can make the new proposal tonight:
http://www.rubygarden.org/ruby?InterfaceContracts
Perhaps tomorrow I can clean it up some more, when my eyes don’t
hurt as much, and after Ziegler points out how wrong it is and how
pointless even trying is and how it’s all just pointy-haired
twaddle to be immediately made obsolete by an eval statement.


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

Sean O’Dell wrote:

At least I need to take time to sit down and read your article
carefully first.

This is, I think, the clearest I can make the new proposal tonight:

http://www.rubygarden.org/ruby?InterfaceContracts

Perhaps tomorrow I can clean it up some more, when my eyes don’t hurt as much,
and after Ziegler points out how wrong it is and how pointless even trying is
and how it’s all just pointy-haired twaddle to be immediately made obsolete
by an eval statement.

Sean O’Dell

I read it over a bit and have a few comments

  • Rather have the method definition stay as is (no addition of type
    declaration). Interface should be an optional enhancement - take a
    class, add a interface (hopefully short) section, and we have what we
    need - no fuss (or in Ruby, reopen an
    existing class, …). It may be more work to allow interface to be
    added “after” the method have been defined though.

  • Rather not have the return type declaration. With dynamic language, I
    don’t know if this could be done without runtime checkin. Also, the
    check, I think, would also need to be done at the object receiver end
    (i.e. calling class) and this would involves runtime checkin with the
    cost to be born by user of object.

BTW, thanks much for taking the heat for trying to expose this issue.
Don’t know where this will lead but it is much better than people get
exasperated and quietly leave.

I do feel, however, that having interface fully separated from class put
an onus on the use of interface (as personally I mostly design the
object structure through the interface -i.e. user of objects should not
have to care/deal with class - only interfaces). Class is only a
convenient expression to support code reuseability through inheritance
and polymorphism. But it is also a convenient way of describe
interface.

Syntactic sugar (simplicity, style) is a desirable feature of Ruby, and
making it it inconvenient to use will turn people off from using
and we’ll be right back to using the same stuff as where we started.

Thien

···

On Thursday 20 November 2003 07:58 pm, Yukihiro Matsumoto wrote:

Hi,

This is, I think, the clearest I can make the new proposal tonight:

http://www.rubygarden.org/ruby?InterfaceContracts

I read the proposal. It’s huge modify, which potentially affect
Ruby’s character very much. I know “interface contract” (using your
new term) is a good thing, putting aside the syntax in the example I
don’t like. But I have to consider its trade-off.

What we gain and what we lose? Selling point? I don’t care.
Better diagnosis? It’s good, but worth this big change?
I don’t know yet.

						matz.

p.s.
Please do not use bad words everyone.

···

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

I am not sure exactly how Haskell works, but it sounds like perhaps
fulfillment could occur through a form of aliasing, although calls could
still be made to the method required by its original name. Calls doing
that would actually route through the aliased method. Since this only
involves the interface mechanism, and would be just another method to
Ruby, this could work, sure.

It could look like:

class AnyClass
def method(parameters) implements someothermethod
end

… which would allow someothermethod to be fulfilled in the interface
requirement, but the method would actually be called method. You could
call either and get the same method. Until the method was subbed later
on by its real name, in which case method would just be a method (and
would still exist).

Actually it’s rather an application of the adapter pattern, which is an
interface problem and which could benefit from support in interface
declaration. But my problem rather lies in the fact that two libraries
both expect an object to have a method with a certain name - but the same
for both - but they expect different behavior from it. You can always
rename your own methods, but not those that a library expects. (Though you
can “adapt” those a library offers through something like aliasing).

Oh, I see. You know, I think I know of a script language that did that.
Actually, what it had were a sort of virtual method system, where you could
have the same method name implement several variations of itself, but each
one was tagged to a “context.” When you call the method, you could call it
in the default context and the default method would execute, or put the
object into some other context and call the method, and an entirely different
method would execute. The method names could be the same; they were only
differentiated by their context.

Interfaces allow that, but wouldn’t be able to provide for it. You could
certainly still handle method_missing calls for methods that are outside
the scope of an interface because an object would only need to fulfill an
interface, not be strictly bounded by it. I doubt we could create an
interface mechanism that actually made use of method_missing, though. I
think when it comes to interfaces, things get a little bit strict. But
the freedom is still there to work outside of them. If a class can’t
implement a method without handling it through a call to method_missing,
I think we have to say that method cannot fulfill an interface.

My point is just that the wolves will pick on this because it decreases
flexibility in the sense that any method which expects an object
implementing a certain interface can’t be passed such a proxy. If it’s
just your own code, you can just decide not to use the interface (which is
basically what you say above, right? Or only use part of it), but anyone
using your interfaces in a library API would restrict the flexibility for
the users. Basically implementing an interface is saying that you are duck
typing, but the check doesn’t manage all of duck typing.

I know it’s a shortcoming, but the whole notion of interfaces has lots of
things that restrict what you can do. That’s why you can mix them in
anywhere, and all the usual Ruby rules still apply.

But I think where might want both a run-time method morphing scheme AND to be
able to promise it through an interface, I really think we would have to come
up with a name aliasing scheme (perhaps that was your suggestion originally,
I think). It would serve the purpose.

But let’s also not forget that interfaces wouldn’t DOMINATE Ruby. They’re
just there to provide a little help to code sharers. I doubt it can be all
things to all people.

I think when it comes down to the nuts and bolts of it, those sorts of
things are cool ideas to patch in down the road. I think the basics of
it will work, and this sort of thing will crop up now and again, but Matz
or someone would be able to zip in a patch to do that pretty easily.

Well, just saying it would be nice to think of this possibility up front,
that it’s possible and easy to do. I’m sure Matz is a much better
programmer than anyone of us, but not all is easily done.

I think if the interface mechanism were there, it would appear as a short hop
to adding in an “alternate context” sort of mechanism. Right now, that’s a
couple steps ahead, so it’s seems far-off, but with interfaces working, it
wouldn’t.

There are two ways this is partially covered:

One, and I know this is the “not my job” answer: interfaces should be
well-defined enough to separate Input from Output to begin with. I think
with poorly designed interfaces, you’re going to have trouble.

OK, this is where I don’t agree with you. If you don’t allow refining the
granularity (which superinterfacing is supposed to do), you’ll always end
up being less flexible than duck typing as it is now. This has nothing to
do with poor design. A good design is flexible, maintainable, adaptable,
but it can’t provide for all future needs. Can you guarantee that if you
write an interface, that it’s the smallest useable subset of
functionality?

But interfaces are for making contracts. Contracts are like plans. You can’t
design it poorly up-front, start making promises, then rescind the promises.
The interfaces (when used, they ARE optional) are supposed to be a layout of
what something can and can’t do. Ruby provides flexibility enough by itself,
interfaces should provides firmness.

Two, interfaces can be subbed in my proposal, so you could subclass an IO
string interface from a base IO interface.

But as to superclassing, since the original interface designer lumped
Input and Output into one interface, what you are really talking about is
bypassing the interface requirements that methods might have. Instead of
looking at it as superclassing an interface, look at it as shoving any
old object past a requirement. I think there should be a mechanism for
that as well. Flexibility should always be paramount.

I just don’t see how you can make a contract that says “this does this” and
then pass in an object which has superclassed that contract, removed some
portions of it, then push the object to a parameter which requires the
original contract. Even with a superclassing mechanism, it’s a lie; the
method is not receiving what it has asked for. So, since it’s a lie, why not
just make a way to push any object past a requirement. If someone is going
to do that, they’re taking the risk. Something might blow up, or if they
know for some good reason it won’t, they can try it.

What I mean is, if an interface designer lumps Input and Output together, and
provides a method that requires an object which fulfills the InputOutput
contract, how can you pass an object which only partially fulfills this
requirement?

My feeling is, you should be able to, but since you’re giving it an object
that doesn’t give it 100% of what it asks for, just shove the object in there
the old-school Ruby way and hope for the best. No need to write up a
superclass. Write a whole new interface for Input and one for Output, and
then just shove objects that fulfill those interfaces past InputOutput
requirements.

Unless I misunderstood your use of superclassing the interface. Correct
please if I’m wrong.

I will. Suppose someone design a library with Input and Output as provided
interfaces. Then classes will emerge that implement these interfaces,
right. The separation in Input and Output is based on the functionality of
the library, logically, right? When I use this library, and I would need
only an interface that only requires a subset of say the Input interface.
This is possible, right? I have several options. Either I create my own
interface with a subset of the methods of the Input interface, but then
any class implementing this Input interface can’t be passed as something
implementing your interface, or at least not as such, while duck typing
allows for this. If you allow for superinterfacing (i.e., defining a
subset of methods in a separate interface), you have this flexibility
automatically.

I see where you’re driving at. The interface is not compared through method
signatures. There are methods which require InputOutput by name, not by a
set of method signatures, so superclassing to Input and thus generating a
unique signature of methods would not make those methods happy. They still
just want objects which fulfill the InputOutput contract.

Again though, my experience is: when you design the interfaces, just design
them right.

But looking at the method signature idea: I think if you matched interfaces
based on method signatures, you’re talking about having methods which all
have their own (potentially) uniquely generated requirement signature. That
means that every object passed in every parameter would have to be checked to
ensure each object passed had all the right methods. That’s a lot of
run-time overhead. It’s much simpler just to compare the parameter types
(named interfaces or none) to the interface description to see that they
match the requirements for that method. It would be much, much faster just
doing that, and if you designed the interfaces correctly, you get the same
reassurance.

Sean O'Dell
···

On Friday 21 November 2003 02:28 am, Peter wrote:

Whatever you say Ziegler.

Sean O'Dell
···

On Thursday 20 November 2003 10:52 pm, Austin Ziegler wrote:

On Fri, 21 Nov 2003 14:50:27 +0900, Sean O’Dell wrote:

On Thursday 20 November 2003 07:58 pm, Yukihiro Matsumoto wrote:

At least I need to take time to sit down and read your article
carefully first.

This is, I think, the clearest I can make the new proposal tonight:
http://www.rubygarden.org/ruby?InterfaceContracts
Perhaps tomorrow I can clean it up some more, when my eyes don’t
hurt as much, and after Ziegler points out how wrong it is and how
pointless even trying is and how it’s all just pointy-haired
twaddle to be immediately made obsolete by an eval statement.

That’s enough, Sean. Everyone knows now that you’re a spoiled little
brat who doesn’t like being shown that he’s wrong or ignorant. You
can stop being an ass and embarrassing yourself.

You’ve also convinced me – far more than you ever had before –
that you don’t know what you’re talking about. After all, it’s
more important to try to insult me than to actually accomplish
anything. Isn’t it?

You’ve put together multiple proposals, one of which was badly
flawed. I’ve poked huge holes in the first, and pointed out that
there’s a fundamental misunderstanding in the second. Nothing more,
nothing less. Just because you decided to take my poking holes in
your ideas personally doesn’t mean that you have to make an ass of
yourself.

oh come on guys! its all sport! you know, Duck Hunting! :slight_smile: its fun!

sure give each other a hard time. its a good show. but don’t hold bad
karma…

karma!..hey that it! all we need is a karma based type system:

def your_karma(x)
if x.bad_karma?
raise BadKarmaError, "seek guidance from nearest ruby guru"
end
puts x…good_karma?
end

be true!

-t0

uh…that would be me. at least i know you’re reading me :wink:

sorry, i won’t do it. although i don’t believe in bad words, like that funny
saying of a country bumpkin: “guns don’t shoot people…I do!” same with bad
words. it is how you mean them. i don’t normally use “bad” words as it is
tacky. but sometimes i do for “color” or effect --to be funny. but it
probably does not translate well to japanese speakers :frowning:

anyway, sorry. i will refrain.

So matz i have a special gift for you!!!

but first i have question. will send off list…hmmm…what is you email? i
will look for it.

sorry again,
-t0

···

On Friday 21 November 2003 11:20 am, Yukihiro Matsumoto wrote:

Please do not use bad words everyone.