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

Ah, okay. That does sound like a promising approach, particularly since
you can annotate existing ruby objects with interface names.

martin

···

Sean O’Dell sean@celsoft.com wrote:

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

This is entirely possible:

I agree there is no need to declare any type declarations in the method
itself, and I meant to eliminate those from the example code in the
“interface implementation” section where the class was defined. I was tired.

It’s no more work really to add the interface to an existing class. It’s all
just a matter of comparing the interface table to the method definition.
There’s very little difference between catching “method added” calls and
iterating through all the methods.

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

Run-time checking would have to be done to match parameter types (interface
contracts) anyway. It’s probably not a big difference to also check the
return type as well.

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.

It’s not a problem at all. The thinkers got separated from the agitators
pretty quickly, and I’m dealing with the agitators in my own way. Once I
know someone is just being negative and crude, it’s pretty easy to whip them
up a batch of their own medicine.

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.

I agree with this entirely, but I also see it the other way around. The
StringIO is the standard case example. If a method requires a parameter to
be of type IO, you wouldn’t be able to pass a type StringIO because StringIO
is not derived from IO, it merely implements the same interface that IO does.
Thus the need to separate IO.

Although, this could also be settled through virtual classes that define the
interface, and StringIO could be changed to inherit it. I am not sure why
that is not a valid option because it’s the sort of practice I’m used to, but
I’m sure there’s a reason for it.

Maybe someone should say why, exactly, StringIO doesn’t derive from a virtual
base IO class?

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.

Agreed. I think possible syntax sugars will become apparent as this sword is
hammered out.

Sean O'Dell
···

On Friday 21 November 2003 12:12 am, Thien Vuong wrote:

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.

Some of the things we gain were listed in the proposal.

As to benefit: it depends on who you care about. Programmers, and especially
library authors, gain a way to help people learn a little about their code
and to catch potential errors in pitfalls. Project developers gain pretty
much the same things: the ability to share code and help their co-workers
understand a little more about their code and to help prevent them from
making some obvious mistakes. We also gain some speed in debugging: where
interfaces are used by people unfamiliar with the code they are calling into
(through ignorance and lack of documentation) it’s faster responding to a
nice error message about type incompatibilities than it is to wonder about an
error regarding method calls. Project managers are also far more likely to
implement Ruby in their projects if they feel it is as safe as what they
need, and type checking is one of the safety catches that a lot of people
have grown comfortable with. It’s also something Python doesn’t have, and
will be one of the things you can flat-out say “we have it, they do not.”

Worth it? In my opinion, absolutely.

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

Except in private email, of course, as Ziegler clearly already knows. Thanks
for the fan mail, Ziegler!

···

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

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:

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.

Yup. And what I mean to say is that that context can be provided by the
interface the method belongs to. It’s merely an idea, I don’t know how it
will look in practice. And in case you would uberhaupt decide to borrow
something from the idea above, please don’t get me started about the
dangers of defaults :wink:

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.

Granted. But my feeling is that it would be nicer to have the benefits of
interface checking without any loss in flexibility. There will be loss in
code size, but I do like the idea of saying something in code instead of
in documentation - which interface checking could partly do IMO.
Documentation makes promises, interfaces could formalize them. But you’d
have to get it right…

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.

Agreed. I’m just a bit worried that you’re proposal as it is now - or was
when I last checked it - will limit flexibility initially, which will make
its acceptance a bit harder. What I hope from your proposal is that it’s
really a way of declaring that you’re duck typing. I feel that it would be
better to have your approach be built from the ground up with the same
dynamism and flexibility in mind - especially in the context of ruby.
Anyway, the “alternate context” sort of mechanism is just a possibility
for an extra abstraction level.

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.

My point is that an existing interface, e.g., from a library makes a
number of promises, and when reusing some of the components making these
promises, you’d only need a subset of those promises. It’s not a matter of
good design, but a matter of granularity. As interfaces declare
collections of methods, each method offering some functionality, it should
be clear that not in all contexts the functionality of each of these
methods is required, but only a subset. To make it concrete… if I’d use
the String class, which offers a number of methods, it’s easily
imagineable that there’s a method I’ll never use in my code, e.g., unpack.
Duck typing then means that instead of passing my code a String, it is OK
to pass it an object which implements all methods from String except for
unpack. Does this make the interface that String provided poorly designed?
What I really want to say is that good design is always an issue, but to
have no interference with duck typing, you need to deal with the issue of
granularity as well. And this can be provided by superinterfacing and
subinterfacing - the former being only necessary when you have fixed
interfaces that can’t be extended dynamically. This would be nice if it
was what you wanted, but it seems like it’s your implementation that would
need it - correct me if I’m wrong.

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.

Like I said, an interface contains a number of methods, right? Each method
holds a number of promises, possibly WRT other methods, right? To me a
method that supplies only part of the promises logically is another
method. A method is really a request to do something, and the promises of
a method kind of catch the idea of what the request asked for (if that’s
not so, your code will malfunction). But no matter how well you design
your interface, it’s unthinkable that you can provide just these promises
that are required by any code that will ever use it. Of course in the
current setting, the set of promises of a method is entailed by the
signature of that method, hence my String example above.

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.

Have you ever considered lazily checking interfaces? Suppose you have a
method requiring an argument that implements a certain interface. Instead
of checking the interface at the time of the method call, you’d check
parts of it when the interface of the argument is used. By this last thing
I mean when a method from the interface is actually called on the argument
that implements the interface, then you’d check for the existence of the
method. Type-checking the arguments to the method call are of course then
also lazily done within that method call. Provided that you use all
methods from the interface, the interface will be type-checked completely
during the call. If you don’t use all these methods, it was unnecessary to
require them all anyway.

Now if you read this carefully, this sounds exactly like any ruby method
call. Thus there’s no overhead. But if you also provide a way to
distinguish between calls to methods from a certain interface and other
methods, then you can print the detailed error diagnostics you wanted
since you know what interface is involved. Additionally it doesn’t seem to
imply any runtime overhead except when the interface is actually violated
in the sense of a duck typing error. Also if you’d really need more info,
you could provide it and make sure all work necessary for that only
happens when a method from an interface is actually missing.

And I just realized this also works well for the ObjectProxy example…
Also I don’t see how it can break duck typing in any way since now the
only difference lies in error diagnostics.

I don’t know if I make sense here to you, if I don’t, I’ll work out an
example tomorrow - it’s bed time here. I also don’t know if you appreciate
the difference in how it works.

Peter

Yukihiro Matsumoto wrote:

Hi,

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

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

  					matz.

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

Perhaps one could make assertions about parameters / methods that could
be checked?
e.g.

class someclass < someOtherClass
assert .kind_of(someClass, Number)
def initialize (foo, bar)
assert.responds_to(foo, +)
assert.kind_of(bar, Number)

end

end

The only advantage I see of this over the normal responds_to? and
kind_of? is that it could be enabled or disabled by either a flag or by
a global variable ($DEBUG or possibly $ASSERT instead). assert
appears slightly special in that since it doesn’t require any import
statement, it’s probably added onto Object, and also I notice that the
“+” operator was considered as a normal method without being attached to
any variable (and methods would need to be able to go there too).
Perhaps that argument should be quoted?

This clearly doesn’t answer all of the requirements, but it does answer
some of them, and might assist in debugging. (And it appears to me that
it would be simple for someone who understood Ruby better than I do to
implement.) Clearly if this were to be intended as a serious checking
tool it would need expansion, e.g. one would want a way to test that “+”
could take either one or two arguments, and that those arguments could
be numbers. A benefit of this approach is that it could probably be
bolted on without any change to the interpreter itself (at least until
it was decided to implement interpreter flags).

···

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:

My own views on interface crystallization:

  1. It should not be done in-line, but rather through a separate express
    creation of an interface table. [Note: one of the nice things about the
    way Ruby (and other languages) does things is the inline creation of
    dispatch on type tables for generic operators through the use of
    classes in an object system. It would be bad to complicate this and
    other elements of Ruby’s human interface by also putting interface
    "contracts" inline with Ruby’s current (usually very comprehensible)
    class declaration system.]

  2. The table would include fields specifying whether the interface is
    mutable or immutable, the number of arguments and “types” of arguments
    a method takes, exceptions to raise if the particular interface element
    fails, and so on.

  3. A skeleton table could be generated from existing code, with
    suitable default values (such as mutable interface, argument “type” set
    to Object, etc. The developer would choose where to crystallize an
    interface element and forego additional possible dynamism.

  4. The table could be queried to produce detailed documentation
    information and/or included at runtime as a constraint on execution.

  5. In the future, one could perhaps also use the table to guide a Ruby
    compiler as to when a form of “static typing” can be used to optimize a
    particular program (according to the instructions of the developer).

I do not, however, think the proposal is necessarily a good idea. It
does seem very costly, and the magnitude of the benefit is not clear to
me. A way to make it lower-cost would be good, because then it would be
easier to try.

Some questions:
Have the main proponents (and critics) looked at how Objective C
handles this and similar issues?
Could this, or something similar, be done within Ruby?
How would this handle methods that take blocks?
How can Ruby better document the kind of block code that would be
useful with respect to a particular method?
How would this, and related ideas, work in a distributed environment,
where one might wish to differentiate site-specific capabilities?

Regards,

Mark

Yes, precisely, and in-fact Matz could add cheap, pre-defined interface tags
for all of the built-in Ruby types. I wouldn’t even give them an interface
description for people to look at; the basic types could just be there
magically.

Sean O'Dell
···

On Friday 21 November 2003 06:32 am, Martin DeMello wrote:

Sean O’Dell sean@celsoft.com wrote:

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.

Ah, okay. That does sound like a promising approach, particularly since
you can annotate existing ruby objects with interface names.

Hi,

Some of the things we gain were listed in the proposal.

As to benefit: it depends on who you care about. Programmers, and especially
library authors, gain a way to help people learn a little about their code
and to catch potential errors in pitfalls. Project developers gain pretty
much the same things: the ability to share code and help their co-workers
understand a little more about their code and to help prevent them from
making some obvious mistakes. We also gain some speed in debugging: where
interfaces are used by people unfamiliar with the code they are calling into
(through ignorance and lack of documentation) it’s faster responding to a
nice error message about type incompatibilities than it is to wonder about an
error regarding method calls. Project managers are also far more likely to
implement Ruby in their projects if they feel it is as safe as what they
need, and type checking is one of the safety catches that a lot of people
have grown comfortable with. It’s also something Python doesn’t have, and
will be one of the things you can flat-out say “we have it, they do not.”

Worth it? In my opinion, absolutely.

In my opinion, not much. You’ve mentioned interface contract would:

(a) help learning code.
(b) gain speed in debugging by more check (and better message).
(c) make project manager feel better for more safety.
(d) allow us to say “we have something you don’t have” to Python
people.

Among these, only (b) appeal to me. (a) can be done better by RDoc
documents. For (c) and (d), I don’t care about selling Ruby to
anyone.

I prefer Jim Weirich’s idea in [ruby-talk:86007], utilizing method
combination.

in the library code foo.rb:

require ‘foo_if’

which defines interface

you can comment out from production code

class Foo
def greet(hi)
hi.display
print “\n”
end
end

in the foo_if.rb:

class Foo
def greet:pre(hi)
assert hi.respond_to? :display
end
end

with probably interface checking cosmetic.

						matz.
···

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

Okay, I’ve said my peace on this subject and designed up a proposal you can
take or leave. I think what I had in mind is clear enough, so I think that’s
all I need to say about it.

Sean O'Dell

My own views on interface crystallization:

(similar to my own)

  1. It should not be done in-line, but rather through a separate express
    creation of an interface table. [Note: one of the nice things about the way
    Ruby (and other languages) does things is the inline creation of dispatch on
    type tables for generic operators through the use of classes in an object
    system. It would be bad to complicate this and other elements of Ruby’s
    human interface by also putting interface “contracts” inline with Ruby’s
    current (usually very comprehensible) class declaration system.]

i thinks it’s absolutely in line with the ruby way for an ‘interface’ to
simply be an object

class Interface
def initialize object = nil
skeletonize object if object
end
end

  1. The table would include fields specifying whether the interface is
    mutable or immutable, the number of arguments and “types” of arguments a
    method takes, exceptions to raise if the particular interface element fails,
    and so on.

this too, should simply be an object

class Interface
attr :signatures
class Signature
def initialize object = nil, meth = nil
skeletonize object, meth if object and meth
@signatures = Hash.new # map meth name to signature
end
end
end

  1. A skeleton table could be generated from existing code, with suitable
    default values (such as mutable interface, argument “type” set to Object,
    etc. The developer would choose where to crystallize an interface element
    and forego additional possible dynamism.

skeleton_sig = Signature.new Array, :each

class Interface
class Signature
# true/false
def takes_block; end

# attributes of block
def block_attr; end

# list of errors/exceptions types
def raises; end

# list of Classes, Interfaces, or methods any argument must respond_to?
# example: sig.signature # => [String, StringInterface, :to_s]
def signature; end

end
end

  1. The table could be queried to produce detailed documentation information
    and/or included at runtime as a constraint on execution.

see above

  1. In the future, one could perhaps also use the table to guide a Ruby
    compiler as to when a form of “static typing” can be used to optimize a
    particular program (according to the instructions of the developer).
  1. Interfaces HAVE implementations vs. classes IMPLEMENTING an
    Interface. this is vastly simpler with respect to backward compat:

BAD:

class MyClass
  # requires change to class 'Class'
  implements Interface
end

GOOD:

interface.impl << MyClass

# no change to class 'Class' needed

I do not, however, think the proposal is necessarily a good idea. It
does seem very costly, and the magnitude of the benefit is not clear to
me. A way to make it lower-cost would be good, because then it would be
easier to try.

again, agreed. but if people HAVE to have such a beast i concur that it
should be a completely separate one - not tightly intergrated into the
language.

Some questions:

How can Ruby better document the kind of block code that would be
useful with respect to a particular method?

perhaps

class Interface
class Signature; end
class MethodSignature < Signature; end
class BlockSignature < Signature; end
end

???

-a

···

On Sat, 22 Nov 2003, Mark Wilson wrote:

ATTN: please update your address books with address below!

===============================================================================

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
STP :: Solar-Terrestrial Physics Data | NCEI
NGDC :: http://www.ngdc.noaa.gov/
NESDIS :: http://www.nesdis.noaa.gov/
NOAA :: http://www.noaa.gov/
US DOC :: http://www.commerce.gov/

The difference between art and science is that science is what we
understand well enough to explain to a computer.
Art is everything else.
– Donald Knuth, “Discover”

/bin/sh -c ‘for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done’
===============================================================================

My own views on interface crystallization:

  1. It should not be done in-line, but rather through a separate express
    creation of an interface table. [Note: one of the nice things about the
    way Ruby (and other languages) does things is the inline creation of
    dispatch on type tables for generic operators through the use of
    classes in an object system. It would be bad to complicate this and
    other elements of Ruby’s human interface by also putting interface
    “contracts” inline with Ruby’s current (usually very comprehensible)
    class declaration system.]

Agreed. But also, one of the advantages to having the interfaces separate is
they won’t be cluttered with code, which means you can browse an interface to
determine what it does in one compact location. Much different from browsing
classes.

  1. The table would include fields specifying whether the interface is
    mutable or immutable, the number of arguments and “types” of arguments
    a method takes, exceptions to raise if the particular interface element
    fails, and so on.

Just for example, why would someone need a mutable interface?

  1. A skeleton table could be generated from existing code, with
    suitable default values (such as mutable interface, argument “type” set
    to Object, etc. The developer would choose where to crystallize an
    interface element and forego additional possible dynamism.

You mean, sort of a class extractor that can generate an interface template
that they can then edit to suit their needs? If so, that’s something that
could be a third-party utility.

  1. The table could be queried to produce detailed documentation
    information and/or included at runtime as a constraint on execution.

Is the table different from the interface description I describe in the wiki?
The proposal now already plans to constrain method calls based on the
interface description.

  1. In the future, one could perhaps also use the table to guide a Ruby
    compiler as to when a form of “static typing” can be used to optimize a
    particular program (according to the instructions of the developer).

Perhaps … but I think going this far might too far off Ruby’s path.

I do not, however, think the proposal is necessarily a good idea. It
does seem very costly, and the magnitude of the benefit is not clear to
me. A way to make it lower-cost would be good, because then it would be
easier to try.

It’s pretty cheap in terms of run-time overhead. It really does only the bare
minimum I can imagine any form of type checking doing. It only tests for an
“interface compliance” flag at run-time; that’s little more than a test for
true/false. How much cheaper can it be?

Some questions:
Have the main proponents (and critics) looked at how Objective C
handles this and similar issues?

No, but I’m open to ideas. =)

How would this handle methods that take blocks?

Interesting problem, but one that definitely can be worked out. It doesn’t
appear to be circular, but I’m not aware of all the issues regarding them, so
I think it’s workable.

How can Ruby better document the kind of block code that would be
useful with respect to a particular method?

I’m not sure what this question is. I speak perfect English, too. =)

How would this, and related ideas, work in a distributed environment,
where one might wish to differentiate site-specific capabilities?

Don’t laugh at me, but: what?

Sean O'Dell
···

On Friday 21 November 2003 07:23 am, Mark Wilson wrote:

My own views on interface crystallization:

···

On Sat, 22 Nov 2003, Mark Wilson wrote:

1. It should not be done in-line, but rather through a separate express

creation of an interface table. [Note: one of the nice things about the

way Ruby (and other languages) does things is the inline creation of

dispatch on type tables for generic operators through the use of

classes in an object system. It would be bad to complicate this and

other elements of Ruby’s human interface by also putting interface

“contracts” inline with Ruby’s current (usually very comprehensible)

class declaration system.]

This is a wonderful idea. Let me restate it to make sure I understand it.
Just as you can do the following:

class Person
def greet(other_person)
other_person.to do
say "hello"
end
end
end

class Person
def some_other_method
end
end

…(I’ve defined class Person somewhere, but I can always open up the
class again and define something else in it): it would be wonderful if
you can either inline it or make it external in a similar fashion.
I’m not sure what that would look like, but for those of us who don’t want
to use this feature, we could make sure that any “interface” declarations
are contained in separate files and can be excluded when we program.

I think the ability to do this would make the whole idea a lot more
palatable to a lot of us.

Chad

Well, this is certainly much simpler to implement.

Sean O'Dell
···

On Friday 21 November 2003 03:53 pm, Yukihiro Matsumoto wrote:

Hi,

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

Some of the things we gain were listed in the proposal.

As to benefit: it depends on who you care about. Programmers, and
especially library authors, gain a way to help people learn a little
about their code and to catch potential errors in pitfalls. Project
developers gain pretty much the same things: the ability to share code
and help their co-workers understand a little more about their code and
to help prevent them from making some obvious mistakes. We also gain
some speed in debugging: where interfaces are used by people unfamiliar
with the code they are calling into (through ignorance and lack of
documentation) it’s faster responding to a nice error message about type
incompatibilities than it is to wonder about an error regarding method
calls. Project managers are also far more likely to implement Ruby in
their projects if they feel it is as safe as what they need, and type
checking is one of the safety catches that a lot of people have grown
comfortable with. It’s also something Python doesn’t have, and will be
one of the things you can flat-out say “we have it, they do not.”

Worth it? In my opinion, absolutely.

In my opinion, not much. You’ve mentioned interface contract would:

(a) help learning code.
(b) gain speed in debugging by more check (and better message).
(c) make project manager feel better for more safety.
(d) allow us to say “we have something you don’t have” to Python
people.

Among these, only (b) appeal to me. (a) can be done better by RDoc
documents. For (c) and (d), I don’t care about selling Ruby to
anyone.

I prefer Jim Weirich’s idea in [ruby-talk:86007], utilizing method
combination.

in the library code foo.rb:

require ‘foo_if’

which defines interface

you can comment out from production code

class Foo
def greet(hi)
hi.display
print “\n”
end
end

in the foo_if.rb:

class Foo
def greet:pre(hi)
assert hi.respond_to? :display
end
end

with probably interface checking cosmetic.

[On how one might ‘implement’ interfaces:]

I prefer Jim Weirich’s idea in [ruby-talk:86007], utilizing method
combination.

in the library code foo.rb:

require ‘foo_if’

which defines interface

you can comment out from production code

class Foo
def greet(hi)
hi.display
print “\n”
end
end

in the foo_if.rb:

class Foo
def greet:pre(hi)
assert hi.respond_to? :display
end
end

with probably interface checking cosmetic.

I’m not buying into the interface debate one way or the other, but a
related question here is: how do you envisage :pre, :post, etc.,
working if they are defined multiple times?

This is important because they could be used to implement some
aspect-oriented code, and then also be used to implement some
interface checking.

For example:

class Example
def meth(o)
# some code on ‘o’
end

def meth:pre(o)
  logger.info "About to process #{o}"
end

def meth:pre(o)
  assert o.responds_to? :display
end

end

Do both the :pre method wrappers get executed? If so, in what order?
If not, which one does? And why not execute both?

Gavin

···

On Saturday, November 22, 2003, 10:53:39 AM, Yukihiro wrote:

[snip]

  1. The table would include fields specifying whether the interface is
    mutable or immutable, the number of arguments and “types” of arguments
    a method takes, exceptions to raise if the particular interface
    element
    fails, and so on.

Just for example, why would someone need a mutable interface?

I think Ruby has (abstract) undeclared mutable interfaces now. I think
that the programmer(s) should have the option of when they want to lock
an interface on a case-by-case basis, rather than lock everything by
bringing in the interface infrastructure.

  1. A skeleton table could be generated from existing code, with
    suitable default values (such as mutable interface, argument “type”
    set
    to Object, etc. The developer would choose where to crystallize an
    interface element and forego additional possible dynamism.

You mean, sort of a class extractor that can generate an interface
template
that they can then edit to suit their needs? If so, that’s something
that
could be a third-party utility.

I’m thinking that the whole thing should exist, if at all, completely
separate from Ruby, at least until it has been “seasoned” with
extensive and widespread use.

  1. The table could be queried to produce detailed documentation
    information and/or included at runtime as a constraint on execution.

Is the table different from the interface description I describe in
the wiki?
The proposal now already plans to constrain method calls based on the
interface description.

I think just a different metaphor for the “interface” to the interface
descriptions. I think Ara Howard’s thoughts on doing it inline are
better than my table suggestion.

  1. In the future, one could perhaps also use the table to guide a Ruby
    compiler as to when a form of “static typing” can be used to optimize
    a
    particular program (according to the instructions of the developer).

Perhaps … but I think going this far might too far off Ruby’s path.

Rite. :slight_smile:

I do not, however, think the proposal is necessarily a good idea. It
does seem very costly, and the magnitude of the benefit is not clear
to
me. A way to make it lower-cost would be good, because then it would
be
easier to try.

It’s pretty cheap in terms of run-time overhead. It really does only
the bare
minimum I can imagine any form of type checking doing. It only tests
for an
“interface compliance” flag at run-time; that’s little more than a
test for
true/false. How much cheaper can it be?

I think there is a large potential cost (and benefit) on the human
interface side, the full extent of which is not knowable in advance of
getting some working implementations. I think doing it in Ruby and
keeping class and method modeling separate from interface declaration
lower the cost of trying it.

Some questions:
Have the main proponents (and critics) looked at how Objective C
handles this and similar issues?

No, but I’m open to ideas. =)

Unfortunately, I asked the question because I know only enough about
Objective C to know that it is compiled and dynamically typed and has
optional static type declarations.

[snip]

Regards,

Mark

···

On Nov 21, 2003, at 1:33 PM, Sean O’Dell wrote:

How does that work? I envisaged that classes would be “tagged” as
implementing a set of interfaces, then that set propagating to objects
created from that class upon instantiation. That way objects too would
be aware of which interfaces they supported to facilitate quicker
parameter type (interface) checking. If it’s the Interface object which
keeps a set of supporting classes, doesn’t that require a search through
them to find, at the point of instantiation, which interfaces the class
supports?

···

“Ara.T.Howard” ahoward@ngdc.noaa.gov wrote:

  1. Interfaces HAVE implementations vs. classes IMPLEMENTING an
    Interface. this is vastly simpler with respect to backward compat:

BAD:

class MyClass
  # requires change to class 'Class'
  implements Interface
end

GOOD:

interface.impl << MyClass

# no change to class 'Class' needed


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

I have considered this too. I would like to propose an alternate/augmenting
syntax that has a simple definite rule for how they work together:

def dothis
print “A”
end

def dothis
pre
print “B”
post
print “C”
end

dothis # => BAC

def dothis
pre
print “E”
post
print “D”
end

dothis # => EBACD

def dothis
pre
print “F”
main
print “Z”
post
print “G”
end

dothis # => FEZDG

This final result might seem odd at first, but it is a very simple system.
Every subsequent definition of a pre and/or post, causes the latter to become
part of main. Thus every method has a pre, main and post once defined and
every subsequent addition moves them a step inward to main.

Another example, this time with : syntax.

def dothis
print “A”
end

def dothis:post
print “B”
end

dothis # => AB

def dothis:post
print “C”
end

dothis # => ABC

def dothis:main
print “Q”
end

dothis # => QC

def dothis
print “Z”
end

dothis # => Z (still can redefine)

What do you think?

-t0

···

On Saturday 22 November 2003 07:19 am, Gavin Sinclair wrote:

I’m not buying into the interface debate one way or the other, but a
related question here is: how do you envisage :pre, :post, etc.,
working if they are defined multiple times?

Do both the :pre method wrappers get executed? If so, in what order?
If not, which one does? And why not execute both?

I really hope that ruby will give an message (method redefined) : I don't
want to learn a new language and you have module to do what you want.

Guy Decoux

Well, I’m not sure what I want in this case. Wrapping methods is a
great idea to satisfy a common idiom. I think it does seem a bit
wrong not to allow multiple wrappers, though. The idiom as it stands
(alias method to something else, and call alias from redefined method)
can be used to wrap a method several times if desired.

What method are you talking about? Oh, aspectr I suppose.

Gavin

···

On Saturday, November 22, 2003, 11:47:50 PM, ts wrote:

Do both the :pre method wrappers get executed? If so, in what order?
If not, which one does? And why not execute both?

I really hope that ruby will give an message (method redefined) : I don’t
want to learn a new language and you have module to do what you want.

Well, I'm not sure what I want in this case. Wrapping methods is a
great idea to satisfy a common idiom. I think it does seem a bit
wrong not to allow multiple wrappers, though. The idiom as it stands

Perhaps in this case, you can also have multiple def in the same class :slight_smile:

What method are you talking about?

   module B
      def a:pre
      end
   end

   class A
      include B

      def a:pre
      end

      def a
      end
   end

Guy Decoux