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