Please keep in mind that interfaces are invented as simple additional
virtual method tables to avoid multiple inheritance. And passed around
instead of the object.
This way i could get rid of the explicit callbacks and just define for
my dialog_controller to inherit the button_listener and add it to the
button. Works find. unless my dialog has two buttons.
If i could implement the button_listener interface twice i could use
this.
I'm using eiffel like syntax now cause what they have is almost what i
want:
(current is the objects this or self reference in Eiffel)
The button would look like
--------------------------------------------------------------------------------------------------------
class Button
register_listener (obj: Button_Listener) is .... end
end
--------------------------------------------------------------------------------------------------------
And in my dialog controller it would look like
--------------------------------------------------------------------------------------------------------
class My_Dialog_Controller
implements
Button_Listener as listener1
on_press as cancel_button_pressed
Button_Listener as listener2
on_press as okay_button_pressed
okay_button_pressed is
do io.put_string("pressed okay") end
cancel_button_pressed is
do io.put_string("pressed cancel") end
-- handler code
setup_dialog is
local
cancel_button, okay_button: Button
do
cancel_button.register_listener(current as listener1)
okay_button.register_listener(current as listener2)
end
end -- class MyDialogController
--------------------------------------------------------------------------------------------------------
Other examples are objects which implements a compare function and a
sortable container
taking those objects and sorting based on different criterias.
So what do you think are advantages of multiple interfaces in contrast
to
explicit other ways to provide callback functions. As i said
technically interfaces are just jump tables.
Oh yes, there should be a way to specify that all other methods of the
interface are not defined and should be predefined values (ignores).
For example if the Button_Listener is also providing a
callback for on_mouse_enter events etc. Something like
implements
Button_Listener as listener2 only
on_press as okay_button_pressed
on_key_press as check_for_key_shortcuts
Please comment.
I disagree, as there are many conceptual differences between interfaces and
MI, and after having dealt with some of the "subtleties" in implementing an
object system with both mechanisms (and lots of compiler-related work), I
can fairly safely assert that although they "seem" similar, they are in many
ways "inherently" different.
the concept of MI is that a class "physically" represents several classes,
and so can be cast as needed.
the concept of interfaces is that the interface is itself disjoint from the
object, and that an object "fits into" an interface (implementing an
interface then mostly says "yes, I can do this", rather than "I incorporate
this into myself").
so, we have an interface variable, and an object implementing an interface,
and then said object "can" be assigned to this variable and manipilated
as-if it were this interface. the interface then need not be a part of the
physical structure of an object, it need only contain objects of classes
which implement it.
similarly, in MI, an inherited class adds members to the derived class,
whereas an interface demands that the class itself define these members, ...
similarly, in newer incarnations of the JVM, it is possible to dynamically
(as-in, at runtime) add interfaces to classes and objects, which is
something which makes no real conceptual sense with MI (since to do so would
imply physically changing the object in question).
...
this is why it makes some conceptual sense to allow MI to multiply inherit
from a single base class, but little sense with interfaces.
"I can read, and I can also read".
>
> If i could implement the button_listener interface twice i could use
> this.
> I'm using eiffel like syntax now cause what they have is almost what i
> want:
> (current is the objects this or self reference in Eiffel)
>
<snip>
>
> So what do you think are advantages of multiple interfaces in contrast
> to
> explicit other ways to provide callback functions. As i said
> technically interfaces are just jump tables.
>
> Oh yes, there should be a way to specify that all other methods of the
> interface are not defined and should be predefined values (ignores).
> For example if the Button_Listener is also providing a
> callback for on_mouse_enter events etc. Something like
>
<snip>
if you want interfaces, use interfaces.
if you want MI, use MI.
if you want both, implement both (they may or may not utilize some similar
underlying machinery).
trying to mutilate one into the other is IMO ill advised...
I am not sure I understand you.
> class My_Dialog_Controller
> implements
> Button_Listener as listener1
> on_press as cancel_button_pressed
> Button_Listener as listener2
> on_press as okay_button_pressed
Why would you want My_Dialog_Controller to implement Button_Listener
(at all, let alone twice)?
Are you going to pass a My_Dialog_Controller instance to a function that
expects an object that implements that interface? If so, how would that
function know which of the two implementations of the interface to use?
In your example, what I think you want to do is have one function
(method, whatever) called when one button is pressed, and another function
called when the other button is pressed.
My preferred solution for that would be to make the functions be
first-class objects, and write something like:
--------------------------------------------------------------------------------------------------------
-- Button_Listener is the type of callback function that
-- Button's register_listener method expects.
class Button
register_listener (obj: Button_Listener) is .... end
end
class My_Dialog_Controller
okay_button_pressed is
do io.put_string("pressed okay") end
cancel_button_pressed is
do io.put_string("pressed cancel") end
-- handler code
setup_dialog is
local
cancel_button, okay_button: Button
do
-- in the below, "current:okay_button_pressed" is supposed to
-- _refer_ to the method, not actually call it. So
-- current:okay_button_pressed will return a reference to an
cancel_button.register_listener(current:okay_button_pressed)
okay_button.register_listener(current:cancel_button_pressed)
end
end -- class MyDialogController
--------------------------------------------------------------------------------------------------------
Regards,
Bob
> In your example, what I think you want to do is have one function
> (method, whatever) called when one button is pressed, and another function
> called when the other button is pressed.
Yes but assume you have a listbox and you want to catch
list item selects, mouse double clicks, key presses, mouse context
menu clicks...
With one method it doesn't work well but if you have a potentially
large number of callbacks (remember the many many WM_xxx messages on
windows)
it becomes much smarter - or at least less code then registering each
callback
on it's own.
From the implementation point of a language which has interfaces, they
are
just function pointer tables. So i wonder if i can't reuse them for a
different
purpose.
> Other examples are objects which implements a compare function and a
> sortable container
> taking those objects and sorting based on different criterias.
Others are doubly-linked lists. You can make an item to participate in
multiple lists. There are numerous cases where an interface is additive.
> So what do you think are advantages of multiple interfaces in contrast
> to explicit other ways to provide callback functions. As i said
> technically interfaces are just jump tables.
This is a different story. An interface operation is always better than a
callback independently on the way the interfaces are composed in the type
algebra (e.g. additive vs. not).
Callback is procedural decomposition. Interface is OO. The latter has a
higher abstraction level. So there is no question.
> Oh yes, there should be a way to specify that all other methods of the
> interface are not defined and should be predefined values (ignores).
It is already so. Interface = abstract type with some (or all) operations
undefined (abstract). Non-abstract operations (defaults) are inherited. No
problem.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
> trying to mutilate one into the other is IMO ill advised...
Thats exactly the point. I'm working on an Eiffel compiler but found
the
concepts too difficult and MI not really usefull in my 8 years of
Eiffel
programming.
Thats why i'm now working on Edison an Eiffel based language with
interfaces instead of MI (well and a few other additional features)
Again, I don't think I am following you.
Assume, indeed, that we have a listbox. Now we want to catch the events
you mention ... and do what? Could you elaborate the example?
> With one method it doesn't work well but if you have a potentially
> large number of callbacks (remember the many many WM_xxx messages on
> windows)
> it becomes much smarter - or at least less code then registering each
> callback
> on it's own.
What doesnt't work well? What becomes much smarter?
I don't know what you mean by "the many WM_xxx messages on windows". That
could be my lack of knowledge; I've never written more than a simple
hello world dialog box for Windows.
I hope you can clarify what you mean. Perhaps it would help if you
worked out the example you have in mind, provided a description of what
you want the program to do, how you would implement that without your
proposal, and how your proposal makes things better.
Regards,
Bob
> "llothar" <scholz...@gmail.com> wrote in message
> news:78704f49-4fd9-4cbf...@s31g2000yqs.googlegroups.com...
>> Lets say you have something like java (i have forgotten the used
>> syntax there so no example code)
>> My example is from a GUI where you have a button which is using a
>> button listener interface which has
>> a on_pressed interface method.
>>
>> Please keep in mind that interfaces are invented as simple additional
>> virtual method tables to avoid multiple inheritance. And passed around
>> instead of the object.
>>
>
> I disagree, as there are many conceptual differences between interfaces and
> MI, and after having dealt with some of the "subtleties" in implementing an
> object system with both mechanisms (and lots of compiler-related work), I
> can fairly safely assert that although they "seem" similar, they are in many
> ways "inherently" different.
I disagree. There is absolutely no difference. Java interfaces is a poor
man's MI.
> the concept of MI is that a class "physically" represents several classes,
> and so can be cast as needed.
There is no physical representation, it is an incredibly flawed idea. The
concept of inheritance is not about representation, it is about
*substitutability*. Note the difference. A substitutability could be
achieved by means of certain representations, or by other means.
Representation is an implementation issue, totally out of scope. Interface
is to abstract implementation away.
> the concept of interfaces is that the interface is itself disjoint from the
> object, and that an object "fits into" an interface (implementing an
> interface then mostly says "yes, I can do this", rather than "I incorporate
> this into myself").
Interface is a type, object is an instance of. They cannot be same.
> similarly, in MI, an inherited class adds members to the derived class,
> whereas an interface demands that the class itself define these members, ...
Members is a part of the interface. There is no semantic difference between
the operation ".Field" applied to the object X, e.g. X.Field and an
operation Field applied to X like Field (X). Nothing here says anything
about the memory layout of X.
Consider X of the type 2D point. It can implement the interface of
Euclidean co-ordinates with the members .x, .y and the interface of polar
co-ordinates with the members .magnitude, .angle. What is the
representation of X, is of nobody's interest.
> if you want interfaces, use interfaces.
> if you want MI, use MI.
> if you want both, implement both (they may or may not utilize some similar
> underlying machinery).
>
> trying to mutilate one into the other is IMO ill advised...
Nope. A good designed language should have no explicit interfaces. It
should be always possible to inherit an interface from a concrete type.
Interface = type with all operations abstract. Kill all implementations of
the type, the rest is the interface of.
but, the original post was about mutating one into the other, hence me
taking issue...
it is possible to support both, and I did this in my object system
(although, the MI support is not exactly good, since I didn't care so much
about the MI case...).
errm, I have no real idea what interfaces have to do with registering
callbacks...
> From the implementation point of a language which has interfaces, they
> are
> just function pointer tables. So i wonder if i can't reuse them for a
> different
> purpose.
just a bit of trivia:
my framework did not implement interfaces via function-pointer tables...
the system is instead held together via the use of a collection of (fairly
large) hash tables...
(the hash is then used to resolve the interface method to the correct
virtual method for a given class).
it actually seems to work fairly well in my case.
I think there are several other VMs that implement their object system this
way...
they differ in the subtleties...
this is about like saying that abstract references are poor mans'
pointers...
an abstract reference and a pointer are essentially different entities, even
if they serve a similar role and may be implemented similarly.
>> the concept of MI is that a class "physically" represents several
>> classes,
>> and so can be cast as needed.
>
> There is no physical representation, it is an incredibly flawed idea. The
> concept of inheritance is not about representation, it is about
> *substitutability*. Note the difference. A substitutability could be
> achieved by means of certain representations, or by other means.
> Representation is an implementation issue, totally out of scope. Interface
> is to abstract implementation away.
>
but, MI is related to classes, and classes are essentially a physical
representation (similar to a struct, ...).
similarly, MI generally represents the unioning of several classes into a
composite, rather than exporting a particular interface.
similarly, this is the basis for the existence of concepts such as "virtual
inheritance", ...
>> the concept of interfaces is that the interface is itself disjoint from
>> the
>> object, and that an object "fits into" an interface (implementing an
>> interface then mostly says "yes, I can do this", rather than "I
>> incorporate
>> this into myself").
>
> Interface is a type, object is an instance of. They cannot be same.
>
class Bar: Baz, IFoo { ... }
Bar obj; //declare obj, which is an object (reference)
IFoo iobj; //declares iobj, which is an interface
obj=new Bar(); //new object instance
iobj=obj; //shoves object into interface
>> similarly, in MI, an inherited class adds members to the derived class,
>> whereas an interface demands that the class itself define these members,
>> ...
>
> Members is a part of the interface. There is no semantic difference
> between
> the operation ".Field" applied to the object X, e.g. X.Field and an
> operation Field applied to X like Field (X). Nothing here says anything
> about the memory layout of X.
>
the layout exists within the implementation.
multiple-interfaces essentially brings with it the idea of correlation with
the physical representation, in a manner similar to multiple-inheritence.
> Consider X of the type 2D point. It can implement the interface of
> Euclidean co-ordinates with the members .x, .y and the interface of polar
> co-ordinates with the members .magnitude, .angle. What is the
> representation of X, is of nobody's interest.
>
possibly, however, multiple-inheritence, if used, carries with it semantics
of how the layout behaves in practice.
class Foo { ... };
class BarA: public Foo { ... };
class BarB: public Foo { ... };
class Baz: public BarA, public BarB;
conceptually, Baz contains 2 different versions of Foo:
BarA::Foo, and BarB::Foo.
Baz *baz;
Foo *foo;
baz=new Baz();
foo=baz; //errm, which Foo?...
these semantics would not be sensible with interfaces, since an interface is
separate from the underlying representation of a class.
>> if you want interfaces, use interfaces.
>> if you want MI, use MI.
>> if you want both, implement both (they may or may not utilize some
>> similar
>> underlying machinery).
>>
>> trying to mutilate one into the other is IMO ill advised...
>
> Nope. A good designed language should have no explicit interfaces. It
> should be always possible to inherit an interface from a concrete type.
>
I disagree, and as well this is not commonly accepted semantics.
> Interface = type with all operations abstract. Kill all implementations of
> the type, the rest is the interface of.
>
this would imply a VERY different concept of MI than is generally held, and
would (I think) essentially eliminate the whole point of the concept of
multiple-interfaces.
> "Dmitry A. Kazakov" <mai...@dmitry-kazakov.de> wrote in message
> news:1vmb1rflm4mvw.1932a7xbqa3nw$.dlg@40tude.net...
>> On Wed, 18 Nov 2009 09:58:02 -0700, BGB / cr88192 wrote:
>>
>>> the concept of MI is that a class "physically" represents several
>>> classes, and so can be cast as needed.
>>
>> There is no physical representation, it is an incredibly flawed idea. The
>> concept of inheritance is not about representation, it is about
>> *substitutability*. Note the difference. A substitutability could be
>> achieved by means of certain representations, or by other means.
>> Representation is an implementation issue, totally out of scope. Interface
>> is to abstract implementation away.
>
> but, MI is related to classes, and classes are essentially a physical
> representation (similar to a struct, ...).
Nope. Class is a set of types. Nothing is said about the representations
of. The members of the set share some common desired properties, which are
formalized as an interface, contract etc. It is said that the members
(types) of the class implement the interface of.
> similarly, MI generally represents the unioning of several classes into a
> composite, rather than exporting a particular interface.
MI = construction of a type that is a member of several classes (sets of
types). Several -> multiple.
> similarly, this is the basis for the existence of concepts such as "virtual
> inheritance", ...
I see no connection. What you (following C++) call "virtual" is an
idempotent way to inherit from T:
T + T + T = T
Non-virtual is an additive way:
T + T + T = (T, T, T)
The OP asked about the second way. BTW, C++ supports both.
>>> the concept of interfaces is that the interface is itself disjoint from the
>>> object, and that an object "fits into" an interface (implementing an
>>> interface then mostly says "yes, I can do this", rather than "I
>>> incorporate
>>> this into myself").
>>
>> Interface is a type, object is an instance of. They cannot be same.
>
> class Bar: Baz, IFoo { ... }
>
> Bar obj; //declare obj, which is an object (reference)
> IFoo iobj; //declares iobj, which is an interface
>
> obj=new Bar(); //new object instance
> iobj=obj; //shoves object into interface
I have no idea what does this mean. Object is not an interface of itself.
>> Members is a part of the interface. There is no semantic difference between
>> the operation ".Field" applied to the object X, e.g. X.Field and an
>> operation Field applied to X like Field (X). Nothing here says anything
>> about the memory layout of X.
>
> the layout exists within the implementation.
So what? Implementation and interface are separated per software design
principle having exactly this name.
>> Interface = type with all operations abstract. Kill all implementations of
>> the type, the rest is the interface of.
>
> this would imply a VERY different concept of MI than is generally held,
http://en.wikipedia.org/wiki/Interface_%28computer_science%29
> and
> would (I think) essentially eliminate the whole point of the concept of
> multiple-interfaces.
How so? In fact it is your concept that eliminates interfaces. If the
representation is exposed then interface becomes a function of the
representation. This is how the languages of the first generations dealt
with this about 50 years ago. But almost instantly people understood that
this was insufficient both semantically and practically.
It is wrong semantically, because computer representations are in most
cases merely models of things that exist outside them and even cannot be
adequately represented in a Turing machine. Example: Real number, Customer.
So there is an abstraction model layer anyway and the language that
supports this kind of abstraction can easily do it for machine objects as
well. This is how interfaces appear. This was commonly recognized as a huge
step forward in software design.
It is wrong practically, because it is technically impossible to deduce
interface from the representation, a halting problem, you know, and even if
not it is terribly slow to verify if two representations are equivalent.
And even to define "equivalence" of representations requires interfaces
anyway: 1 at the address 0x001000 is equivalent to 1 at the address
0x002000. It might be also equivalent to "1", or maybe "one", or Pi**0 etc.
Well, I don't know Eifel, so I can only guess.
> So what do you think are advantages of multiple interfaces in contrast to
> explicit other ways to provide callback functions. As i said technically
> interfaces are just jump tables.
Actually I see two problems.
One is minor: it is incompatible with interfaces being a part of a VMT.
This is easy to see, the class would have to have two entries for said
method, each for both interfaces, with the same names.
There are ways around that, but it would be less a class implementing an
interface and more a class having multiple aggregated other objects.
The other is a severe limitation: normal listener or multiple dispatch
systems can be extended runtime. Even if you would somehow make it work at
the VMT level, you would keep this problem, since it is a purely compiletime
construct.
To solve that you can go from the VMT system to a more smalltalkish OO
system, but what would be the benefit?
I don't see how that is possible with a normal VMT based system. Care to
explain? Or do you mean a conversion instead of a cast?
usually, the way MI works is that the classes are placed end-to-end in
memory, with multiple VTables, ...
casting in the MI case may then adding in an offset, essentially giving a
pointer to one of the sub-classes...
gramted, this is not how my implementation of MI worked:
in my case, I just sort of did a hack where there was only (physically) SI,
and the MI case essentially created a new (hacked) root class which flagged
itself as MI.
if a field/method handle from one of the base classes was used, it would be
caught and re-routed through the hash (similar to how I handled interfaces),
which would redirect the request to the correct member in the new class.
the problem though is that this can't effectively fully emulate C++ style
inheritence, since a given handle from a given base-class can only refer to
a single possible member in the new class.
later, I decided that this object system would, simply, not be used for C++
style classes (C++ style classes instead being structured according to the
IA-64 ABI...).
eventually, I gave up on trying to support C++, noting that it was far more
effort than I was willing to expend on it...
at present, C and Java are my only current "actively supported" languages,
with C as primary and Java as secondary. Java support is incomplete, but is
partially supported both by a JBC interpreter, and by trans-compiling JBC to
C, but the direct Java -> native compiler is stalled...
Java is then supported by JBC, and C is supported both natively, and via
interpreted x86 (in the form of a simulatated POSIX-style environment,
although the interpreter has not moved much beyond "trivial" apps, mostly
due to lacking library faciliities, particularly, facilities for
communicating effectively with the native host app...).
granted, it is almost to the level where I could probably effectively port
Doom or Quake to the thing, although I am not sure if there is much point...
So it is a conversion, not a pure cast (reinterpretation of typed memory).
Note that you can hide any behaviour if you are willing to go that far, if
you store enough metadata in your class, including returning interfaces.
at the language level, it is a cast, but yes, something more than a simple
cast takes place...
granted, if you cast a double to a long, something more happens there as
well, so I was using 'cast' in a slightly looser sense...
God Bless America!
"BGB / cr88192" <cr8...@hotmail.com> wrote in message
news:he246p$h6k$1...@news.albasani.net...