comp.lang.ada
 help / color / mirror / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* Re: How to check syntax with GNAT?
  @ 2017-07-13  5:47  8% ` Simon Wright
  0 siblings, 0 replies; 99+ results
From: Simon Wright @ 2017-07-13  5:47 UTC (permalink / raw)


Victor Porton <porton@narod.ru> writes:

> $ make my-check 
> gnatmake -p -Plibrdf.gpr \
>                  -XLIBRARY_KIND=static -XOBJ_DIR=./obj-static -
> Xsoversion=librdf-ada.so.2.0.14 -XMODE=Install -XDEBUG_MODE=check
> gnatgcc -c -gnatc -gnat2012 -gnatc rdf-raptor-bnode.adb
> ...
> gprlib rdf-ada.lexch
> ar cr /home/porton/Projects/redland-bindings/ada/lib/librdf-ada.a 
> /home/porton/Projects/redland-bindings/ada/obj-static/rdf-raptor-bnode.o 
> /home/porton/Projects/redland-bindings/ada/obj-static/rdf-raptor-iostream.o 
> ...
> /usr//bin/ar: /home/porton/Projects/redland-bindings/ada/obj-static/rdf-
> raptor-bnode.o: No such file or directory
> gprlib: call to archive builder /usr//bin/ar failed
> gprbuild: could not build library for project librdf
> gnatmake: objects up to date.
>
> Why does it attempt to build object files and the library despite of -gnatc 
> switch and how to make it not to attempt build object files?

It doesn't attempt to build object files; that's why the gprlib call
fails. It does build .ali files, though.

You can get gnatmake (actually, gprbuild) to stop after the compilation
by using its -c flag:

   lockheed:test-stm32f4 simon$ gnatmake -p -P testbed -c -cargs -gnatc
   Setup
      [mkdir]        object directory for project Testbed
   Compile
      [Ada]          testbed.adb
      [Ada]          containing.adb
      [Ada]          dispatching.adb
      [Ada]          floating_point.adb
      [Ada]          heartbeat.adb
      [Ada]          interrupts.adb
   interrupts.adb:44:09: (style) bad casing of "Handler" declared at line 41
      [Ada]          iteration.adb
      [Ada]          last_chance_handler.adb
      [Ada]          so.adb
      [Ada]          streams.adb
      [Ada]          strings.adb
      [Ada]          memory_streams.adb
   lockheed:test-stm32f4 simon$ ls .build/*.o
   ls: .build/*.o: No such file or directory

(the style warning is a compiler bug that I haven't reported yet!)

I say above "gnatmake (actually, gprbuild)" because nowadays (GCC 7, not
GCC 6) gnatmake checks whether gprbuild is available and execs it if so.

I do checks like this in the editor, because why wait to check the
closure rather than checking the change you just made? (of course this
isn't totally effective for spec changes). But, I have it (Emacs
ada-mode) set up to actually compile the unit being edited, by

 '(ada-prj-default-check-cmd
   "gprbuild -c -u -f -gnatc -p -P ${gpr_file} ${full_current}")

because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66162#c3 .

^ permalink raw reply	[relevance 8%]

* Re: Your wish list for Ada 202X
  @ 2014-04-18 21:28 11%                                                     ` Randy Brukardt
  0 siblings, 0 replies; 99+ results
From: Randy Brukardt @ 2014-04-18 21:28 UTC (permalink / raw)


"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
news:brdegqFi62jU1@mid.individual.net...
> On 14-04-17 01:27 , Randy Brukardt wrote:
>> "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message
>> news:br8bu5Fg3keU1@mid.individual.net...
>>> On 14-04-15 03:08 , Randy Brukardt wrote:
...
>> There's also the point that a
>> dispatching call always has to be assumed to be to some body not even
>> written yet, so it's nearly impossible to say anything definitive about 
>> it's
>> contract.
>
> But the operation has been *specified*, even if no bodies exist,
> therefore the contract *from the caller's point of view* should have
> been defined. Otherwise there is not much point in using a class at all,
> or indeed in separating operation declarations and bodies.

Right, but here I'm a practicalist, rather than theortician. Humans write 
programs, and they tend to ignore anything not convinient. That certainly 
goes for whatever part of the contract is not formally specified and 
checked. So there is a lot more risk from re-dispatching than static 
binding, simply because there is more likelihood of error (unintentional or 
malicious).

>> ...
>>>> This last issue doesn't arise for a class-wide operation, where every
>>>> call is going to look at an object of TT as type TT.
>>>
>>> Except if TT inherits some operation from T, because then that operation
>>> looks at the object as type T. (I know that from the language-semantics
>>> point of view the inherited operation acts on TT, but the programmer
>>> wrote its code with T in mind.)
>>>
>>> If redispatching is suspect because it breaks the assocation of an
>>> operation with a unique type, then inheritance of operations must also
>>> be suspect, for the same reason.
>>
>> I understand your point, but I think the language-semantics view is 
>> actually
>> the correct one. One only allows inheritance of operations when the
>> implementation for T and for TT is thought to be identical. One hopes 
>> that
>> the author of TT considered that carefully!
>
> Well, I use redispatching only when I think that the operation being
> called is well specified and is or will be carefully implemented for
> each type in the class, as appropriate for that type. Same difference :-)

If you truly believe that you can "well specify" and "carefully implement" 
everything in your system, well, you're a better man than me. :-) I don't 
believe that about my code even when I write the entire thing at one time - 
much less when other people are involved or years pass between work. One of 
the things that attracted me to Ada in the first place is that it forces me 
to specify enough that it prevents many of my worst impulses. (Instantiating 
Unchecked_Conversion is painful enough to prevent most reuse of objects, for 
one example.) I doubt I'd ever get a lengthy C program to work!

>> It's true that maintenance of the T operation might in fact break the TT
>> operation (meaning that they should have different implementations), so
>> there is some additional danger in inheritance.
>
> Yes. In general, the more a program is "factored" into parts that are
> combined and invoked in many contexts, the harder it becomes to maintain
> proper behaviour in all contexts. Subprograms, inheritance, dispatching,
> redispatching all tend in this direction.

Right.

>> There is also danger in
>> inheritance that the author of TT didn't know about. (I think it would be
>> much better if all inheritance was explicit; but to be practical that 
>> would
>> require a rather different syntax than Ada uses, and thus such a thing 
>> would
>> not make sense in an Ada perspective.
>
> To make inheritance explicit, it seems to me that each inherited
> operation must be declared for the derived type, with its full profile,
> perhaps as
>
>   inherited procedure Foo (X: in T; ....);
>
> This would require just one new reserved word, "inherited", and does not
> feel like a "rather different syntax". Did you have something else in 
> mind?

The problem with this sort of syntax is that it's really wordy and tends to 
obscure the important issues (which is not the exact profile, as least 
unless you have a resolution problem). Remember all of the people that used 
renames to avoid using use clauses for Ada 83? (Maybe not, that was a long 
time ago.) They often had bugs like:
   function "+" (Left, Right : P.Big_Int) return P.Big_Int renames P."-";
where the profile is obscuring the critical differences.

I'd prefer a much simpler declaration of inheritance, something like:
   type Child is new Parent with ...
      with inherits => Foo, Bar, Blech;

where names not listed are hidden from all visibility unless overridden. 
(The Ada dispatching model insists that the routines exist, so for Ada all 
one could do would be to hide any uninherited operations from direct calls. 
One could imagine have uninherited operations raise Program_Error in 
dispatching as an alternative, but that's not ideal either because it makes 
a tripping hazard as Bob calls it. Thirdly, one could require all operations 
to be either inherited or overridden, but that just makes a new kind of pain 
for deriving types, especially for those of us who prefer incremental 
implementation of things).

Whether that's enough or if some alternative with optional profiles is 
necessary, I don't know. Most operations aren't overloaded, after all, so 
the profile is just noise.

                       Randy.




^ permalink raw reply	[relevance 11%]

* Re: Asynchronous Transfer of Control
  2014-04-10 22:49 13%   ` Randy Brukardt
@ 2014-04-10 23:16  0%     ` Adam Beneschan
  0 siblings, 0 replies; 99+ results
From: Adam Beneschan @ 2014-04-10 23:16 UTC (permalink / raw)


On Thursday, April 10, 2014 3:49:31 PM UTC-7, Randy Brukardt wrote:

> I don't think they are, but it doesn't matter. Annex D requires immediate 
> abort, so if you have Ada.Dispatching.Yield, you also have made everything 
> essentially an abort completion point.

Ah, I had forgotten about D.6.

                              -- Adam


^ permalink raw reply	[relevance 0%]

* Re: Asynchronous Transfer of Control
  2014-04-10 15:15 11% ` Adam Beneschan
@ 2014-04-10 22:49 13%   ` Randy Brukardt
  2014-04-10 23:16  0%     ` Adam Beneschan
  0 siblings, 1 reply; 99+ results
From: Randy Brukardt @ 2014-04-10 22:49 UTC (permalink / raw)


"Adam Beneschan" <adambeneschan@gmail.com> wrote in message 
news:b00eabf3-5933-4c43-a75f-7137cd3fb95d@googlegroups.com...
...
>If it's a mathematical calculation, chances are that it doesn't; however, 
>adding
>"delay 0.0;" statements at key places in the calculation would add abort
>compeltion points, and hopefully this statement would be implemented in a 
>way
>so that it isn't a severe drag on efficiency.

It shouldn't be, but our experience with Claw was that not all implementers 
got the memo. (At least not until we submitted Claw bug reports to them.)

>(There's also Ada.Dispatching.Yield, which the RM says is a "task 
>dispatching
>point", but it's not clear to me whether all task dispatching points are 
>also
>abort completion points--seems like they should be, but I'd have to check 
>the
>RM further.)

I don't think they are, but it doesn't matter. Annex D requires immediate 
abort, so if you have Ada.Dispatching.Yield, you also have made everything 
essentially an abort completion point.

I'm not sure why abort completion points and task dispatching points are 
different in the RM; I'm pretty sure our implementation treats them as the 
same thing. Maybe that's also because of Annex D - task dispatching point is 
defined there and that's too late for the formal semantics of abort.

                                  Randy.





^ permalink raw reply	[relevance 13%]

* Re: Asynchronous Transfer of Control
  @ 2014-04-10 15:15 11% ` Adam Beneschan
  2014-04-10 22:49 13%   ` Randy Brukardt
  0 siblings, 1 reply; 99+ results
From: Adam Beneschan @ 2014-04-10 15:15 UTC (permalink / raw)


On Thursday, April 10, 2014 3:41:15 AM UTC-7, AdaMagica wrote:
> This piece of code is very similar to RM 9.7.4(10-13).
> 
> It seems that GNT GPL 2013 on Windows does ot work correctly.
> 
> with Ada.Text_IO;
> use  Ada.Text_IO;
> with Ada.Calendar;
> use  Ada.Calendar;
> 
> procedure Run_It is
> 
>   Line: String (1 .. 10);
>   Last: Natural;
>   Now : constant Time := Clock;
> begin
>   select
>     delay 10.0;
>     Put_Line ("aborted   " & Integer'Image (last) & Duration'Image (Clock - Now));
>   then abort
>     Put (" > ");
>     Get_Line (Line, Last); 
>     Put_Line ("terminated" & Integer'Image (last) & Duration'Image (Clock - Now));
>   end select;
> end Run_It;
> 
> This is the result if I only press <return> after the delay has expired:
> 
> C:\...\Ada-Kode\run_it
> 
> terminated 0 26.688941821
> aborted    0 26.689382659
> 
> [2014-04-10 12:24:42] process terminated successfully (elapsed time: 26.92s)
> 
> I.e. the abortable_part is not aborted.
> 
> Am I missing something? Or is this expected behaviour on Windows?

The RM says that when the abortable_part is aborted, it doesn't actually have to stop executing until the next abort completion point.  The abort completion points are defined in 9.8(16-19).  The abortable_part *could* be terminated at other points (as long as they're not inside abort-deferred operations, see 9.8(6-11)), but it's up to the implementation.

I/O operations like Get_Line aren't abort completion points.  It seems reasonable that an implementation *should* provide for an I/O operation to be aborted if it could be forced to wait (e.g. input from the console, waiting for a socket connect, etc.).  But the RM doesn't require it.
  
Based on that, I think the examples in 9.7.4(10-13) are flawed.  While those kinds of examples may be the intended use of the asynchronous_select, they don't necessarily work, and the RM should probably make it clear that the effect is implementation-dependent.  In particular, the comment in the first example, "-- This will be abandoned upon terminal interrupt", appears to be making an assertion that is not necessarily true.  I'm planning on sending something to Ada-Comment about this.  (Don't know why I didn't notice this before.)  In the second example, we don't know whether Horribly_Complicated_Recursive_Function contains any abort completion points or not.  If it's a mathematical calculation, chances are that it doesn't; however, adding "delay 0.0;" statements at key places in the calculation would add abort compeltion points, and hopefully this statement would be implemented in a way so that it isn't a severe drag on efficiency.  (There's also Ada.Dispatching.Yield, which the RM says is a "task dispatching point", but it's not clear to me whether all task dispatching points are also abort completion points--seems like they should be, but I'd have to check the RM further.)

My understanding is that Windows makes it more difficult than, say, Unix/Linux to forcibly interrupt a thread, without that thread's cooperation.  That is, if I recall correctly, the thread to be interrupted has to use different versions of I/O API calls, and/or special API routines, that enable the operation to be interrupted.  I think that system designers have come to believe that allowing threads to be interrupted at any arbitrary point causes problems.  As I mentioned above, it may be a reasonable expectation that a keyboard input subprogram should allow for thread interruption, but others may have different opinions; anyway, it's not a requirement and GNAT apparently doesn't do it.

                                -- Adam 



^ permalink raw reply	[relevance 11%]

* C++/Ada dispatching
@ 2013-07-31 18:30  6% Tarek Ghaleb
  0 siblings, 0 replies; 99+ results
From: Tarek Ghaleb @ 2013-07-31 18:30 UTC (permalink / raw)


Hi everyone,

Here is the problem: given a C++ class Fl_Widget and a derived class
Fl_Window, I'd like to write a thick binding that wraps the C++ type
into an Ada Type and offers only a subset of the available operations,
plus do type conversions, etc. before calling the C++ operations. So
the basic idea is that an Ada Widget is in the form of,

   type Fl_Widget is abstract tagged limited record
      Base_Widget : access Class_Fl_Widget.Fl_Widget'Class;
   end record;

And here is an example: 

(Apologies for including so much code, I tried to strip it down as
much as possible but still give a complete example).

header file fl_widget.hpp:

  class Fl_Widget {
    int _width;
    int _height;
  public:
    void show();
    virtual void some_operation() { };
  protected:
    Fl_Widget();
    Fl_Widget(int width, int height);
  };

header file fl_window.hpp:

  #include "fl_widget.hpp"

  class Fl_Window : public Fl_Widget {
  public:
    Fl_Window();
    Fl_Window(int width, int height);
    void fullscreen();
    void some_operation();
  };

C++ file fl_widget.cpp:

  #include "fl_widget.hpp"
  #include <cstdio>

  Fl_Widget::Fl_Widget() {}

  Fl_Widget::Fl_Widget(int width, int height) {
    _width  = width;
    _height = height;
  }

  void Fl_Widget::show() {
    std::puts("view called");
  }

C++ file fl_window.cpp:

  #include "fl_window.hpp"
  #include <cstdio>

  Fl_Window::Fl_Window() {}

  Fl_Window::Fl_Window(int width, int height) : Fl_Widget(width, height)
  {
    std::puts("initialized window");
  }

  void Fl_Window::fullscreen() {
    std::puts("fullscreen called");
  }

  void Fl_Window::some_operation() {
    // empty
  }

generated Ada thin binding fl_widget_hpp.ads:

  pragma Ada_2005;
  pragma Style_Checks (Off);

  with Interfaces.C; use Interfaces.C;

  package fl_widget_hpp is

     package Class_Fl_Widget is
	type Fl_Widget is tagged limited record
	   u_width  : aliased int;
	   u_height : aliased int;
	end record;
	pragma Import (CPP, Fl_Widget);

	procedure show (this : access Fl_Widget'Class);  
	pragma Import (CPP, show, "_ZN9Fl_Widget4showEv");

	procedure some_operation (this : access Fl_Widget);
	pragma Import 
          (CPP, some_operation, "_ZN9Fl_Widget14some_operationEv");

	function New_Fl_Widget return Fl_Widget;
	pragma CPP_Constructor (New_Fl_Widget, "_ZN9Fl_WidgetC1Ev");

	function New_Fl_Widget 
	   (width : int; height : int) return Fl_Widget;
	pragma CPP_Constructor (New_Fl_Widget, "_ZN9Fl_WidgetC1Eii");


     end;
     use Class_Fl_Widget;
  end fl_widget_hpp;

generated Ada thin binding fl_window_hpp.ads:

  pragma Ada_2005;
  pragma Style_Checks (Off);

  with Interfaces.C; use Interfaces.C;
  with fl_widget_hpp;

  package fl_window_hpp is

     package Class_Fl_Window is
	type Fl_Window is limited new
	fl_widget_hpp.Class_Fl_Widget.Fl_Widget with record
	   null;
	end record;
	pragma Import (CPP, Fl_Window);

	function New_Fl_Window return Fl_Window;
	pragma CPP_Constructor (New_Fl_Window, "_ZN9Fl_WindowC1Ev");

	function New_Fl_Window 
	  (width : int; height : int) return Fl_Window;
	pragma CPP_Constructor (New_Fl_Window, "_ZN9Fl_WindowC1Eii");

	procedure fullscreen (this : access Fl_Window'Class);
	pragma Import (CPP, fullscreen, "_ZN9Fl_Window10fullscreenEv");

	procedure some_operation (this : access Fl_Window);
	pragma Import 
          (CPP, some_operation, "_ZN9Fl_Window14some_operationEv");
     end;
     use Class_Fl_Window;
  end fl_window_hpp;

and the Ada file widget.ads:

  with fl_widget_hpp;

  package Widget is

     type Fl_Widget is abstract tagged limited record
	Base_Widget : access 
          fl_widget_hpp.Class_Fl_Widget.Fl_Widget'Class;
     end record;

     procedure Show (Object : Fl_Widget);

  end Widget;

with body in widget.adb:

  package body Widget is

     procedure Show (Object : Fl_Widget) is
     begin
	Object.Base_Widget.show;
     end Show;

  end Widget;

and window.ads:

with Widget;

package Window is

   type Fl_Window is new Widget.Fl_Widget with null record;

   procedure Init (Object : in out Fl_Window);

   procedure Fullscreen (Object : Fl_Window);

end Window;

and body in window.adb:

  with fl_window_hpp; use fl_window_hpp;

  package body Window is

     type Base_Window_Access is access all Class_Fl_Window.Fl_Window;

     procedure Init (Object : in out Fl_Window) is
	Win : constant Base_Window_Access :=
	  new Class_Fl_Window.Fl_Window'(
					 Class_Fl_Window.New_Fl_Window
					   (width  => 500,
					    height => 500));
	--  Is there a better way to do this?
     begin
	Object.Base_Widget := Win;
     end Init;

     procedure Fullscreen (Object : Fl_Window) is
     begin
	Base_Window_Access (Object.Base_Widget).fullscreen;
	--  This fails with
	--  raised CONSTRAINT_ERROR : window.adb:36 tag check failed
     end Fullscreen;

  end Window;

and finally a driver to test this code:

  with Window;

  procedure Main is
     Win : Window.Fl_Window;
  begin
     Win.Init;
     --  Curiously, commenting this line out, no errors are raised and
     --  fullscreen() is called. (Although, Base_Widget is
     --  uninitialized/null here!)

     Win.Show;
     Win.Fullscreen;
  end Main;


I'm getting raised CONSTRAINT_ERROR : window.adb:36 tag check failed,
the line

	Base_Window_Access (Object.Base_Widget).fullscreen;

Also, I'm looking for related reading material. So far I've only found
a couple of GEM's on AdaCore and a section in the GNAT manual, and a
Green Hills `Mixing Ada and C++' report. Any recommendations?

Another question: when importing overloaded C++ functions, the
generated code with `g++ -fdump-ada-spec` fails to compile as it
imports the function twice, for example:

     function align 
       (this : access constant Fl_Widget'Class) 
        return FL_Enumerations_H.Fl_Align;
      pragma Import (CPP, align, "_ZNK9Fl_Widget5alignEv");

      procedure align 
        (this : access Fl_Widget'Class; 
         alignment : FL_Enumerations_H.Fl_Align);
      pragma Import (CPP, align, "_ZN9Fl_Widget5alignEj");

how should overloaded C++ functions be imported?

Tarek. 

-- 
Injustice anywhere is a threat to justice everywhere. -- Martin Luther
King, Jr.

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---


^ permalink raw reply	[relevance 6%]

* Re: Is this expected behavior or not
  2013-03-28 21:55  0%                                               ` Randy Brukardt
@ 2013-03-29 12:26  0%                                                 ` Dmitry A. Kazakov
  0 siblings, 0 replies; 99+ results
From: Dmitry A. Kazakov @ 2013-03-29 12:26 UTC (permalink / raw)


On Thu, 28 Mar 2013 16:55:34 -0500, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:cqf0yy6q930$.1sdzw45bc0c1w.dlg@40tude.net...

>> These are two data types, string and slice. Are you treating slice as an
>> Ada-subtype of string? I consider slice a member of same class as string,
>> yet a distinct type (in Ada sense). This is like 4.1.5, but in the same
>> type hierarchy.
> 
> I thought you might do that, but then you're going to have problems of 
> compatibility (Ada currently considers them the same type). An operation 
> like "&" cannot not allow mixed string operands (if you do allow that, you 
> make string literals ambiguous).

Right, if strings form a hierarchy, then "&" must be primitive and a
multi-method. There is no alternative to that. Even if you are going to add
a completely new set of string types without slices you still will have
this problem:

   declare
        X : New_String_Type;
        Y : A_Descendant_Of;
    begin
        ... X & Y ...;  -- Is this legal? Does it raise Constraint_Error?

The answers must be yes, no. And for this "&" must be a multi-method with
all combinations of argument and the result types defined. Making some of
them class-wide could reduce the number of combinations. And it will be
ambiguous with literals and other overloaded operations returning string
objects.

>>> Nobody wants "type cloning".
>>
>> It is a very useful building block to me. Anyway it is Ada 83 legacy.
> 
> Ada 83 derived types are virtually useless, and no one understood how they 
> worked.

What would you do if you need a new type with same properties. Copy-paste?
Example:

   type Position is <some positive number>;
   type Key is some <some positive number>;
   type Container is ...;

How do you prevent Position and Key mixed in Container operations if they
belong to same hierarchy?

>>> I don't think a version of untagged'Class that did not work on existing
>>> derived types would fly.
>>
>> Astonishing that you even considered that possibility. In my view they are
>> completely independent things.
> 
> You really have a strange mind. The whole idea of 'Class is to allow 
> different but related types to share implementations.

Yes, if "implementation" means class-wide and inherited operations. The
idea of T'Class is to share an interface, so that programs could be written
in terms of the interface, which would make them working on all instances
of the class (AKA, generic programming). We want to have this for all types
including those which representations are different. If you want to be able
to inherit an operation for such a type, the only way to do it is to
compose old body with type representation conversion. This is the model for
untagged classes. You will be free to derive from any non-limited type
ignoring its representation, but then the compiler will ask you either to
override an inherited primitive operation or else define corresponding
conversions so that it could create one.

> You're only allowed to 
> convert between related types, which includes derived types.

That is the only way to have a class without sharing (inheriting, actually)
representations.

The model of Ada 95 tagged types provides a class with shared
representations. This need to be augmented for the case when
representations has to be different. Note that this was partially done when
Java interfaces were added in Ada 2005. Java interface is a type without
any representation, so there is nothing to inherit from, except for a slot
for the type tag. Drop that slot, and you will have a workable model for
building classes of scalar types and arrays.

>> We also need "extension" that drops parent's representation altogether.
>> E.g. something like:
>>
>>   type Character is new Unsigned_8 -- or enumeration, whatever
>>      and Wide_Wide_Character'Interface;
>>
>> Character is member of Wide_Wide_Character'Class with a representation
>> different from Wide_Wide_Character.
> 
> I don't think that would work semantically, at least in the 'Class case. 
> Unless you expect every operation down to assigning individual components to 
> be dispatching, even in primitive routines defined for a specific type.

Exactly! I want all that mess to become orderly defined primitive
operations. This also includes attributes and aspects. There should be no
special cases like T'Read, ":=" etc. There should be no magic and strange
stuff like attributes, slices, ranges, aspects infesting the language, only
objects and operations.

> That's because you can't copy all tagged types (we have to have limited 
> types), and thus calling a parent operation would have to assume that 
> extensions have a different representation. That would both have problems of 
> re-dispatch and simply would be awfully expensive (you'd have to do full 
> program compilation to have any hope of decent code).

Re-dispatch is a bad idea anyway.

Yes, for untagged classes the conversions from the specific type to a class
and backwards are no more for free. But these types are meant to be
copyable anyway.

> The only alternative would be to totally ban implementation inheritance on 
> such types, but as implementation inheritance is 10 times more useful than 
> interface inheritance, it would make the construct 95% useless.

Huh, and you tell me that type cloning is useless? Cloning is all about
implementation inheritance.

For copyable objects implementation inheritance is much less interesting
than for by-reference types. Operations (especially cross operations) need
to be re-implemented anyway, at least for performance reasons. Few other
operations are [conversion ->] inherited body [-> conversion].

>> Making it regular is a simplification.
> 
> This isn't regular. All numeric types are currently members of a single 
> hierarchy,

It is not a single hierarchy. It is a forest of similar hierarchies. They
are similar just because they were constructed by the compiler rather than
by the programmer. It is nominal vs. structured. Same structure does not
imply equality, at least, it is meant to be so in Ada.

> and in practice, the vast majority of tagged types are members of 
> two hierarchies (controlled and limited controlled).

So what? This is equivalent to say that a type can be either copyable or
else not. Yes, "copyable" is an interface. There is a countable infinity of
other interfaces a type may implement. Which is why multiple inheritance is
so important.

But even if two types implement the same interface, e.g. can be copied,
that by no means should automatically imply that these types must belong to
the same hierarchy. This decision is up to the programmer.

Type cloning is a valuable mechanism to insulate type hierarchies against
each other.

Consider a container type defined for Copyable'Class. How do you prevent
mixing apples and oranges in there? Creating two new container types for
copyable apples and copyable oranges? But they are still the same
hierarchy. You need some fundamental operation which tells that a type
breaks off the hierarchy.

> More hierarchies don't buy anything (you can always move your 'Classes 
> around in the hierarchy to get subsets).

They buy safety through type checks.

>>>>>      overriding
>>>>>      procedure Op (A : in out Der; B : in Der);
>>>>
>>>> This is not an overriding since the mode is different.
>>>
>>> It *is* an overriding in Ada 83, and it still is in Ada 2012. I agree that
>>> it should not have been, but that is irrelevant because we're stuck with 
>>> it.
>>
>> Only when Der is derived using Ada 83 construct. Int'Class will be built
>> using "extension."
> 
> No way; derived types currently form a hierarchy (that's why you can 
> interconvert them); changing that would require fundamentally changing the 
> Ada model of hierarchies.

To me it is a wording issue not a real problem.

If you want a theoretic POV, no problem, both notions are fully compatible
with each other, it is one in a more general model:

Ada 83 hierarchy is a class of equivalence. Types from the hierarchy are
equal in the sense that they can be used interchangeable in the operations.
Each type is both a sub- and supertype of another (in non-Ada sense). The
graph of types is undirected.

Ada 95 tagged hierarchies are rather directed. A tagged type is only a
subtype (in non-Ada sense) of another tagged type in the hierarchy.

Untagged class would be an ability to have directed hierarchies of scalar
types and arrays. Why there should be none?

Conversely, ad-hoc supertypes would allow building Ada 83 equivalent types
with all types including tagged. You would derive a new type [=subtype] and
simultaneously declare it a supertype. This will effectively become a type
you can use interchangeably with the parent type [and get some ambiguities,
surely].

> The issue today is that you can't name those 
> hierarchies, that's what untagged 'Class would allow.

Name it a "taxonomy" then.

>>>>>      Obj : Int'Class := Der'(1);
>>>>>      Op (A => 1, B => Obj); -- Legal??
>>>>
>>>> MD is not fully implemented in Ada, but anyway, presuming that Op is a
>>>> multi-method, that the mode is "in" and that 1 is Universal_Integer (is
>>>> it?), the above is illegal because Op is not a method of
>>>> Universal_Integer'Class. You would have to write it as:
>>>>
>>>>   Op (A => Der'(1), B => Obj);  -- Same tags
>>>>   Op (A => Int'(1), B => Obj);  -- Different tags, Constraint_Error
>>>
>>> This seems wrong; an integer literal usually gets its type from context.
>>> It's only a value of type Universal_Integer if there is no type given from
>>> context (as in a type conversion or number declaration). I was presuming
>>> that integer literals act as tag-indeterminate functions (the most sensible
>>> model; if you have constants for a tagged type you usually would model them
>>> as tag-indeterminate functions - for instance, the constants Zero and One in
>>> a universal arithmetic package), you don't need multiple dispatch: the Ada
>>> dispatching rules simply calls the correct version of the function for the
>>> tag of the object. And that's what we would want to happen for integer
>>> literals (that's the closest analogy to what happens for existing
>>> expressions).
>>
>> This is one of possible interpretations of Ada semantics. You consider
>> literals primitive operations, e.g.
>>
>>   function "1" return Int;
>>
>> In Ada 95 such function has to be overridden, when Der extends Int.
>> However, if the representation is inherited and not changed, the rule 
>> could be that the compiler silently overrides all literals:
>>
>>   overriding function "1" return Der;
>>
>> In this case you will have 1 overloaded. Op will become ambiguous.
> 
> Yes, this is how Ada literals work today. This isn't how its described (it's 
> an implicit conversion rather than overloading) but the effect is the same.
> 
>> The alternative with different types can be discarded using some 
>> preference rules, e.g. domination, and thus ambiguity resolved.
> 
> Preference rules cause Beaujolias effects, and almost never can be 
> tolerated.

The idea that you can have an object of partially visible type was likely
wrong. So the separation of "with" and "use" was an mistake too. The
language should rather prevent declarations which are doomed to cause
ambiguities later.

> As soon as user-defined things are involved, preference rules simply don't 
> work.

Some rules are clearly needed to choose between:

   function "&" (Left : String; Right : Wide_String) return Wide_String;
   function "&" (Left : String; Right : Wide_String) return String;

The problem is not Ada design, but the nature of multi-methods with cross
operations enabled. The programmer should be allowed to declare some
signatures as equivalent, meaning: the compiler is free to use any without
reporting ambiguity.

The principle is always same, if you cannot decide it, leave to choice to
the programmer.

> The problem being that adding 
> or removing a single declaration can silently change the meaning of an 
> expression without causing an error. This is considered intolerable.)

Not always. It is OK with overriding.

My take on this that the language should prevent situations when you have
an object with some of its operations invisible, especially, when these
operations override the same primitive operation. I think this should be
possible to do while keeping it backward compatible, because standard types
are always visible anyway.

> My contention remains: if you are going to allow user 
> "Handle.all", then you need to expose the type of Handle.all. If you don't 
> need to allow that, then you are not going to use 4.1.5 at all. So I fail to 
> see your concern.

I don't need Handle.all, but I do need Handle.Foo meaning Handle.all.Foo.
Publicly it is an opaque by-copy type, privately it is an access type.

> Compiler checks are impossible for these things.

Why so? How is it different from in-mode of an argument. The compiler
routinely checks that you never update it.

> Unless you want to drive 
> yourself nuts with OOP baloney - and it's never going to be possible to do 
> these sorts of checks with type checking.

I don't understand why it has to be impossible to have:

   type File is ...;

   type Read_File is new File ...;
   prcodure Read (X : in out File; Data : out Stream_Element_Array);

   type Write_File is new File ...;
   procedure Write (X : in out File; Data : Stream_Element_Array);

   type Readwrite_File is new Read_File and Write_File ...;

with concrete types, but well possible with interfaces.

The nature of the check that the operation Write is not applied to
Read_File is exactly same in both cases.

It is not about checking, especially because the above construct is still
possible to get through generics. It is just a stupid limitation motivated
by urban legends mindlessly repeated through (using you wording) OO-baloney
texts.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Is this expected behavior or not
  2013-03-28 13:50  0%                                             ` Dmitry A. Kazakov
@ 2013-03-28 21:55  0%                                               ` Randy Brukardt
  2013-03-29 12:26  0%                                                 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 99+ results
From: Randy Brukardt @ 2013-03-28 21:55 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:cqf0yy6q930$.1sdzw45bc0c1w.dlg@40tude.net...
> On Wed, 27 Mar 2013 14:42:47 -0500, Randy Brukardt wrote:
>
>> The problem is that a slice ought to be a referential object as you put 
>> it,
>> and a "regular" object is definitely *not* a referential object (a copy
>> copies the data).
>
> What is "regular" object here? String?

A non-slice string object.

>> I don't see any way for a single data type to have two
>> different behaviors
>
> These are two data types, string and slice. Are you treating slice as an
> Ada-subtype of string? I consider slice a member of same class as string,
> yet a distinct type (in Ada sense). This is like 4.1.5, but in the same
> type hierarchy.

I thought you might do that, but then you're going to have problems of 
compatibility (Ada currently considers them the same type). An operation 
like "&" cannot not allow mixed string operands (if you do allow that, you 
make string literals ambiguous).

...
>> Nobody wants "type cloning".
>
> It is a very useful building block to me. Anyway it is Ada 83 legacy.

Ada 83 derived types are virtually useless, and no one understood how they 
worked. I objected to building tagged types on that foundation during Ada 
9x, but they didn't pay any attention to me on that. :-)

Ada 83 derived types would be one of the first things to get rid of in a new 
Ada-like language -- everything should be related. Indeed, all integer types 
belong to Root_Integer'Class (you just can't name that type in Ada as it 
stands); it would be weird to *break* that.

 ...
>> I don't think a version of untagged'Class that did not work on existing
>> derived types would fly.
>
> Astonishing that you even considered that possibility. In my view they are
> completely independent things.

You really have a strange mind. The whole idea of 'Class is to allow 
different but related types to share implementations. You're only allowed to 
convert between related types, which includes derived types.

>> In any case, I didn't realize that you were making an entire new kind of
>> type derivation
>
> To me it is exactly same as tagged extension when you add nothing to the
> existing representation.

Sure, this I totally agree with. But those are highly related to each other: 
Parent'Class includes the parent and the derivation.

> We also need "extension" that drops parent's representation altogether.
> E.g. something like:
>
>   type Character is new Unsigned_8 -- or enumeration, whatever
>      and Wide_Wide_Character'Interface;
>
> Character is member of Wide_Wide_Character'Class with a representation
> different from Wide_Wide_Character.

I don't think that would work semantically, at least in the 'Class case. 
Unless you expect every operation down to assigning individual components to 
be dispatching, even in primitive routines defined for a specific type. 
That's because you can't copy all tagged types (we have to have limited 
types), and thus calling a parent operation would have to assume that 
extensions have a different representation. That would both have problems of 
re-dispatch and simply would be awfully expensive (you'd have to do full 
program compilation to have any hope of decent code).

The only alternative would be to totally ban implementation inheritance on 
such types, but as implementation inheritance is 10 times more useful than 
interface inheritance, it would make the construct 95% useless.

>>> Moreover, it is highly desired to that cloning were available for tagged
>>> types as well:
>>>
>>>   package Original is new Ada.Containers.Vectors ...;
>>>   type Clone is new Original.Vector; -- Cloning, not extending!
>>>
>>> Now, I have to hierarchies of Vector, not very useful in this particular
>>> case, because of missing helper types, but anyway.
>>
>> Pointless complication. I thought you were trying to simplify the 
>> language!
>
> Making it regular is a simplification.

This isn't regular. All numeric types are currently members of a single 
hierarchy, and in practice, the vast majority of tagged types are members of 
two hierarchies (controlled and limited controlled). If I was going to 
simplify this further, I would make all of these into a single hierarchy. 
More hierarchies don't buy anything (you can always move your 'Classes 
around in the hierarchy to get subsets).

>>>>      overriding
>>>>      procedure Op (A : in out Der; B : in Der);
>>>
>>> This is not an overriding since the mode is different.
>>
>> It *is* an overriding in Ada 83, and it still is in Ada 2012. I agree 
>> that
>> it should not have been, but that is irrelevant because we're stuck with 
>> it.
>
> Only when Der is derived using Ada 83 construct. Int'Class will be built
> using "extension."

No way; derived types currently form a hierarchy (that's why you can 
interconvert them); changing that would require fundamentally changing the 
Ada model of hierarchies. The issue today is that you can't name those 
hierarchies, that's what untagged 'Class would allow.

>>>>      Obj : Int'Class := Der'(1);
>>>>      Op (A => 1, B => Obj); -- Legal??
>>>
>>> MD is not fully implemented in Ada, but anyway, presuming that Op is a
>>> multi-method, that the mode is "in" and that 1 is Universal_Integer (is
>>> it?), the above is illegal because Op is not a method of
>>> Universal_Integer'Class. You would have to write it as:
>>>
>>>   Op (A => Der'(1), B => Obj);  -- Same tags
>>>   Op (A => Int'(1), B => Obj);  -- Different tags, Constraint_Error
>>
>> This seems wrong; an integer literal usually gets its type from context.
>> It's only a value of type Universal_Integer if there is no type given 
>> from
>> context (as in a type conversion or number declaration). I was presuming
>> that integer literals act as tag-indeterminate functions (the most 
>> sensible
>> model; if you have constants for a tagged type you usually would model 
>> them
>> as tag-indeterminate functions - for instance, the constants Zero and One 
>> in
>> a universal arithmetic package), you don't need multiple dispatch: the 
>> Ada
>> dispatching rules simply calls the correct version of the function for 
>> the
>> tag of the object. And that's what we would want to happen for integer
>> literals (that's the closest analogy to what happens for existing
>> expressions).
>
> This is one of possible interpretations of Ada semantics. You consider
> literals primitive operations, e.g.
>
>   function "1" return Int;
>
> In Ada 95 such function has to be overridden, when Der extends Int.
> However, if the representation is inherited and not changed, the rule 
> could
> be that the compiler silently overrides all literals:
>
>   overriding function "1" return Der;
>
> In this case you will have 1 overloaded. Op will become ambiguous.

Yes, this is how Ada literals work today. This isn't how its described (it's 
an implicit conversion rather than overloading) but the effect is the same.

> The alternative with different types can be discarded using some 
> preference
> rules, e.g. domination, and thus ambiguity resolved.

Preference rules cause Beaujolias effects, and almost never can be 
tolerated. Ada used to have some for literals and they caused all manner of 
problems. The preference rules for universal causes problems as well (as you 
are pointing out here); these are extremely fragile and only work because 
universal types can't have any user-defined operations or visibility 
changes.

As soon as user-defined things are involved, preference rules simply don't 
work. Maybe they would work in a language without nesting and private parts 
and use clauses, but they don't work in Ada. (The problem being that adding 
or removing a single declaration can silently change the meaning of an 
expression without causing an error. This is considered intolerable.)

>>>> An interface can't have "..." as the parameter type for Write; there 
>>>> has
>>>> to be something there.
>>>
>>>   procedure Write (File : in out File_Access; Data : 
>>> Stream_Element_Array)
>>>      is abstract;
>>>
>>>> And that's the target type! Say again how it is that you
>>>> are not exposing this type??
>>>
>>> The target is File. I would gladly have MD and a hierarchy for the 
>>> second
>>> parameter, but that is another story for now.
>>
>> OK, if the target is File, then you know that - that's public 
>> information.
>> When you dereference a File_Handle, you get a File. You don't have to 
>> make
>> the contents of File public, just it's name. So I still don't see why you
>> think this is a problem.
>
> I don't want to expose File at all. Public views should have no access to
> it, otherwise than indirectly through the handle. E.g. they should not be
> able to get an access the file object, store it somewhere, deallocate it,
> use stream attributes on it, and perform any other fancy stuff.
> Furthermore, later on, a decision may fall to replace file descriptor with
> something completely different keeping code that uses handles intact. It 
> is
> good old information hiding principle.

Fine. But then you don't need any user-visible dereferencing, and you surely 
wouldn't use it. My contention remains: if you are going to allow user 
"Handle.all", then you need to expose the type of Handle.all. If you don't 
need to allow that, then you are not going to use 4.1.5 at all. So I fail to 
see your concern.

>>> Because whether a message is relevant to the choice if the program were 
>>> OK
>>> to deploy depends now on the message content. The language does not help
>>> me anymore to indicate it as a bug.
>>
>> But there is absolutely nothing new about this.
>
> There is nothing new that people die, yet nobody actually likes it.
>
>> GNAT has a variety of
>> warnings (calling everything it displays a "warning" in order to avoid
>> arguments about its particular classifications of message), but most 
>> people
>> choose to treat some subset of them as errors that have to be removed 
>> before
>> deployment. You would do that same; choose a *class* of warnings that 
>> have
>> to be removed; there is no parsing of messages needed. If a warning in 
>> the
>> prohibited class exists, the program is not ready for deployment.
>
> Some C compilers give warning when you write:
>
>   if (x = 1) ...
>
>> Yes, this means you need to develop a coding standard and a development
>> standard to ensure that these these things are followed. But not having
>> those in some form is just lousy programming management.
>
> Error checks do not belong to coding standards. Coding standard, and
> testing, and code review etc are there when compiler checks were
> impossible.

Compiler checks are impossible for these things. Unless you want to drive 
yourself nuts with OOP baloney - and it's never going to be possible to do 
these sorts of checks with type checking. (This is not a type problem, it's 
a subtype (in the Ada sense) problem.) Feel free to pick your poison, as it 
will, but expecting types to do all of the work is just as silly as 
expecting that you can make a correct program with defining any types at 
all.

                                       Randy.





^ permalink raw reply	[relevance 0%]

* Re: Is this expected behavior or not
  2013-03-27 19:42  5%                                           ` Randy Brukardt
@ 2013-03-28 13:50  0%                                             ` Dmitry A. Kazakov
  2013-03-28 21:55  0%                                               ` Randy Brukardt
  0 siblings, 1 reply; 99+ results
From: Dmitry A. Kazakov @ 2013-03-28 13:50 UTC (permalink / raw)


On Wed, 27 Mar 2013 14:42:47 -0500, Randy Brukardt wrote:

> The problem is that a slice ought to be a referential object as you put it, 
> and a "regular" object is definitely *not* a referential object (a copy 
> copies the data).

What is "regular" object here? String?

> I don't see any way for a single data type to have two 
> different behaviors

These are two data types, string and slice. Are you treating slice as an
Ada-subtype of string? I consider slice a member of same class as string,
yet a distinct type (in Ada sense). This is like 4.1.5, but in the same
type hierarchy.

>>> You missed the point altogether. You can't dispatch in general on untagged
>>> types because overriding operations may have different modes and subtypes
>>> for the parameters. So what *is* the profile of the operation for T'Class,
>>> and how can it work?
>>>
>>> Consider:
>>>
>>>      Type Int is range 1 .. 10;
>>>      procedure Op (A, B : in Int);
>>>
>>>      Type Der is new Int;
>>
>> This is not derivation within the class, it is a "type-cloning." Type
>> cloning creates a new class and new a type (all types up the hierarchy). 
>> We need some syntax to indicate the difference.
>>
>>   type Der is new Int <whatever>;
>>
>> It is unfortunate that tagged types reused "is new" for a purpose
>> completely different from type cloning.
> 
> Nobody wants "type cloning".

It is a very useful building block to me. Anyway it is Ada 83 legacy.

> I have no idea why anyone that wants 'Class 
> would want to avoid maximizing the interoperability of types.

Sometimes we want types related, sometimes we don't, while reusing existing
implementations. The language should support programmer's choice.

> The original motivating example for Integer'Class was:
> 
>      Put (Obj : Integer'Class; Width : Count := 0);
> 
> so that one didn't need to understand generic instantiations just to do 
> simple I/O of strongly typed entities.

Yes.

Cloned Integer will "inherit" this Put operation in Ada 83 sense. Ada 83
cloning is orthogonal to type hierarchies. You get a new hierarchy when you
clone a type.

> I don't think a version of untagged'Class that did not work on existing 
> derived types would fly.

Astonishing that you even considered that possibility. In my view they are
completely independent things.

> In any case, I didn't realize that you were making an entire new kind of 
> type derivation

To me it is exactly same as tagged extension when you add nothing to the
existing representation.

We also need "extension" that drops parent's representation altogether.
E.g. something like:

   type Character is new Unsigned_8 -- or enumeration, whatever
      and Wide_Wide_Character'Interface;

Character is member of Wide_Wide_Character'Class with a representation
different from Wide_Wide_Character.

>> Moreover, it is highly desired to that cloning were available for tagged
>> types as well:
>>
>>   package Original is new Ada.Containers.Vectors ...;
>>   type Clone is new Original.Vector; -- Cloning, not extending!
>>
>> Now, I have to hierarchies of Vector, not very useful in this particular
>> case, because of missing helper types, but anyway.
> 
> Pointless complication. I thought you were trying to simplify the language!

Making it regular is a simplification.

>>>      overriding
>>>      procedure Op (A : in out Der; B : in Der);
>>
>> This is not an overriding since the mode is different.
> 
> It *is* an overriding in Ada 83, and it still is in Ada 2012. I agree that 
> it should not have been, but that is irrelevant because we're stuck with it.

Only when Der is derived using Ada 83 construct. Int'Class will be built
using "extension."

>>>      Obj : Int'Class := Der'(1);
>>>      Op (A => 1, B => Obj); -- Legal??
>>
>> MD is not fully implemented in Ada, but anyway, presuming that Op is a
>> multi-method, that the mode is "in" and that 1 is Universal_Integer (is
>> it?), the above is illegal because Op is not a method of
>> Universal_Integer'Class. You would have to write it as:
>>
>>   Op (A => Der'(1), B => Obj);  -- Same tags
>>   Op (A => Int'(1), B => Obj);  -- Different tags, Constraint_Error
> 
> This seems wrong; an integer literal usually gets its type from context. 
> It's only a value of type Universal_Integer if there is no type given from 
> context (as in a type conversion or number declaration). I was presuming 
> that integer literals act as tag-indeterminate functions (the most sensible 
> model; if you have constants for a tagged type you usually would model them 
> as tag-indeterminate functions - for instance, the constants Zero and One in 
> a universal arithmetic package), you don't need multiple dispatch: the Ada 
> dispatching rules simply calls the correct version of the function for the 
> tag of the object. And that's what we would want to happen for integer 
> literals (that's the closest analogy to what happens for existing 
> expressions).

This is one of possible interpretations of Ada semantics. You consider
literals primitive operations, e.g.

   function "1" return Int;

In Ada 95 such function has to be overridden, when Der extends Int.
However, if the representation is inherited and not changed, the rule could
be that the compiler silently overrides all literals:

   overriding function "1" return Der;

In this case you will have 1 overloaded. Op will become ambiguous. The
alternative with different types can be discarded using some preference
rules, e.g. domination, and thus ambiguity resolved.

>>> An interface can't have "..." as the parameter type for Write; there has 
>>> to be something there.
>>
>>   procedure Write (File : in out File_Access; Data : Stream_Element_Array)
>>      is abstract;
>>
>>> And that's the target type! Say again how it is that you
>>> are not exposing this type??
>>
>> The target is File. I would gladly have MD and a hierarchy for the second
>> parameter, but that is another story for now.
> 
> OK, if the target is File, then you know that - that's public information. 
> When you dereference a File_Handle, you get a File. You don't have to make 
> the contents of File public, just it's name. So I still don't see why you 
> think this is a problem.

I don't want to expose File at all. Public views should have no access to
it, otherwise than indirectly through the handle. E.g. they should not be
able to get an access the file object, store it somewhere, deallocate it,
use stream attributes on it, and perform any other fancy stuff.
Furthermore, later on, a decision may fall to replace file descriptor with
something completely different keeping code that uses handles intact. It is
good old information hiding principle.

>> Because whether a message is relevant to the choice if the program were OK
>> to deploy depends now on the message content. The language does not help 
>> me anymore to indicate it as a bug.
> 
> But there is absolutely nothing new about this.

There is nothing new that people die, yet nobody actually likes it.

> GNAT has a variety of 
> warnings (calling everything it displays a "warning" in order to avoid 
> arguments about its particular classifications of message), but most people 
> choose to treat some subset of them as errors that have to be removed before 
> deployment. You would do that same; choose a *class* of warnings that have 
> to be removed; there is no parsing of messages needed. If a warning in the 
> prohibited class exists, the program is not ready for deployment.

Some C compilers give warning when you write:

   if (x = 1) ...

> Yes, this means you need to develop a coding standard and a development 
> standard to ensure that these these things are followed. But not having 
> those in some form is just lousy programming management.

Error checks do not belong to coding standards. Coding standard, and
testing, and code review etc are there when compiler checks were
impossible.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[relevance 0%]

* Re: Is this expected behavior or not
  @ 2013-03-27 19:42  5%                                           ` Randy Brukardt
  2013-03-28 13:50  0%                                             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 99+ results
From: Randy Brukardt @ 2013-03-27 19:42 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:wdlyfbnwcnp7.10c9btwjmpm7j.dlg@40tude.net...
> On Tue, 26 Mar 2013 16:31:35 -0500, Randy Brukardt wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:1u72u7h5j4jg3$.wlxmaltyzqik.dlg@40tude.net...
>>> On Mon, 25 Mar 2013 17:58:26 -0500, Randy Brukardt wrote:
>>>
>>>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>>>> news:a96esjwiniqy$.op3wh7x9wrsl.dlg@40tude.net...
>>>>> On Fri, 22 Mar 2013 21:33:02 -0500, Randy Brukardt wrote:
>>>> ...
>>>>>> That doesn't necessarily mean copying of the data. If the designer
>>>>>> of the abstraction, have put in enough smarts to share
>>>>>> representations --
>>>>>> after all,
>>>>>
>>>>> You should break your mental block. No shared representation, I want
>>>>> different representations for different string types.
>>>>
>>>> I was talking about sharing representations of *different* objects of 
>>>> the
>>>> same string type (for instance, a string variable and a slice of that
>>>> variable - that case, sharing the data might be preferred to copying 
>>>> it).
>>>
>>> OK, the representation would be for type-specific string objects:
>>>
>>>   bounds + pointer
>>>
>>> and for class-wide string objects:
>>>
>>>   tag + bounds + pointer
>>
>> Sure, but irrelevant. The question is whether slicing copies the data or
>> not. If it is a new object, the data must be copied logically,
>
> No, logically it is a referential object.
>
>> but my point
>> was that it would be possible for an abstraction to defer actually making 
>> a
>> copy until an assignment is actually done. It's still a copy.
>
> Exactly the reverse, an implementation could be allowed to use a copy if
> that is consistent with the semantics of the slice being a reference.
>
> But regardless of the semantics, why this representation should not work?

The problem is that a slice ought to be a referential object as you put it, 
and a "regular" object is definitely *not* a referential object (a copy 
copies the data). I don't see any way for a single data type to have two 
different behaviors - as you've argued elsewhere, you can't have a single 
operation doing two different things. I suppose you could make a slice be a 
different type than a regular string object, but then you have problems with 
type matching (you want a slice to be compatible with the equivalent normal 
object).

...
>>>> And dispatching is incompatible with untagged types, simply because Ada
>>>> 83 got inheritance horribly wrong, and we're stuck with that.
>>>
>>> I disagree. It seems fully compatible with Ada 83 because T'Class would 
>>> be
>>> a distinct type with objects of that type. It is orthogonal to
>>> Ada-subtypes. You will not dispatch on Positive vs. Integer, these will
>>> reman specific [sub]types. In order to dispatch you will need a 
>>> class-wide
>>> object of the type Integer'Class (which will be strictly same as
>>> Positive'Class, except, possibly, the constraint). That object will have
>>> the representation tag + value. For Integer and Positive objects nothing
>>> changes. We might consider redefining some existing operations to become
>>> class-wide in some arguments, but that is another story.
>>
>> You missed the point altogether. You can't dispatch in general on 
>> untagged
>> types because overriding operations may have different modes and subtypes
>> for the parameters. So what *is* the profile of the operation for 
>> T'Class,
>> and how can it work?
>>
>> Consider:
>>
>>      Type Int is range 1 .. 10;
>>      procedure Op (A, B : in Int);
>>
>>      Type Der is new Int;
>
> This is not derivation within the class, it is a "type-cloning." Type
> cloning creates a new class and new a type (all types up the hierarchy). 
> We
> need some syntax to indicate the difference.
>
>   type Der is new Int <whatever>;
>
> It is unfortunate that tagged types reused "is new" for a purpose
> completely different from type cloning.

Nobody wants "type cloning". We waste a lot of mental energy getting rid of 
it in generics, for example. I have no idea why anyone that wants 'Class 
would want to avoid maximizing the interoperability of types. The original 
motivating example for Integer'Class was:

     Put (Obj : Integer'Class; Width : Count := 0);

so that one didn't need to understand generic instantiations just to do 
simple I/O of strongly typed entities.

I don't think a version of untagged'Class that did not work on existing 
derived types would fly. For no other reason than the fact that it would 
make tagged and untagged types more different, rather than less different.

In any case, I didn't realize that you were making an entire new kind of 
type derivation - I wouldn't have guessed that someone that has been talking 
repeatedly about simplifying the language would add an entirely new kind of 
type to the language.

> Moreover, it is highly desired to that cloning were available for tagged
> types as well:
>
>   package Original is new Ada.Containers.Vectors ...;
>   type Clone is new Original.Vector; -- Cloning, not extending!
>
> Now, I have to hierarchies of Vector, not very useful in this particular
> case, because of missing helper types, but anyway.

Pointless complication. I thought you were trying to simplify the language!

>>      overriding
>>      procedure Op (A : in out Der; B : in Der);
>
> This is not an overriding since the mode is different.

It *is* an overriding in Ada 83, and it still is in Ada 2012. I agree that 
it should not have been, but that is irrelevant because we're stuck with it.

>>      Obj : Int'Class := Der'(1);
>>      Op (A => 1, B => Obj); -- Legal??
>
> MD is not fully implemented in Ada, but anyway, presuming that Op is a
> multi-method, that the mode is "in" and that 1 is Universal_Integer (is
> it?), the above is illegal because Op is not a method of
> Universal_Integer'Class. You would have to write it as:
>
>   Op (A => Der'(1), B => Obj);  -- Same tags
>   Op (A => Int'(1), B => Obj);  -- Different tags, Constraint_Error

This seems wrong; an integer literal usually gets its type from context. 
It's only a value of type Universal_Integer if there is no type given from 
context (as in a type conversion or number declaration). I was presuming 
that integer literals act as tag-indeterminate functions (the most sensible 
model; if you have constants for a tagged type you usually would model them 
as tag-indeterminate functions - for instance, the constants Zero and One in 
a universal arithmetic package), you don't need multiple dispatch: the Ada 
dispatching rules simply calls the correct version of the function for the 
tag of the object. And that's what we would want to happen for integer 
literals (that's the closest analogy to what happens for existing 
expressions).

> Multi-methods (a special case of MD) is another and long story. They 
> should
> be properly supported in the end.
>
>> And if you say that Der cannot override Op this way, you're now 
>> incompatible
>> with Ada 83- Ada 2012.
>
> I want to preserve and extend type-cloning.

And you claim that the ARG keeps building gazebos. You're building a 
lakeside floating pavillion. ;-)

...
>> An interface can't have "..." as the parameter type for Write; there has 
>> to
>> be something there.
>
>   procedure Write (File : in out File_Access; Data : Stream_Element_Array)
>      is abstract;
>
>> And that's the target type! Say again how it is that you
>> are not exposing this type??
>
> The target is File. I would gladly have MD and a hierarchy for the second
> parameter, but that is another story for now.

OK, if the target is File, then you know that - that's public information. 
When you dereference a File_Handle, you get a File. You don't have to make 
the contents of File public, just it's name. So I still don't see why you 
think this is a problem.

>>>>>> That's my point about static analysis. Such a tool should be able to 
>>>>>> prove
>>>>>> that the majority of run-time checks can't happen, and give you a 
>>>>>> list of
>>>>>> those remaining.
>>>>>
>>>>> I don't need any list. Should I send it to my customers? I need the
>>>>> program fail to compile when writing analogue input.
>>>>
>>>> Treat the list as failures if you must, and insist that it be empty
>>>> before shipping.
>>>
>>> So, I need an AI system to parse compiler messages (of various vendors) 
>>> on
>>> top?
>>
>> Huh? Why would you "parse" them?
>
> Because whether a message is relevant to the choice if the program were OK
> to deploy depends now on the message content. The language does not help 
> me
> anymore to indicate it as a bug.

But there is absolutely nothing new about this. GNAT has a variety of 
warnings (calling everything it displays a "warning" in order to avoid 
arguments about its particular classifications of message), but most people 
choose to treat some subset of them as errors that have to be removed before 
deployment. You would do that same; choose a *class* of warnings that have 
to be removed; there is no parsing of messages needed. If a warning in the 
prohibited class exists, the program is not ready for deployment.

Yes, this means you need to develop a coding standard and a development 
standard to ensure that these these things are followed. But not having 
those in some form is just lousy programming management. And one thing we 
decided on the ARG long ago is that there is no way that a programming 
language can prevent lousy programming management -- any language can be 
misused without much effort. That cannot be prevented by a programming 
language; it's futile to try, and when you do try, you tend to make the 
language harder to use on real problems. So we assume competent management 
is used with Ada; we're not trying to make the language idiot-proof.

                                            Randy.





^ permalink raw reply	[relevance 5%]

* Re: ANN: Ahven 1.8
  @ 2010-06-05  4:08  9%         ` Stephen Leake
  0 siblings, 0 replies; 99+ results
From: Stephen Leake @ 2010-06-05  4:08 UTC (permalink / raw)


Dan <dan@irvine.com> writes:

> Ahven accepts parameterless procedures as test routines,
> such as the p1,p2,p3,q1,q2,q3 in my example.  AUnit, in contrast,
> requires test routines to have a parameter of type
> AUnit.Test_Cases.Test_Case'Class.  I have thousands of procedures that
> I would like to test using a test driver, but unfortunately not a
> single one of those comes in the form AUnit requires.

Ah. Adapting an existing test suite to use the framework is an issue.

You could write one AUnit test that calls all the thousands of tests,
but that would be silly.

You could probably write a tool to convert those tests to match AUnit,
but that would still be a lot of work.

> The problem is that Ada doesn't have a good way for one procedure to
> create other procedures, that can then be registered (using 'access).
> I tried using generics to instantiate the new test procedures, but ran
> into accessiblity-level problems.  I also tried using an allocator of
> a protected type that contains a procedure, but that results in a
> protected procedure, and AUnit only knows how to register normal
> (unprotected) procedures.

You need to write new source code. Real software writes itself :) (a new
slogan I just made up :).

> I presume that it may be possible to modify AUnit to support
> registering parameterless test procedures (or even better, an array of
> them), which would be convenient for my purposes.  

Not easy; the tests are called by the standard Ada dispatching call methods.

> It would also be possible to write some sort of offline test-generator
> that creates the kind of test procedures that AUnit expects.

Yes.

-- 
-- Stephe



^ permalink raw reply	[relevance 9%]

* Re: Ada and EDF in Win32?
  @ 2009-06-19 15:52  9% ` sjw
  0 siblings, 0 replies; 99+ results
From: sjw @ 2009-06-19 15:52 UTC (permalink / raw)


On Jun 19, 1:36 am, Günther Wimpassinger <marsianre1...@gmx.net>
wrote:

> I just started learning Ada and try to implement a small tasking example
> (some homework). I would like to use EDF scheduling, but if I try
> "with Ada.Dispatcher.EDF" I get an errormessage during compilation:
> "EDF is not supported in this configuration"
>
> I tried to add "pragma Task_Dispatching_Policy(EDF_Within_Priorities)".
> In the .adb sourcfile and in the "gnat.adc" config file. But this
> does not change anything.
>
> Is EDF only available on systems, where the OS/Environment supports EDF
> or is it possible to use EDF in Ada on standard PC OSs (like GNU/Linux
> or Windows without realtime extensions).

I assume you're using GNAT. The header of a-disdef.ads in GNAT GPL
2009 on Mac OX X (find this in GPS by selecting Help > GNAT Runtime >
Ada 2005 > Ada > Dispatching > EDF) says

--  This unit is not implemented in typical GNAT implementations that
lie on
--  top of operating systems, because it is infeasible to implement in
such
--  environments.

--  If a target environment provides appropriate support for this
package,
--  then the Unimplemented_Unit pragma should be removed from this
spec and
--  an appropriate body provided.



^ permalink raw reply	[relevance 9%]

* Re: Question about OO programming in Ada
  2003-12-09 13:29 10%                       ` Hyman Rosen
@ 2003-12-09 14:36  0%                         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 99+ results
From: Dmitry A. Kazakov @ 2003-12-09 14:36 UTC (permalink / raw)


On Tue, 09 Dec 2003 08:29:16 -0500, Hyman Rosen <hyrosen@mail.com>
wrote:

>Dmitry A. Kazakov wrote:
>> Dispatch table is a property of a dispatching subroutine.
>
>No it's not, at least not in the nearly universal C++ implementation.
>In that approach, there exists one dispatch table per tagged class
>with slots for each virtual function of that class. Then every object
>of that class contains a pointer to this single dispatch table. To
>make a dispatching call, the compiler accesses the dispatch table
>using the index corresponding to the function being called, and calls
>the method found there. (The model is more complicated due to virtual
>and multiple inheritance, so that an object may contain pointers to
>more than one dispatch table, and the addresses are sometimes to fixup
>thunks, but that doesn't matter here.)
>
>I'm pretty sure that at least GNAT implements Ada dispatching the
>same way.

Again, implementation issue is irrelevant. It is a subroutine that is
dispatching [in a parameter]. The object is not. The difference
becomes especially clear, when you consider multiple dispatch.

>> It is a complementary view. Either we say that the type of an object
>> is mutating or that the type of a formal parameter does (= changing
>> the dispatch table = changing the subroutine parameter profile). The
>> effect is same. It is no more strongly typed.
>
>In C++, the type of 'this' in a method is always 'pointer-to-class-type-
>of-this-method', or a const variant of that. The (dynamic) type of the
>object pointed to by 'this' can change as control passes through *tors.

This is exaclty what I meant by claiming that it is not a class-wide
pointer. A dispatching subroutine is defined on the whole class
(=closure of the domains of all derived types). Each override
represents a part of its body called according to the type tag. The
behaviour in C++ constructors/destructors clearly violates this. So
either the type is not class-wide or the subroutine is not
dispatching. Choose what you want, the result is same.

>Note that for typical C++ implementations we are not just "saying" that
>the type of the object changes; the generated code actually modifies the
>dispatch table pointer stored within the object as it progresses through
>its construction and destruction. (In fact, I believe Microsoft's C++
>compiler offers an option to disable this for efficiency when you can
>assure it that it won't matter.)

--
Regards,
Dmitry Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[relevance 0%]

* Re: Question about OO programming in Ada
  @ 2003-12-09 13:29 10%                       ` Hyman Rosen
  2003-12-09 14:36  0%                         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 99+ results
From: Hyman Rosen @ 2003-12-09 13:29 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> Dispatch table is a property of a dispatching subroutine.

No it's not, at least not in the nearly universal C++ implementation.
In that approach, there exists one dispatch table per tagged class
with slots for each virtual function of that class. Then every object
of that class contains a pointer to this single dispatch table. To
make a dispatching call, the compiler accesses the dispatch table
using the index corresponding to the function being called, and calls
the method found there. (The model is more complicated due to virtual
and multiple inheritance, so that an object may contain pointers to
more than one dispatch table, and the addresses are sometimes to fixup
thunks, but that doesn't matter here.)

I'm pretty sure that at least GNAT implements Ada dispatching the
same way.

> It is a complementary view. Either we say that the type of an object
> is mutating or that the type of a formal parameter does (= changing
> the dispatch table = changing the subroutine parameter profile). The
> effect is same. It is no more strongly typed.

In C++, the type of 'this' in a method is always 'pointer-to-class-type-
of-this-method', or a const variant of that. The (dynamic) type of the
object pointed to by 'this' can change as control passes through *tors.
Note that for typical C++ implementations we are not just "saying" that
the type of the object changes; the generated code actually modifies the
dispatch table pointer stored within the object as it progresses through
its construction and destruction. (In fact, I believe Microsoft's C++
compiler offers an option to disable this for efficiency when you can
assure it that it won't matter.)




^ permalink raw reply	[relevance 10%]

* Re: virtual functions in ada95
  @ 2001-06-16 19:43  9% ` tmoran
  0 siblings, 0 replies; 99+ results
From: tmoran @ 2001-06-16 19:43 UTC (permalink / raw)


>How can i use virtual functions in Ada?
  "An Ada dispatching subprogram is analogous to a C++ virtual function."
p 27, Ada as a Second Language, ISBN 0-07-011607-5

> type TNTGL_Node_Record is new TNTGL_Custom_Node_Record with private;
> type TNTGL_Visual_Node_Record is new TNTGL_Node_Record with private;
> type TNTGL_Sphere_Record is new TNTGL_Visual_Node_Record with private;

> procedure Run (Node : access TNTGL_Node_Record'Class);
> procedure Run (Sphere : access TNTGL_Sphere_Record'Class);

  A TNTGL_Sphere_Record, or any descendant of one, is also a descendant of
TNTL_Node_Record.  Which Run would you like to call in that case?
I think you want to drop the 'Class from the Run procedure declarations,
and have Run dispatch based on the run-time type of its paramter.

  procedure Run (Node : access TNTGL_Node_Record);
  procedure Run (Sphere : access TNTGL_Sphere_Record);
anything from a TNTGL_Node_Record up to the parent of a
TNTGL_Sphere_Record would call the first Run, a Sphere or its
descendants would call the second Run.



^ permalink raw reply	[relevance 9%]

* Re: Ada vs. C/C++ (was re: bitwise something-or-other)
  @ 2000-01-24  0:00 12%           ` Hyman Rosen
  0 siblings, 0 replies; 99+ results
From: Hyman Rosen @ 2000-01-24  0:00 UTC (permalink / raw)


Mark Lundquist <mark@rational.com> writes:
> For instance, C++ has its VPTR/VTABLE crap

You probably know this, but just for the record, the vptr/vtable technique
is part of an implementation to handle virtual method dispatching, and is
not defined within C++ itself. Ada dispatching is done in exactly the same
way. Indeed, I believe GNAT makes Ada tagged records compatible with
corresponding C++ classes so that pointers to such objects may be exchanged
between the two languages.




^ permalink raw reply	[relevance 12%]

* Re: Object,Subject,Verb, and Phrase (Sentence) Oriented Programming
  1999-06-18  0:00 11%   ` Fernando D. Mato Mira
@ 1999-06-18  0:00 14%     ` Matthew Heaney
  1999-06-18  0:00  0%       ` Fernando Mato Mira
  0 siblings, 1 reply; 99+ results
From: Matthew Heaney @ 1999-06-18  0:00 UTC (permalink / raw)


On 18 Jun 1999 11:52, "Fernando D. Mato Mira" <matomira@acm.org> wrote:

> Really, can't Ada dispatching be upgraded w/o losing
> backwards-compatibility?

What are your specific objections to "Ada dispatching"?  

And how is dispatching in Ada any different from dispatching in Eiffel
or C++?


> I still have to get my refs. But for what I remember, it seems
> so.. Time for a poll..

I don't understand what you're trying to say here.





^ permalink raw reply	[relevance 14%]

* Re: Object,Subject,Verb, and Phrase (Sentence) Oriented Programming
       [not found]     ` <19990617103727.07296.00000475@ng34.aol.com>
@ 1999-06-18  0:00 11%   ` Fernando D. Mato Mira
  1999-06-18  0:00 14%     ` Matthew Heaney
  0 siblings, 1 reply; 99+ results
From: Fernando D. Mato Mira @ 1999-06-18  0:00 UTC (permalink / raw)


Rjbotting wrote:

> Fernando D. Mato Mira excogitated:
> > I have to refresh my memory on the specs to see how to classify
> >Ada!!
> Hm.... I've been thinking aabout Ada since this
> came up:
> >Fernando send: aPaper about: subjectOriented to: OOPSLA
> which reminded me of vintage Ada:
> send(subject=>Fernando,object=>aPaper, about=>subjectOriented, to=>OOPSLA);

Comments welcome.    [** see below]

>
> When I was working on the syntax of a
> language I decided that, in general
>   f(a,b,c....)
>   a.f(b,c,....)
>   (a,b).f(c,...)
> etc
> would be different syntax for the same expression

Yup.

>
>
> (What we used to call "syntatic sugar" in the 70s)

"Syntactic sugar causes cancer of the semicolon" -- Alan Perlis

>
>
> I also experimented with parsing sentence like
> commands:
>   Fernando: move thePaper to OOPSLA.
> (how did COBOL get in here?)
>

Oh, no! Don't tell me I have sto study OO Cobol now! ;->
Gee. I've become a `language botanist'.. [** AND archeologist!]

>
> I have no data as to what works "best".

What "works best" depends. It seems to me that the categorization tells
you when a language is nicely put together in broad lines. i.e., both Eiffel
and C++
are SO in all these dimensions, but we know there's a difference, isn't it?
;->
But then, they lose some clarity if you extend just the dispatching, for
example.
Fitting in different ones might indicate a need for `more work', but which
in the end can result in a nicer language.


PS:
Really, can't Ada dispatching be upgraded w/o losing backwards-compatibility?
I still
have to get my refs. But for what I remember, it seems so.. Time for a poll..

--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1                   email: matomira AT acm DOT org
CH-2007 Neuchatel                 tel:       +41 (32) 720-5157
Switzerland                       FAX:       +41 (32) 720-5720

www.csem.ch      www.vrai.com     ligwww.epfl.ch/matomira.html







^ permalink raw reply	[relevance 11%]

* Re: Object,Subject,Verb, and Phrase (Sentence) Oriented Programming
  1999-06-18  0:00 14%     ` Matthew Heaney
@ 1999-06-18  0:00  0%       ` Fernando Mato Mira
  0 siblings, 0 replies; 99+ results
From: Fernando Mato Mira @ 1999-06-18  0:00 UTC (permalink / raw)




Matthew Heaney wrote:

> On 18 Jun 1999 11:52, "Fernando D. Mato Mira" <matomira@acm.org> wrote:
>
> > Really, can't Ada dispatching be upgraded w/o losing
> > backwards-compatibility?
>
> What are your specific objections to "Ada dispatching"?
>
> And how is dispatching in Ada any different from dispatching in Eiffel
> or C++?

Eiffel, C++, Ada fall all in the same category here.
See Dylan or standard CLOS dispatching. That's what I'd like. And it
doesn't
mean that also having restricted single dispatch would not be possible.

> > I still have to get my refs. But for what I remember, it seems
> > so.. Time for a poll..

The word about multimethods seem to be spreading. Ada95 embraced OO.
Is a new round scheduled? And the poll is; "Who wants that?"

Ada has an edge here w.r.t. Eiffel and C++ regarding adoption of multi
dispatch.
Extending the others will imply having them look gratuitously asymmetric or
increase
in complexity. Resolving how that would interplay with overloading in C++
will be an issue.
Eiffel uses classes as the unit of encapsulation. That is weird for
multimethods. Not to say
anything about extensibility.






^ permalink raw reply	[relevance 0%]

* Dispatching and different types
@ 1997-07-11  0:00  9% Phillip Durbin
  0 siblings, 0 replies; 99+ results
From: Phillip Durbin @ 1997-07-11  0:00 UTC (permalink / raw)



I am new to Ada and  was wondering, why doesn't Ada dispatching let you
use different inherited types? And of course how do you work  around
this ? For example if I have tagged type T, and two derived types A and
B (where A and B have different extensions) then procedure P(A,B) would
be  illegal, although P(T'CLASS,T'CLASS) is OK. The problem as I see it
is how do I get the functionality of P(A,B) from P(T'CLASS,T'CLASS),
when the operation to be performed needs both extensions of A and B. I
can't dispatch P(T,B) or P(A,T) with P(A,B) because both A and B are
derived types that are different. It seems to me it would be rather easy
to do a signature check to find the correct one. Am I missing some
obvious point here or is there some other feature in Ada that handles
this better?

 Phil Durbin
 durbin@killians.gsfc.nasa.gov




^ permalink raw reply	[relevance 9%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-18  0:00 10%                       ` Vincent Celier
@ 1996-11-22  0:00  9%                         ` Don Harrison
  0 siblings, 0 replies; 99+ results
From: Don Harrison @ 1996-11-22  0:00 UTC (permalink / raw)



Vincent Celier writes:

:Don Harrison wrote:
:
:> I'd have to say that I never instantiate anything in Ada without explicitly
:> providing actual parameters. I think it makes it easier to see what's going
:> on at the instantiation site without having to check the generic declaration
:> to see that a default isn't unwittingly being used. So, rather than being
:> disappointed that Eiffel doesn't have default actual parameters, I'm glad
:> that it doesn't.

:Default parameters are very useful when low-level interfaces need to
:migrate.
:
:To remove a generic formal:
:   1- Add a default: upwardly change, no client code should be
:      affected,
:   2- Ask all client to remove the obsolete parameter in their
:instantiations
:   3- When all clients have done 2, remove the generic formal.
:
:To add a new generic formal:
:   1- Add the new generic formal, with a default,
:   2- Ask all clients to add an actual parameter in all instantiatrions,
:   3- Remove the default.

Yes, this technique works. We've used it here occasionally with Ada-83 and
I agree it's appropriate in that context.

However, in an OO context, I would do it differently:

1) Define a new generic class inheriting the stuff it needs (from the original 
   or an ancestor thereof) and adding whatever new stuff it requires.
2) Convert clients when convenient to use the new generic.

This way, you retain the benefit of being able to see the parameters at the
site of instantiation and avoid the transitional state of obsolesence.

:-- Always looking for experienced Ada developpers willing to live in
:BBC,
:-- (Beautiful British Columbia).

You mean they need to be persuaded? :)  Some people don't know what's good 
for them.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 9%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-19  0:00 13%                           ` Jon S Anthony
@ 1996-11-20  0:00 12%                             ` Don Harrison
  0 siblings, 0 replies; 99+ results
From: Don Harrison @ 1996-11-20  0:00 UTC (permalink / raw)



Jon S Anthony writes:

:> :> :>  type Some_Type is tagged limited private;

:> :"Some_Type" is the generic formal (like the T in Eiffel)
:> :and could be instantiated with anything.  
:> 
:> Do you mean like the following?
:> 
:>   class X [T] ...              -- unconstrained genericity.
:
:Yes.
:
:
:> If so, this is different from what Bob Duff said.
:
:Huh?????  I went and checked and this is seems to be exactly what Bod said!

Yes, You're right. My mistake. You were both saying this is unconstrained
genericity: an actual of any type may be substituted. Further, no operations
come with it (because the designer of the generic can't anticipate what 
actuals may be provided in instantiations).


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-15  0:00 12%                         ` Don Harrison
@ 1996-11-19  0:00 13%                           ` Jon S Anthony
  1996-11-20  0:00 12%                             ` Don Harrison
  0 siblings, 1 reply; 99+ results
From: Jon S Anthony @ 1996-11-19  0:00 UTC (permalink / raw)



In article <E0wDCo.GJx@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

In article <E0wDCo.GJx@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Jon S Anthony writes:
> 
> :> :>  type Some_Type is tagged limited private;
> 
> :> :I meant "type Some_Type is new Other_Type with private".
> 
> :In the first, "Some_Type" is the generic formal (like the T in Eiffel)
> :and could be instantiated with anything.  
> 
> Do you mean like the following?
> 
>   class X [T] ...              -- unconstrained genericity.

Yes.


> If so, this is different from what Bob Duff said.

Huh?????  I went and checked and this is seems to be exactly what Bod said!
Here's what he said:


>> I believe Eiffel has something similar to both, but I forget the syntax.
>> Is this the "class X [Some_Type]" vs. "class X [Some_Type ->
>> Other_Type]" thing?  You can have a generic class where the formal can
>> be any class, or you can require the formal to be a subclass of some
>> particular class.
>> 
>> - Bob


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 13%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-14  0:00  8%               ` Robert I. Eachus
  1996-11-14  0:00 13%                 ` Robert A Duff
  1996-11-15  0:00  8%                 ` Don Harrison
@ 1996-11-19  0:00 12%                 ` Jon S Anthony
  2 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-19  0:00 UTC (permalink / raw)



In article <E0wEJo.Gpr@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> :  > IMHO, overloading should have no semantic impact. It should merely be 
> :  > 'syntactic sugar' as Jean-Marc suggested.
> : 
> :   Nice dream, but...the fact that horses are a good way to commute
> :shouldn't lead to the outlawing of jet planes for intercontinental
> :travel.  However, you do need to make sure that the airplane pilot
> :knows how to fly. ;-)
> 
> Yes, and thankfully they make planes *easier* to fly these days. :)
> 
> Jon should know something about that.
> 
> 
> Don.

I guess it depends on what you mean by "easier".  If all you want to
do is straight and level, A to B stuff, I suppose you may have a
point.  However, if you are going to do competition aerobatics or air
show work, the airplane you're going to want for "ease" of use (if you
are sane) will have zero in common with the previous sense of "ease".

Which only goes to show how very context dependent such "value
judgements" tend to be.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-15  0:00  5%                   ` Robert I. Eachus
@ 1996-11-19  0:00  8%                     ` Don Harrison
  1996-11-18  0:00 10%                       ` Vincent Celier
  0 siblings, 1 reply; 99+ results
From: Don Harrison @ 1996-11-19  0:00 UTC (permalink / raw)



Robert I. Eachus writes:

:   In Ada you get to choose between THREE places where parameters and
:methods can be fixed:  At the point where generic definition appears,
:at the point where the generic instantiation occurs, and at the point
:of the call.  

That sounds about the same as Eiffel.

:The "tricky bit" is that you can also have overridable
:defaults bound at any of those three locations.  I don't know why you
:would want to provide a RK routine where the default number of steps
:was set during instantiation, but you can do it if you want to.

I'd have to say that I never instantiate anything in Ada without explicitly 
providing actual parameters. I think it makes it easier to see what's going 
on at the instantiation site without having to check the generic declaration 
to see that a default isn't unwittingly being used. So, rather than being 
disappointed that Eiffel doesn't have default actual parameters, I'm glad 
that it doesn't.

:  > If you were writing this now in Ada95, would you be able to reduce
:  > the complexity by using OO stuff?
:
:   No, and no!  First, the complexity is not in the code, it is in the
:understanding of the requirements.  Second, if those are the
:requirements, the same solution is probably the simplest in Ada 83 and
:Ada 95.

I'll take your word for it. 

:   This is a symptom of a general problem for OO programmers learning
:Ada.  In Ada generics are often a much simpler, and hugely more
:maintainable solution to many problems that can only be solved with
:inheritance in other OO languages.  

Yes, generics are useful. I'm glad they are in Eiffel. However, if I had to
choose between generics and inheritance, I would choose inheritance. I recall
Bertrand Meyer saying in OOSC that you can emulate generics using inheritance
but not the reverse.

:  > I'll interpret 'powerful' to mean 'esoteric'. :)
:
:  No, I meant powerful.  Just like working with rocket fuel or
:high-voltage electicity or what have you.  When you are working with
:constructs where the change of one word, say a parameter name, can
:have a global effect on modules which never use that name, you have to
:use design principles and configuration manangement tools very
:different from the run of the mill.

If it's all the same to you, I'll stick to 'the run of the mill'. :)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-19  0:00  8%                     ` Don Harrison
@ 1996-11-18  0:00 10%                       ` Vincent Celier
  1996-11-22  0:00  9%                         ` Don Harrison
  0 siblings, 1 reply; 99+ results
From: Vincent Celier @ 1996-11-18  0:00 UTC (permalink / raw)



Don Harrison wrote:

> I'd have to say that I never instantiate anything in Ada without explicitly
> providing actual parameters. I think it makes it easier to see what's going
> on at the instantiation site without having to check the generic declaration
> to see that a default isn't unwittingly being used. So, rather than being
> disappointed that Eiffel doesn't have default actual parameters, I'm glad
> that it doesn't.
> 

Default parameters are very useful when low-level interfaces need to
migrate.

To remove a generic formal:
   1- Add a default: upwardly change, no client code should be
      affected,
   2- Ask all client to remove the obsolete parameter in their
instantiations
   3- When all clients have done 2, remove the generic formal.

To add a new generic formal:
   1- Add the new generic formal, with a default,
   2- Ask all clients to add an actual parameter in all instantiatrions,
   3- Remove the default.

This work well for constants of global types, and for subprograms
with parameters and return values of global types.
For values of generic private types, it is sometimes possible to add a
new generic
constant, if there is already another generic constant.

For example, in the following spec:

   generic
      type Item is private;
      Nil_Item : in Item;
   package Whatever_Generic is ...

it is possible to introduce a new generic constant of type Item:

   generic
      type Item is private;
      Nil_Item : in Item;
      Default_Item : in Item := Nil_Item;
   package Whatever_Generic is ...


However, it is not possible to default generic formal types and
variables. Other
techniques should then be used.

> Don.
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> Don Harrison             donh@syd.csa.com.au

-- Vincent Celier,
-- 9100 McCutcheon Place, RICHMOND, B.C.
-- CANADA, V7A 5A5
-- +1 (604) 241-9811
--
-- Always looking for experienced Ada developpers willing to live in
BBC,
-- (Beautiful British Columbia).




^ permalink raw reply	[relevance 10%]

* Re: Interfacing contracts (Was: Eiffel and Java + Ada dispatching)
  1996-11-16  0:00  7%                     ` Interfacing contracts (Was: Eiffel and Java + Ada dispatching) Geert Bosch
@ 1996-11-17  0:00 13%                       ` Robert A Duff
  0 siblings, 0 replies; 99+ results
From: Robert A Duff @ 1996-11-17  0:00 UTC (permalink / raw)



In article <56kgrf$61t@fozzie.sun3.iaf.nl>,
Geert Bosch <geert@fozzie.sun3.iaf.nl> wrote:
>Example for interface specification that might be accepted by
>an Ada implementation without violating the Ada-95 standard (yes?):
>
>   --  Integer square root function truncating the exact result
>   function Square_Root (I : Natural) return Natural;
>
>   for Square_Root'Post_Condition use
>      Square_Root (I)  ** 2 <= I and (Square_Root (I) + 1) ** 2 > I;

Well, 13.1(19) says that expression is evaluated at this point, which is
not what you want.

You could use specially-formatted comments, as SPARK does.

By the way, I think invariants (not loop invariants, but per-class
invariants) are the most interesting thing about Eiffel's assertion
facility.

- Bob




^ permalink raw reply	[relevance 13%]

* Interfacing contracts (Was: Eiffel and Java + Ada dispatching)
  1996-11-12  0:00 12%                   ` Joachim Durchholz
  1996-11-15  0:00  8%                     ` Richard Riehle
@ 1996-11-16  0:00  7%                     ` Geert Bosch
  1996-11-17  0:00 13%                       ` Robert A Duff
  1 sibling, 1 reply; 99+ results
From: Geert Bosch @ 1996-11-16  0:00 UTC (permalink / raw)



Joachim Durchholz (jhd@herold.franken.de) wrote:
  "This is the normal contract on parameter and result types. Eiffel  
   contracts also include arbitrary boolean expressions, extending the  
   contracting idea far into the area of program semantics.
   Just as a parameter type makes clear what sorts of parameters are  
   required, the preconditions make clear under what circumstances the  
   routine may be called and expected to return a correct result. The Eiffel  
   postconditions list what the routine guarantees to the caller in turn."

Although Ada's interface capabilities are good enough to define the
range of results, these extra capabilities of Eiffel are very useful indeed. 
Especially for the large programs that are built using Ada. 

Something I'd really like to have is an Ada extension for specifying
both interface constraints and implementation conditions. 

Example for interface specification that might be accepted by
an Ada implementation without violating the Ada-95 standard (yes?):

   --  Integer square root function truncating the exact result
   function Square_Root (I : Natural) return Natural;

   for Square_Root'Post_Condition use
      Square_Root (I)  ** 2 <= I and (Square_Root (I) + 1) ** 2 > I;

In implementation:
   function Square_Root (I : Natural) return Natural is
      Lowerbound : Natural := Natural'Min (2, I);
      for Lowerbound'Invariant use Lowerbound ** 2 <= I;
      ...
   begin
      ...
   end Square_Root;

The advantage of checkng the pre- and post-conditions is that
the user of the subprogram or primitive has a better specification
of what the function (or procedure or...) does. The advantage of
a machine checkable specification is that the user can rely on them.
Ordinary comments on the other hand are often out of date.

Also when my algorithm using the Square_Root function specified
above doesn't work correctly, I only have to look at the specification
to know that the error won't be in the Square_Root implementation.
This is much better than to try figuring out whether the Code is correct
or not. Using a pragma Assert on the computed value just before return
has some drawbacks: you have to look at the implementation to know whether
these assertions are present, and you have to make sure that all possible
returns from the function are checked.

Another point is that it is possible in many cases to automatically
prove invariants. When the proving software cannot prove invariants,
the programmer can (and maybe should) make smaller steps that are
easier to prove. When all invariants can be proved, no checks are
necessary so speed is the same.

Actually it might be possible for the compiler to take advantage of
invariants and pre- / post-conditions by both eliminating checks and
taking advantage of the extra information.
    
Note that in the examples above, the formal parameters are visible
in the expression and that the expression is in fact a function.

Regards,
   Geert
-- 
E-Mail: geert@sun3.iaf.nl    




^ permalink raw reply	[relevance 7%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-13  0:00 12%                       ` Jon S Anthony
@ 1996-11-15  0:00 12%                         ` Don Harrison
  1996-11-19  0:00 13%                           ` Jon S Anthony
  0 siblings, 1 reply; 99+ results
From: Don Harrison @ 1996-11-15  0:00 UTC (permalink / raw)



Jon S Anthony writes:

:> :>  type Some_Type is tagged limited private;

:> :I meant "type Some_Type is new Other_Type with private".

:In the first, "Some_Type" is the generic formal (like the T in Eiffel)
:and could be instantiated with anything.  

Do you mean like the following?

  class X [T] ...              -- unconstrained genericity.

If so, this is different from what Bob Duff said.

In the second you have the
:same as the Eiffel, which to make it explicit would have been written:
:
:    type T is new Some_Type with private.
:
:That's the same as the Eiffel constraint above...

Same as Bob Duff.

BTW, I'll check the RM.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 12%]

* Re: portmanteau (was Re: Eiffel and Java + Ada dispatching)
  1996-11-08  0:00  7%             ` Don Harrison
                                 ` (2 preceding siblings ...)
  1996-11-14  0:00  8%               ` Robert I. Eachus
@ 1996-11-15  0:00  9%               ` Robert I. Eachus
  3 siblings, 0 replies; 99+ results
From: Robert I. Eachus @ 1996-11-15  0:00 UTC (permalink / raw)



In article <E0vMwK.BzE@world.std.com> bobduff@world.std.com (Robert A Duff) writes:

  > What, exactly, is 'portmanteau code'?

   Sheeesh, go and any of several standard texts on the subject of
software engineering, by one of the pioneers in the study of Boolean
logic, Charles Dodgson, writing under some pseudonym.  I think the
discussion actually occurs in the introduction to "The Hunting of the
Snark."  In any case he is discussing "Jabberwocky," and uses the term
portmanteau words to decribe words with more than one meaning packed
into them.  (See also in "Through the Looking Glass" the conversation
between Alice and Humpty Dumpty.)

   So portmanteau code is a section of program code which not only can
be read in more than one way, but all meanings are there and
accessable.  Unix has lots of portmanteau commands, where either the
arguements determine the meaning, such as setenv, or the name by which
the executable is invoked determines the operation to be performed
such as compress.

    (A portmanteau is a type of suitcase which folds up and can be
opened in different ways when folded and unfolded.  Many portmanteaus
are sold today as luggage designed to be carried on aircraft.)

    Totally off the subject, but one upon a time I wrote some
portmanteau machine code.  Two completely different programs for an
IBM 3033. (It wouldn't work on those 360/370 architecture machines
which required instrutions to be aligned. ;-) You executed the second
program by starting one byte after the starting point of the first
program.  (Of course I cheated, there were only about 70 byte
interleaved instructions in the code.)



--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 9%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-12  0:00 12%                   ` Joachim Durchholz
@ 1996-11-15  0:00  8%                     ` Richard Riehle
  1996-11-16  0:00  7%                     ` Interfacing contracts (Was: Eiffel and Java + Ada dispatching) Geert Bosch
  1 sibling, 0 replies; 99+ results
From: Richard Riehle @ 1996-11-15  0:00 UTC (permalink / raw)





On 12 Nov 1996, Joachim Durchholz wrote:


> This is the normal contract on parameter and result types. Eiffel  
> contracts also include arbitrary boolean expressions, extending the  
> contracting idea far into the area of program semantics.
> Just as a parameter type makes clear what sorts of parameters are  
> required, the preconditions make clear under what circumstances the  
> routine may be called and expected to return a correct result. The Eiffel  
> postconditions list what the routine guarantees to the caller in turn.

  It is not a question of whether Ada includes a contract in its
  package specifications.  The model for defining such a contract
  in Ada is a simple type definition with optional ranges and the
  set of operations for that type.  In object-oriented programming,
  to implement inheritance with class attribute extension (Ada has
  always had inheritance with attribute extension), on uses tagged
  types for the contract.

  I am fond of both Eiffel and Ada.  However, I sometimes wonder about
  the underlying reliability of assertions versus simple type definition.
  It seems to me that one can easily design an assertion that exceeds,
  in complexity, the wonderfully simple examples one sees published in
  Eiffel books. And as these assertions become more complex, are we 
  increasing the risk associated with that assertion.  

  I suspect that including assertions in Ada 95 would have made some
  practitioners happy. Would such a feature (no Eiffel pun intended)
  contribute to underlying reliability goals of Ada. Moreover, a
  fundamental notion in Ada is for the compiler to detect the maximum
  number of errors as close to the design specification as possible.
  Assertions are focused on run-time rather than comple-time.

  The structural differences between Ada and Eiffel are sometimes cited
  by advocates of both languages for their benefits.  Eiffel enthusiasts
  sometimes claim the "module is type" model is superior.  Though the
  case for this can be quite compelling, in software engineering practice
  the package model of Ada fares quite well.  Ada's separation of 
  specification from implementation contributes to a design that
  takes advantage of what Bertrand Meyer has called, "Linguistic
  Modular Units."  In Ada this is possible because we can define
  package specifications that are readable by our customers, by
  the systems engineers, and throughout all phases of the project.
  Such specifications can be straightforward in describing the
  "what" with little need to examine the "how."  

  I call this model of "Linguistic Modular Units" in Ada, a 
  Project Level Linguistic Backplane.  Whenver my clients have
  taken this approach, using Ada as the linguistic backplane for
  their entire project, they find it quite useful.  

  I find it entirely too easy to include algorithmic details in
  the definition of an Eiffel class. Consequently, I believe the
  Ada separation of specification from body compensates for its
  lack of an explicit assertion model.  Moreover, the very fact
  of a type definition, along with the rules for types, constitutes
  an implicit notion of precondition, postcondition, and invariant
  that is checked quite rigorously by the Ada run-time.

  Richard Riehle

  





^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-14  0:00  8%               ` Robert I. Eachus
  1996-11-14  0:00 13%                 ` Robert A Duff
@ 1996-11-15  0:00  8%                 ` Don Harrison
  1996-11-15  0:00  5%                   ` Robert I. Eachus
  1996-11-19  0:00 12%                 ` Jon S Anthony
  2 siblings, 1 reply; 99+ results
From: Don Harrison @ 1996-11-15  0:00 UTC (permalink / raw)



Robert I. Eachus writes:

:   In Ada, the default for generics is that you get the "predefined"
:operations for the class.  But if you explicitly pass the operation as
:a generic formal, you can override the standard definition.  No
:surprise there either.  

Okay. If it made sense, I think I would prefer to encapsulate behaviour of 
related operations into a type and define descendants covering the variants. 
Then the parent type bundled with its operations can be used as a formal 
generic parameter. That way, you simplify the generic interface. Don't know 
whether this fits at all.

:The suprise in the construct I demonstrated is
:that it is possible to define generics that are sensitive to the
:environment where they are instantiated.
:
:   And yes, it is a very useful feature, and should be used very
:carefully.  I have written several Ada 83 libraries where generics
:have use this feature extensively, and have as many as thirty formal
:parameters.  Since the packages are intended to be useful, they also
:are designed so that most of the generic formals have default values,
:so the instantiations only need a few lines.

If you were writing this now in Ada95, would you be able to reduce the 
complexity by using OO stuff?

:   But it is a high (and almost lanaguage independent) talent to
:observe the principle of least surprise.

Indeed. :)

:  > If the non-overloading versions are exponentially larger, maybe
:  > the originals were a bit dodgy anyway. :)

In saying this, I didn't realise you were talking about Ada83. It makes more
sense in that context.

:   No, but the most extreme case I know of was real portmanteau code.
:Generic instantiations with other generic instantiations as
:parameters, about four levels deep.  

Nasty stuff!

:But any other way of writing the
:code would have required millions of lines of code.  The several
:thousand generic instantiations weren't easy to debug and test, but
:much much better than any million line monstrosity would have been.
:Just don't use the powerful features for the easy jobs, save them for
:when and where they are needed.

I'll interpret 'powerful' to mean 'esoteric'. :)

:  > IMHO, overloading should have no semantic impact. It should merely be 
:  > 'syntactic sugar' as Jean-Marc suggested.
: 
:   Nice dream, but...the fact that horses are a good way to commute
:shouldn't lead to the outlawing of jet planes for intercontinental
:travel.  However, you do need to make sure that the airplane pilot
:knows how to fly. ;-)

Yes, and thankfully they make planes *easier* to fly these days. :)

Jon should know something about that.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-15  0:00  8%                 ` Don Harrison
@ 1996-11-15  0:00  5%                   ` Robert I. Eachus
  1996-11-19  0:00  8%                     ` Don Harrison
  0 siblings, 1 reply; 99+ results
From: Robert I. Eachus @ 1996-11-15  0:00 UTC (permalink / raw)




   I said:

   :   In Ada, the default for generics is that you get the "predefined"
   :operations for the class.  But if you explicitly pass the operation as
   :a generic formal, you can override the standard definition.  No
   :surprise there either.  

In article <E0wEJo.Gpr@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

  > Okay. If it made sense, I think I would prefer to encapsulate
  > behaviour of related operations into a type and define descendants
  > covering the variants.  Then the parent type bundled with its
  > operations can be used as a formal generic parameter. That way,
  > you simplify the generic interface. Don't know whether this fits
  > at all.

   Exactly, and that is the usual case.  But there are cases where you
want to have several very similar methods/functions/operations (choose
your term) that are slightly different.  In Ada you can do this
tailoring with generic formal subprogram parameters.  For a hackneyed
example say you want to write a Runge-Kutta integration routine.  It
is nice to be able to make it a generic (with respect to the type of
the integrand) and to call it with values for the function to be
integrated and the bounds.

   In Ada you get to choose between THREE places where parameters and
methods can be fixed:  At the point where generic definition appears,
at the point where the generic instantiation occurs, and at the point
of the call.  The "tricky bit" is that you can also have overridable
defaults bound at any of those three locations.  I don't know why you
would want to provide a RK routine where the default number of steps
was set during instantiation, but you can do it if you want to.

  > If you were writing this now in Ada95, would you be able to reduce
  > the complexity by using OO stuff?

   No, and no!  First, the complexity is not in the code, it is in the
understanding of the requirements.  Second, if those are the
requirements, the same solution is probably the simplest in Ada 83 and
Ada 95.

   This is a symptom of a general problem for OO programmers learning
Ada.  In Ada generics are often a much simpler, and hugely more
maintainable solution to many problems that can only be solved with
inheritance in other OO languages.  As a result in well written Ada 95
code, it is rare for a class to have grandchildren.  (Hmmm.  Better
stated as almost all grandchildren are descended from Controlled or
Limited_Controlled.)  But it is not uncommon for a derived tagged type
declaration to be followed by several generic instantiations that
would have be done in some other languages by multiple inheritance.

    My favorite illustration of this uses lists.  In Ada if you create
a class by specialization, and want to be able to make lists of the
members you will almost certainly use a generic.  In other languages
you would inherit from both the general class and a list class.

    Is this because you can't do it the other way?  No, it is because
it usually turns out to be cleaner to have both list objects and
objects which can be members of lists.  Ada makes it easy to do this,
and without loss of generality in the list class, so that is usually
the best way to do it.  (Why is it better to have two types?
Overloading again.  If the types are different, then it is possible to
provide (with one, one-line instantiation) among other operations:

     function "&" (L,R: Element) return List;
     function "&" (L: Element; R: List) return List;
     function "&" (L: List; R: Element) return List;
     function "&" (L,R: List) return List;

    ...and get the expected semantics.  If the types are the same,
then there is no way to distinguish between a list containing one
element and an element.

  > I'll interpret 'powerful' to mean 'esoteric'. :)

  No, I meant powerful.  Just like working with rocket fuel or
high-voltage electicity or what have you.  When you are working with
constructs where the change of one word, say a parameter name, can
have a global effect on modules which never use that name, you have to
use design principles and configuration manangement tools very
different from the run of the mill.

   (Just so I don't scare anyone off, what I usually do is when
overloading operations or overriding methods, I use the same parameter
names.  This makes it clear that you never intend to use parameter
names in overload resolution, just to match parameter values to
formals.)

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 5%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-14  0:00  8%               ` Robert I. Eachus
@ 1996-11-14  0:00 13%                 ` Robert A Duff
  1996-11-15  0:00  8%                 ` Don Harrison
  1996-11-19  0:00 12%                 ` Jon S Anthony
  2 siblings, 0 replies; 99+ results
From: Robert A Duff @ 1996-11-14  0:00 UTC (permalink / raw)



In article <EACHUS.96Nov13204034@spectre.mitre.org>,
Robert I. Eachus <eachus@spectre.mitre.org> wrote:
>   No, but the most extreme case I know of was real portmanteau code.

What, exactly, is 'portmanteau code'?

- Bob




^ permalink raw reply	[relevance 13%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-08  0:00  9%                       ` Don Harrison
@ 1996-11-14  0:00 10%                         ` Jon S Anthony
  0 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-14  0:00 UTC (permalink / raw)



In article <E0J76n.Evn@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> If it's true that specialisations *are* the operations you want most
> often, then making the general (inherited) operations polymorphic
> means that dynamic binding is wasted on a minority of calls.

First, there is no evidence for this.  Second, the conclusion you draw
doesn't follow anyway.


> should read
> 
> ... So, Eiffel 
> dispatches to a more specific operation by default and does not
> inherit the more general parent operation. However, if you *do* want
> the parent operation as well, then you can repeatedly inherit it and
> leave one the same and specialise the other.

Yes, but that doesn't eliminate the type safety issues.


> This is where Eiffel is very flexible compared with Ada because you
> can nominate *either* the inherited (parent) operation *or* the
> specialised one to be polymorphic wrt the parent.

I don't know why you keep saying this sort of stuff.  You can do this
in Ada as well if that is what you _really_ want.  Just use a class
wide parameter for the non-controlling parameter.  Really, I don't see
the big deal here at all.

    ... Op ( x : P;  y : A'Class )...
...
    ... Op ( x : C;  y : B'Class )...
...
    i : P'Class := ... Something in P's type tree
    j : A'Class := ... Something in A's type tree

    ... Op(i, j) ... dispatch to either P's Op or C's op depending on
                     what sort of thing is in i.  Further, if j is NOT
                     a B thing, then raise constraint error


> should read
> 
> So, Ada dispatches to the general (inherited) operation by default
> rather than to a more specific new one. ...

Well, that's still wrong.  This "default" stuff is completely
irrelevant and has nothing to do with anything in the Ada context.


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 10%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-07  0:00 11%                   ` Juergen Schlegelmilch
  1996-11-08  0:00  6%                     ` Don Harrison
@ 1996-11-14  0:00 10%                     ` Jon S Anthony
  1 sibling, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-14  0:00 UTC (permalink / raw)



In article <E0J2vy.E6C@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Now the contentious part. :( The issue of which model is 'correct'
> depends on which operation of B can better be regarded as
> functionally equivalent to the operation in A. (The safety issue is
> secondary, IMO - I'm talking about modelling integrity). What seems
> to happen in the real world is that as

The real world has nothing to do with it.  What is "modelling
integrity" anyway?


> interactions between things become more specific, the things
> involved become more specific as well (or some may stay the
> same). (The things do not become *less* specific, but that is
> another matter). To model this faithfully,

Things in the world aren't specific or general at all.  That is an
artificial organizational constraint applied in the semantics of some
modeling schemes (taxonomic...)  You really must separate the world
from the formalism or you will never get anywhere.


> :but then you have to rename). Thus, in a piece of code where an operation 
> :is applied to arguments suitable only for the inherited version, Eiffel 
> :will signal a type error (system validity or by runtime crash :-), 
> 
> IMO, this is what ought to happen because because the operation has become 
> more specific and so requires more specific parameters.

Well, in a covariant model.  But why think that is all there is or
even that it is the best????  There's just no evidence for it.


> must be fixed. If a more general operation realy *is* required, then
> you can define a *new* operation [(6) in my example] for this
> purpose. So, Eiffel dispatches to a more specific operation by
> default rather than to a more general one. This differs from Ada
> which ...
>
> : will use the inherited (overloaded) version.
>
> So, Ada dispatches to a more general operation by default rather
> than to a more specific one. This is the wrong way round, IMO. I

How did you arrive at that conclusion??  No, it simply dispatches to
the operation for which the arguments are intended.  If it is to the
more general, well then that is because the operands passed _are_ of
the more general type!


> think calling a more general operation ought to be the exception
> rather than the default. Some will not agree with me but that's
> okay. :)

Well, I disagree, because you are just plain factually wrong.


> I *am* saying that because Eiffel is covariant, you don't have to
> re-invent an operation as an overloaded operation due to inheriting
> some unwanted baggage that no longer reflects the specialisation of
> an abstraction.

No, you are not "re-inventing" anything.  You aren't overloading for
those reasons at all.  You overload because a) the inherited operation
is not refined in the "other" parameter and that is what you want and
b) using a different name for the operation is confusing, misleading,
and leads to poor software maintenance.  Which simply says, you can
have your cake (complete safety) and eat it too (give the programmer
model the functional equivalence of unbroken covariance).
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 10%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-13  0:00 11%                       ` Robert A Duff
@ 1996-11-14  0:00  9%                         ` Don Harrison
  0 siblings, 0 replies; 99+ results
From: Don Harrison @ 1996-11-14  0:00 UTC (permalink / raw)



Robert A Duff writes:

:>:>  type Some_Type is tagged limited private;

:>:I meant "type Some_Type is new Other_Type with private".

:In the first example above, Some_Type doesn't have any primitive
:operations.  You can't do much of anything with it, other than declare
:objects and a few other minor things.  (Unless you pass in explicit
:operations, which is what you (or somebody else?) was objecting to,
:several messages ago.)

I don't remember objecting but *was* curious about why operations had to be
explicitly declared as parameters along with types under some circumstances. :)
I expect this is a legacy of Ada-83.

:In the second example, Some_Type inherits all the primitive operations
:of Other_Type.  Inside the generic, you can do dispatching calls to them
:and so forth.  The actual type is required to be in the right class
:(Other_Type'Class), and thus implements all of those things you're
:calling.

This appears to be analogous to Eiffel's constrained genericity:

  class X [Some_Type -> Other_Type] ...

:I believe Eiffel has something similar to both, but I forget the syntax.

It has the 2nd type but not the first. This makes sense for Eiffel, IMO, 
because types potentially carry operations with them. These operations should 
be available wherever the type is used.

:Is this the "class X [Some_Type]" vs. "class X [Some_Type ->
:Other_Type]" thing?  You can have a generic class where the formal can
:be any class, or you can require the formal to be a subclass of some
:particular class.

That's right. The former is called 'unconstrained genericity'. As you would
expect, the operations also come with the type with this form.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 9%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-08  0:00  7%             ` Don Harrison
  1996-11-08  0:00 12%               ` Robert A Duff
  1996-11-08  0:00 11%               ` Jon S Anthony
@ 1996-11-14  0:00  8%               ` Robert I. Eachus
  1996-11-14  0:00 13%                 ` Robert A Duff
                                   ` (2 more replies)
  1996-11-15  0:00  9%               ` portmanteau (was Re: Eiffel and Java + Ada dispatching) Robert I. Eachus
  3 siblings, 3 replies; 99+ results
From: Robert I. Eachus @ 1996-11-14  0:00 UTC (permalink / raw)



In article <E0JIJu.G98@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

  > Okay but the problem I have with this is that picking up the local
  > stuff implicitly as parameters to the instantiation is potentially
  > confusing (as your example demonstrates). What would be clearer
  > and less confusing, IMO, would be to declare the parametric
  > information in a type together with the operation so that when you
  > instantiate (explicitly) with that type (or a descendant type),
  > you get the right operation with it. This way, it's very plain
  > what the actual instantiation parameters are.

   In Ada, the default for generics is that you get the "predefined"
operations for the class.  But if you explicitly pass the operation as
a generic formal, you can override the standard definition.  No
surprise there either.  The suprise in the construct I demonstrated is
that it is possible to define generics that are sensitive to the
environment where they are instantiated.

   And yes, it is a very useful feature, and should be used very
carefully.  I have written several Ada 83 libraries where generics
have use this feature extensively, and have as many as thirty formal
parameters.  Since the packages are intended to be useful, they also
are designed so that most of the generic formals have default values,
so the instantiations only need a few lines.

   But it is a high (and almost lanaguage independent) talent to
observe the principle of least surprise.

  > If the non-overloading versions are exponentially larger, maybe
  > the originals were a bit dodgy anyway. :)

   No, but the most extreme case I know of was real portmanteau code.
Generic instantiations with other generic instantiations as
parameters, about four levels deep.  But any other way of writing the
code would have required millions of lines of code.  The several
thousand generic instantiations weren't easy to debug and test, but
much much better than any million line monstrosity would have been.
Just don't use the powerful features for the easy jobs, save them for
when and where they are needed.

  > IMHO, overloading should have no semantic impact. It should merely be 
  > 'syntactic sugar' as Jean-Marc suggested.
 
   Nice dream, but...the fact that horses are a good way to commute
shouldn't lead to the outlawing of jet planes for intercontinental
travel.  However, you do need to make sure that the airplane pilot
knows how to fly. ;-)


--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-13  0:00 10%                     ` Don Harrison
  1996-11-13  0:00 11%                       ` Robert A Duff
@ 1996-11-13  0:00 12%                       ` Jon S Anthony
  1996-11-15  0:00 12%                         ` Don Harrison
  1 sibling, 1 reply; 99+ results
From: Jon S Anthony @ 1996-11-13  0:00 UTC (permalink / raw)



In article <E0sIBu.MJz@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Bob Duff writes:
> 
> :In article <E0qKM2.ECw@syd.csa.com.au>,
> :Don Harrison <donh@syd.csa.com.au> wrote:
> :>Ada                                             Eiffel
> :>---                                             ------
> :>generic                                         class X [T -> Some_Type] ...
> :>  type Some_Type is tagged limited private;
> :>package X ...
> :
> :I meant "type Some_Type is new Other_Type with private".
> 
> Okay. What's the difference?

In the first, "Some_Type" is the generic formal (like the T in Eiffel)
and could be instantiated with anything.  In the second you have the
same as the Eiffel, which to make it explicit would have been written:

    type T is new Some_Type with private.

That's the same as the Eiffel constraint above...

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-13  0:00 10%                     ` Don Harrison
@ 1996-11-13  0:00 11%                       ` Robert A Duff
  1996-11-14  0:00  9%                         ` Don Harrison
  1996-11-13  0:00 12%                       ` Jon S Anthony
  1 sibling, 1 reply; 99+ results
From: Robert A Duff @ 1996-11-13  0:00 UTC (permalink / raw)



In article <E0sIBu.MJz@syd.csa.com.au>,
Don Harrison <donh@syd.csa.com.au> wrote:
>:>generic                                         class X [T -> Some_Type] ...
>:>  type Some_Type is tagged limited private;
>:>package X ...
>:
>:I meant "type Some_Type is new Other_Type with private".
>
>Okay. What's the difference?

In the first example above, Some_Type doesn't have any primitive
operations.  You can't do much of anything with it, other than declare
objects and a few other minor things.  (Unless you pass in explicit
operations, which is what you (or somebody else?) was objecting to,
several messages ago.)

In the second example, Some_Type inherits all the primitive operations
of Other_Type.  Inside the generic, you can do dispatching calls to them
and so forth.  The actual type is required to be in the right class
(Other_Type'Class), and thus implements all of those things you're
calling.

I believe Eiffel has something similar to both, but I forget the syntax.
Is this the "class X [Some_Type]" vs. "class X [Some_Type ->
Other_Type]" thing?  You can have a generic class where the formal can
be any class, or you can require the formal to be a subclass of some
particular class.

- Bob




^ permalink raw reply	[relevance 11%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-12  0:00 12%                   ` Eiffel and Java + Ada dispatching Robert A Duff
@ 1996-11-13  0:00 10%                     ` Don Harrison
  1996-11-13  0:00 11%                       ` Robert A Duff
  1996-11-13  0:00 12%                       ` Jon S Anthony
  0 siblings, 2 replies; 99+ results
From: Don Harrison @ 1996-11-13  0:00 UTC (permalink / raw)



Bob Duff writes:

:In article <E0qKM2.ECw@syd.csa.com.au>,
:Don Harrison <donh@syd.csa.com.au> wrote:
:>Ada                                             Eiffel
:>---                                             ------
:>generic                                         class X [T -> Some_Type] ...
:>  type Some_Type is tagged limited private;
:>package X ...
:
:I meant "type Some_Type is new Other_Type with private".

Okay. What's the difference?

:>Yes, This is true of Eiffel. You get the benefit of all the contracting
:>defined in the type (and transitively, it's subtypes). But, you don't get
:>this in Ada as it does not support Programming by Contract in the more 
:>general (and usual) sense.
:
:I'm not sure what you mean by that.  That Ada doesn't have assertions?

Yes.

:True.  But there's all kinds of other contractual stuff in Ada -- when
:you export a type from a package, you define a contract; that is, what
:operations there are, and what their parameter names and types are, and
:so forth.

Sure. This is certainly *part* of contracting but this stuff is what you'd 
expect of any sensible statically typed language so isn't anything startling. 
Static typing is good stuff but it's misleading, IMO, to say that Ada supports
Programming by Contract because the term is implies assertions as well.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 10%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-12  0:00  8%                 ` Don Harrison
  1996-11-12  0:00 12%                   ` Joachim Durchholz
@ 1996-11-12  0:00 12%                   ` Robert A Duff
  1996-11-13  0:00 10%                     ` Don Harrison
  1 sibling, 1 reply; 99+ results
From: Robert A Duff @ 1996-11-12  0:00 UTC (permalink / raw)



In article <E0qKM2.ECw@syd.csa.com.au>,
Don Harrison <donh@syd.csa.com.au> wrote:
>Ada                                             Eiffel
>---                                             ------
>generic                                         class X [T -> Some_Type] ...
>  type Some_Type is tagged limited private;
>package X ...

I meant "type Some_Type is new Other_Type with private".

>Yes, This is true of Eiffel. You get the benefit of all the contracting
>defined in the type (and transitively, it's subtypes). But, you don't get
>this in Ada as it does not support Programming by Contract in the more 
>general (and usual) sense.

I'm not sure what you mean by that.  That Ada doesn't have assertions?
True.  But there's all kinds of other contractual stuff in Ada -- when
you export a type from a package, you define a contract; that is, what
operations there are, and what their parameter names and types are, and
so forth.

- Bob




^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-12  0:00  8%                 ` Don Harrison
@ 1996-11-12  0:00 12%                   ` Joachim Durchholz
  1996-11-15  0:00  8%                     ` Richard Riehle
  1996-11-16  0:00  7%                     ` Interfacing contracts (Was: Eiffel and Java + Ada dispatching) Geert Bosch
  1996-11-12  0:00 12%                   ` Eiffel and Java + Ada dispatching Robert A Duff
  1 sibling, 2 replies; 99+ results
From: Joachim Durchholz @ 1996-11-12  0:00 UTC (permalink / raw)



bobduff@world.std.com wrote 12.11.96:

> I'm not sure what you mean by that.  That Ada doesn't have assertions?
> True.  But there's all kinds of other contractual stuff in Ada -- when
> you export a type from a package, you define a contract; that is, what
> operations there are, and what their parameter names and types are, and
> so forth.

This is the normal contract on parameter and result types. Eiffel  
contracts also include arbitrary boolean expressions, extending the  
contracting idea far into the area of program semantics.
Just as a parameter type makes clear what sorts of parameters are  
required, the preconditions make clear under what circumstances the  
routine may be called and expected to return a correct result. The Eiffel  
postconditions list what the routine guarantees to the caller in turn.

Regards,
-Joachim

--
Looking for a new job. Resume available on request. WWW version of resume
available under http://www.franken.de/users/herold/jhd/resume/index.html




^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 11%         ` Don Harrison
                             ` (4 preceding siblings ...)
  1996-11-07  0:00 10%           ` Robb Nebbe
@ 1996-11-12  0:00  8%           ` Jon S Anthony
  5 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-12  0:00 UTC (permalink / raw)




In article <55p0i3$2u4@tjnews.is.s.u-tokyo.ac.jp> jezequel@piccolo.is.s.u-tokyo.ac.jp (Jean-Marc Jezequel) writes:


> >You are correct in saying that there is no semantic difference between
> >unique names and overloading. However, just because there is no semantic
> >difference don't suppose that it doesn't play a critical role in how the language
> >is defined. 
> 
> Yes, it does. For example by making things much more complicated;-)

Let's look at this in a different way.  Suppose that we didn't have any
overloading.  What would happen to the object model?  Suppose we have

    type A is tagged ...
...
    type B is new A with ...
...

    type P is tagged ...
    function Op ( x : P;  y : A ) return Something;
...
    type C is new P with ...
    -- Here we want to "refine" Op based on y having type B (covariant thing)

Now what?  Does C inherit Op from P?  If so, is Op covariant on the
second parameter?  Suppose we want to refine it, then what?  I suppose
we would need to introduce something like the "redefines" clause of
Eiffel lest we have name clashes.  Also, at the time we would've been
doing this, system validity issues associated with covariant
operations would be well known in the field.  What do we do about that?
- especially since one of the fundamental precepts of Ada has always
been to avoid introducing such potential errors.

So, we give up on covariance.  Now what?  We could (taking Don's
suggestion) just disallow another Op for C.  If you want to "refine"
based on the second parameter, you just have to use a different name.
But, that would severely constrain the ability to progam by extension
and in so doing, remove a good piece of why you even bother with OO
construction.

OK, we could try contravariance (ala' Sather).  But now how do we
introduce "refinements" of operations based on their non controlling
parameters?  We've come full circle - use overloading.


It's these sort of issues which (IMO) clearly show that OL is not just
syntactic sugar.  Not by a _long_ way.  It's presence has significant
semantic ramifications for what the object model even is.


> Despite Ada95 being much more clear than C++ in this respect, in complex cases involving
> both overloading and dynamic binding, it is still hardly possible to
> explain in one short sentence (like above) the concept of what's going on.
> 

> Just to change the subject, does anyone know why the designers of
> Ada95 did not choose to include the true multiple-dispatch a la CLOS
> (or point to a reference on this)?  At leat the syntax have been a
> problem; whereas it is in Java/C++/Eiffel.

Maybe Tucker will say something here, but the only thing I have ever
able to determine is that 1) no one knew what the "right" resolution
technique should be when you had multiple distinct types involved
(what's the effective method) and 2) no one really entertained trying
to put in something as complex as the MOP in order to get around 1).

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-08  0:00 12%               ` Robert A Duff
@ 1996-11-12  0:00  8%                 ` Don Harrison
  1996-11-12  0:00 12%                   ` Joachim Durchholz
  1996-11-12  0:00 12%                   ` Eiffel and Java + Ada dispatching Robert A Duff
  0 siblings, 2 replies; 99+ results
From: Don Harrison @ 1996-11-12  0:00 UTC (permalink / raw)



Robert A Duff writes:

:Don Harrison <donh@syd.csa.com.au> wrote:
:>...What would be clearer and less confusing, 
:>IMO, would be to declare the parametric information in a type together with 
:>the operation so that when you instantiate (explicitly) with that type 
:>(or a descendant type), you get the right operation with it. This way, it's 
:>very plain what the actual instantiation parameters are.
:>
:>Not sure how you would write this in Ada.
:
:This feature exists in Ada 95.  

Yes. It was good to see it included. The ability to use a tagged type as the
formal parameter is especially useful. This mechanism is analogous to 
constrained genericity in Eiffel:

Ada                                             Eiffel
---                                             ------
generic                                         class X [T -> Some_Type] ...
  type Some_Type is tagged limited private;
package X ...

For Ada, X could also be a procedure or function.
 
:Look up generic formal derived types in
:the reference manual.  Basically, you declare in the generic that the
:actual will be derived from some particular type, so inside the generic
:you can call the operations inherited from that type, and at the
:instantiation point, the compiler checks that the actual is in fact in
:the correct class.  

Yes.

:Programming by contract and all that good stuff.

Yes, This is true of Eiffel. You get the benefit of all the contracting
defined in the type (and transitively, it's subtypes). But, you don't get
this in Ada as it does not support Programming by Contract in the more 
general (and usual) sense.


Jon Anthony writes:

:That's one of the "typical" uses for generic formal package parameters.  It
:is one of the reasons they were included.
:
:    generic
:        type Some_Type is tagged private;
:        with function Some_Op (...) return Some_Type;
:    package X is end X;
:
:
:    generic
:        with package IX is new X(<>); -- No added constraints on Inst. of X
:    procedure Generic_Op(...);
:
:
:    package IX is new X(My_Type);
:    procedure Actual_Op is new Generic_Op(IX);
:
:An obvious variant that may prove useful in making sure things "line up"
:correctly would be:
:
:    generic
:        type Some_Type is new My_Type with private;
:        with package IX is new X(Some_Type);
:    procedure Generic_Op(...);
:
:Here, any supplied instance for IX must have been obtained via My_Type or
:one of its descendants.

Thanks for the example. 

Sounds like a good argument for unifying module and type. :)  (No, I don't
want to debate that one again).


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 8%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-07  0:00 11%                   ` Jon S Anthony
@ 1996-11-11  0:00 13%                     ` Don Harrison
  0 siblings, 0 replies; 99+ results
From: Don Harrison @ 1996-11-11  0:00 UTC (permalink / raw)



Jon S Anthony writes:

:Unfortunately, that depends on what you mean by "simple".  

Yes, the concept is relative. :(

:I think the real problem here is that dynamic binding is not the same
:category of thing as overloading and so comparing the two leads to
:confusion.

Yes, and that seems to have happened. :)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 13%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-08  0:00 10%                   ` bill.williams
@ 1996-11-11  0:00  7%                     ` Don Harrison
  0 siblings, 0 replies; 99+ results
From: Don Harrison @ 1996-11-11  0:00 UTC (permalink / raw)



Bill Williams writes:

:Which set of parentheses, 1st or 2nd?

2nd.

:I'm not sure I understand what you're saying here. Can we try an
:example so you can tell me that I've got the wrong end of the
:proverbial stick? 

I'll attempt to clarify what I'm saying. It is simply that Ada and Eiffel
offer different rules for selecting the polymorphic operation. The following 
table hopefully summarises the essential differences between the two schemes:

                           Ada                         Eiffel
--------------------------------------------------------------------------------

1) How selected?           Implicit                    Explicit

2) Which selected?         Same signature except for   Redefines clause (+ optional
                           dispatching parameter       select clause for repeated
                                                       inheritance)

3) Selection choice?       No                          Yes

4) Safe?                   Yes                         Yes (if supported by static
                                                       validity rules); No (if not)
5) Other operations        Yes (if has same name)      No (must have different name)
   overloaded?

In the case of Ada, any operation that happens to have the same name as the
polymorphic operation will happen to be overloaded. This has no effect on the 
semantics of polymorphism. I hope this clarifies the issue. If still unsure, 
re-read my post containing the example comparing Ada and Eiffel plus the addendum 
about repeated inheritance.

:Suppose I write a complex number class (gosh, how original) and I
:define all the normal arithmetic operators. In Ada I can overload
:these operators to define 
:  <complex> + <real> 
:as well as 
:  <complex> + <complex>
:[I can do it in C++ as well, but we won't mention that...]
:You seem to be suggesting that in Eiffel I need to define a class
:which inherits from complex and defines interactions with reals. 

Perish the thought. :)

:But even this doesn't work. If I have a variable which is of the
:complex class I can't add reals to it. If it's of the interaction
:class, then I can't add complex's to it. The only solution Eiffel
:offers me is to define 'add_complex' and 'add_real' members to the
:complex class. While this achieves the functionality I need it falls
:way short in terms of ease of maintenance when 'programming in the
:large' IMO.

This is basically what I have in mind except that 'add_complex' may just be
called 'add'. Something like:

  - Class NUMERIC contains an 'add' operation for NUMERICs
  - Class NUMERIC has heirs COMPLEX and REAL.

  - Class REAL redefines 'add' covariantly to add REALs

  - Class COMPLEX redefines 'add' covariantly to add COMPLEXes
  - Class COMPLEX defines an 'add_real' to add COMPLEX and REAL.

(Details omitted to protect the innocent).
  
:Sorry, you've prodded one of the bees in my bonnet w.r.t Eiffel and I
:just couldn't let this one go by.

Yes, I've noticed you have a few. :)


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 7%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-08  0:00  7%             ` Don Harrison
@ 1996-11-08  0:00 12%               ` Robert A Duff
  1996-11-12  0:00  8%                 ` Don Harrison
  1996-11-08  0:00 11%               ` Jon S Anthony
                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 99+ results
From: Robert A Duff @ 1996-11-08  0:00 UTC (permalink / raw)



In article <E0JIJu.G98@syd.csa.com.au>,
Don Harrison <donh@syd.csa.com.au> wrote:
>...What would be clearer and less confusing, 
>IMO, would be to declare the parametric information in a type together with 
>the operation so that when you instantiate (explicitly) with that type 
>(or a descendant type), you get the right operation with it. This way, it's 
>very plain what the actual instantiation parameters are.
>
>Not sure how you would write this in Ada.

This feature exists in Ada 95.  Look up generic formal derived types in
the reference manual.  Basically, you declare in the generic that the
actual will be derived from some particular type, so inside the generic
you can call the operations inherited from that type, and at the
instantiation point, the compiler checks that the actual is in fact in
the correct class.  Programming by contract and all that good stuff.

- Bob




^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-08  0:00  7%             ` Don Harrison
  1996-11-08  0:00 12%               ` Robert A Duff
@ 1996-11-08  0:00 11%               ` Jon S Anthony
  1996-11-14  0:00  8%               ` Robert I. Eachus
  1996-11-15  0:00  9%               ` portmanteau (was Re: Eiffel and Java + Ada dispatching) Robert I. Eachus
  3 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-08  0:00 UTC (permalink / raw)



In article <E0JIJu.G98@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Robert I. Eachus writes:
> 
> :significant.  It is a very useful feature to be able to instantiate a
> :generic in a scope and inherit the local statically enclosing
> :definitions of certain operations.  It is even more useful that the
> :operations are selected based on the name of the function AND the
> :parameter and return value profile.  You not only get the local
> :operator, you get the right version to match the other generic
> :formals.
> 
> Okay but the problem I have with this is that picking up the local stuff 
> implicitly as parameters to the instantiation is potentially confusing
> (as your example demonstrates). What would be clearer and less confusing, 
> IMO, would be to declare the parametric information in a type together with 
> the operation so that when you instantiate (explicitly) with that type 
> (or a descendant type), you get the right operation with it. This way, it's 
> very plain what the actual instantiation parameters are.
>
> Not sure how you would write this in Ada. Maybe (excuse the syntax errors) 

That's one of the "typical" uses for generic formal package parameters.  It
is one of the reasons they were included.

    generic
        type Some_Type is tagged private;
        with function Some_Op (...) return Some_Type;
    package X is end X;


    generic
        with package IX is new X(<>); -- No added constraints on Inst. of X
    procedure Generic_Op(...);


    package IX is new X(My_Type);
    procedure Actual_Op is new Generic_Op(IX);

An obvious variant that may prove useful in making sure things "line up"
correctly would be:

    generic
        type Some_Type is new My_Type with private;
        with package IX is new X(Some_Type);
    procedure Generic_Op(...);

Here, any supplied instance for IX must have been obtained via My_Type or
one of its descendants.


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 11%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-07  0:00  8%                 ` Don Harrison
                                     ` (2 preceding siblings ...)
  1996-11-07  0:00 13%                   ` Jon S Anthony
@ 1996-11-08  0:00 10%                   ` bill.williams
  1996-11-11  0:00  7%                     ` Don Harrison
  3 siblings, 1 reply; 99+ results
From: bill.williams @ 1996-11-08  0:00 UTC (permalink / raw)




donh@syd.csa.com.au (Don Harrison) writes:

> However, in relation to Eiffel, I'm saying that it has no *need* of an 
> overloading mechanism because it is redundant due to the availability of 
> covariance. An operation which you might choose to implement in Ada by 
> overloading an inherited one (because they do the same job), you would 
> implement in Eiffel as an overriding operation because it belongs in the 
> same inheritance hierarchy (according to Eiffel's scheme of things).
> 
> [Before half the world disputes the latter part of this sentence, kindly note 
> the qualifier in parentheses].

Which set of parentheses, 1st or 2nd?

I'm not sure I understand what you're saying here. Can we try an
example so you can tell me that I've got the wrong end of the
proverbial stick? 

Suppose I write a complex number class (gosh, how original) and I
define all the normal arithmetic operators. In Ada I can overload
these operators to define 
  <complex> + <real> 
as well as 
  <complex> + <complex>
[I can do it in C++ as well, but we won't mention that...]
You seem to be suggesting that in Eiffel I need to define a class
which inherits from complex and defines interactions with reals. But
even this doesn't work. If I have a variable which is of the
complex class I can't add reals to it. If it's of the interaction
class, then I can't add complex's to it. The only solution Eiffel
offers me is to define 'add_complex' and 'add_real' members to the
complex class. While this achieves the functionality I need it falls
way short in terms of ease of maintenance when 'programming in the
large' IMO.

Sorry, you've prodded one of the bees in my bonnet w.r.t Eiffel and I
just couldn't let this one go by.

Cheers
Bill
-- 
Bill Williams                     |GEC-Marconi does not necessarily
GEC-Marconi Research Centre       |endorse my opinions!

bill.williams@gecm.com
Tel: +44 1245 242016
Fax: +44 1245 242003





^ permalink raw reply	[relevance 10%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-08  0:00  6%                     ` Don Harrison
@ 1996-11-08  0:00  9%                       ` Don Harrison
  1996-11-14  0:00 10%                         ` Jon S Anthony
  0 siblings, 1 reply; 99+ results
From: Don Harrison @ 1996-11-08  0:00 UTC (permalink / raw)



(A bit of explanation on my last post). I wrote:

:I think the choice in Eiffel of making specialisations functionally equivalent
:to their generalisations is the right one in terms of modelling integrity.

By 'functionally equivalent to', I mean 'polymorphic wrt'. 

The issue of modelling integrity implies a pragmatic consideration as well.
If specialisations reflect greater modelling integrity, you would also expect
that specialised operations are what you would want to *use* (call) most of the 
time rather than general ones. It makes sense, then (to maximise the power of
dynamic binding), for them to be polymorphic wrt the parent class. I don't
have any data to back this up but it seems logical. (if someone can confirm
this, please share it with us).

If it's true that specialisations *are* the operations you want most often,
then making the general (inherited) operations polymorphic means that dynamic
binding is wasted on a minority of calls.


I should also clarify the following.

: ... So, Eiffel 
: dispatches to a more specific operation by default rather than to a more general 
: one.

should read

... So, Eiffel 
dispatches to a more specific operation by default and does not inherit the
more general parent operation. However, if you *do* want the parent operation
as well, then you can repeatedly inherit it and leave one the same and 
specialise the other. This is where Eiffel is very flexible compared with Ada 
because you can nominate *either* the inherited (parent) operation *or* the 
specialised one to be polymorphic wrt the parent. 

and

: So, Ada dispatches to a more general operation by default rather than to a 
: more specific one. ... 

should read

So, Ada dispatches to the general (inherited) operation by default rather than 
to a more specific new one. ... 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 9%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 10%           ` Robb Nebbe
  1996-11-06  0:00  7%             ` Jean-Marc Jezequel
  1996-11-06  0:00  7%             ` To overload or not to overload (was Eiffel and Java + Ada dispatching) Don Harrison
@ 1996-11-08  0:00  8%             ` Robert I. Eachus
  2 siblings, 0 replies; 99+ results
From: Robert I. Eachus @ 1996-11-08  0:00 UTC (permalink / raw)



In article <55p0i3$2u4@tjnews.is.s.u-tokyo.ac.jp> jezequel@piccolo.is.s.u-tokyo.ac.jp (Jean-Marc Jezequel) writes:

  > Just to change the subject, does anyone know why the designers of
  > Ada95 did not choose to include the true multiple-dispatch a la
  > CLOS (or point to a reference on this)?  At leat the syntax have
  > been a problem; whereas it is in Java/C++/Eiffel.

    It was felt to be too much work for too little gain.  With the
current rules a programmer can provide a multiply dispatching routine,
and it is not that uncommon.  But there is a little extra work for the
implementor of the operation, but it is linear.  (In other words if
you have a routine:

     function Foo(X: Foob; Y: Foob'CLASS) return Boolean;

    That underneath calls:

     function Foobar(X: Foob'CLASS; Y: Foob; Additional: Parameters)
        return Boolean;

   Then simulating 'true' multiple dispatch may require overriding Foo
and Foobar for a new descendent of Foob, not just redefinition of Foo.
But the amount of work to be done, assuming you know what you are
doing is the same.

   For example, I created a heterogenous list class, and thought that
it would be nice to have the operation:

   function "&"(X,Y: Object'Class) return List;

   where X and Y can be of any type descended from Object.  The body
is REAL easy:

   function "&"(X,Y: Object'Class) return List is
   begin return Append(New_List(X),Y); end "&";

   Append and New_List are functions that are dispatching and may
require overriding, but as you can see, the "&" above dispatches on
both parameters, but doesn't require writing N squared operations for
N new subclasses.  In fact, it will usually be the case that no new
operations need to be writen or overridden when a new object type is
added to the list.  In more complex cases, the programmer may have
some work to do to figure out how to keep the implementation burden of
adding a new class under control, but in general you simply can't
manage the N-squared case and don't want to.

   (This is not to say that there aren't cases where you want to
implement boundary conditions with special values. For example a list
type that can contain other lists, but that I have never seen any case
where you want the general non-linear complexity.)

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-06  0:00  8%           ` Robert I. Eachus
@ 1996-11-08  0:00  7%             ` Don Harrison
  1996-11-08  0:00 12%               ` Robert A Duff
                                 ` (3 more replies)
  0 siblings, 4 replies; 99+ results
From: Don Harrison @ 1996-11-08  0:00 UTC (permalink / raw)



Robert I. Eachus writes:

:   Okay... (This code is for demonstration purposes only...these
:features are useful, but not often used with predefined types or small
:generics.)
:
:   generic
:     with function "+"(L, R: Integer) return Integer is <>;
:   procedure Test(X,Y: in Integer);
:   
:   
:   with Text_IO;
:   procedure Test(X,Y: in Integer) is 
:   begin
:     Text_IO.Put_Line(" The sum of" & Integer'IMAGE(X) & " and" &
:               Integer'IMAGE(Y) & " is" & Integer'IMAGE(X+Y) & ".");
:   end Test;
:
:   with Test;
:   procedure Main is
:     procedure Test1 is new Test;
:
:     function "+"(L,R: Integer) return Integer
:     is begin return L*R; end "+";
:
:     procedure Test2 is new Test;
:   
:  begin 
:    Test1(5, 10);
:    Test2(5, 10);
:  end Main;
:
:spectre% main
: The sum of 5 and 10 is 15.
: The sum of 5 and 10 is 50.

Thanks for the example.

:     Notice that a much more normal situation would have the two
:instantiations in non-overlapping scopes, and the operator definitions
:coming from a package which defined some generic formal type.
:
:     What this is showing is not that it is possible to maliciously
:mess with definition of "+", 

Okay, we'll try to ignore that. :)

but that the fact that parameter matching
:for generic formal subprogram parameters uses overloading rules is
:significant.  It is a very useful feature to be able to instantiate a
:generic in a scope and inherit the local statically enclosing
:definitions of certain operations.  It is even more useful that the
:operations are selected based on the name of the function AND the
:parameter and return value profile.  You not only get the local
:operator, you get the right version to match the other generic
:formals.

Okay but the problem I have with this is that picking up the local stuff 
implicitly as parameters to the instantiation is potentially confusing
(as your example demonstrates). What would be clearer and less confusing, 
IMO, would be to declare the parametric information in a type together with 
the operation so that when you instantiate (explicitly) with that type 
(or a descendant type), you get the right operation with it. This way, it's 
very plain what the actual instantiation parameters are.

Not sure how you would write this in Ada. Maybe (excuse the syntax errors)

   type Some_Type is tagged ...
   function Some_Op (...) return Some_Type;

   generic
     type T is private;
   procedure Generic_Op (...);

   ...

   procedure Actual_Op is new Generic_Op (Some_Type);

The implicit resolution stuff is not a good idea, IMHO.

:     (Note that to get the local definitions of predefined operators
:for types, generic formal and otherwise, you need to explicitly
:declare those operators as generic formal subprograms.  But the at the
:point of the instantiation, defaults allow the user to ignore these
:"extra" formal parameters.)

Understand.

:     Now what does all this have to do with the no overloading model?
:There are programs which take advantage of these rules that can be
:rewritten--but not trivially--to work in the absence of overloading.
:And the non-overloading version will be exponentially larger than the
:version which uses overloading and generics.

If the non-overloading versions are exponentially larger, maybe the originals 
were a bit dodgy anyway. :)

:     The case of generics with formal tagged type parameters is even
:more complex.  (The ARG is trying to decide just how much more
:complex. ;-)

Sounds like a headache. :)

IMHO, overloading should have no semantic impact. It should merely be 
'syntactic sugar' as Jean-Marc suggested.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 7%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-07  0:00 11%                   ` Juergen Schlegelmilch
@ 1996-11-08  0:00  6%                     ` Don Harrison
  1996-11-08  0:00  9%                       ` Don Harrison
  1996-11-14  0:00 10%                     ` Jon S Anthony
  1 sibling, 1 reply; 99+ results
From: Don Harrison @ 1996-11-08  0:00 UTC (permalink / raw)



I wrote:

:>However, in relation to Eiffel, I'm saying that it has no *need* of an 
:>overloading mechanism because it is redundant due to the availability of 
:>covariance. An operation which you might choose to implement in Ada by 
:>overloading an inherited one (because they do the same job), you would 
:>implement in Eiffel as an overriding operation because it belongs in the 
:>same inheritance hierarchy (according to Eiffel's scheme of things).

These comments are made in the context of the example Jon Anthony and I
discussed. The different schemes of Ada and Eiffel might be demonstrated 
by expanding the example Jon and I were discussing.

Assuming types A and B with heirs C and D repectively. Consider the following
operations:

Ada                                        Eiffel
---                                        ------

A's operations
op (a: A; b: B'Class)                (1)    In A: op (b: B)                  (4)

B's operations
op (c: C; d: D'Class)  -- overloaded (2)   In C: op (d: D)      -- overrided (5)
op (c: C; b: B'Class)  -- inherited  (3)   In C: new_op (b: B)  -- new       (6)

What we see is that Ada has taken the safe approach of diverting polymorphism
down the avariant path (3). The specialised op (2) becomes an overloaded 
operation and is no longer polymorphic wrt (1). Note that (3) is more general
than (2).

On the Eiffel side, polymorphism continues down the line of specialisation
(true covariance) so that (5) is polymorphic wrt (4). The more general (6)
is a new operation.

Now the contentious part. :(  The issue of which model is 'correct' depends on
which operation of B can better be regarded as functionally equivalent to 
the operation in A. (The safety issue is secondary, IMO - I'm talking about
modelling integrity). What seems to happen in the real world is that as
interactions between things become more specific, the things involved become
more specific as well (or some may stay the same). (The things do not become
*less* specific, but that is another matter). To model this faithfully,
you would need multiple dispatching but for most purposes, you can use use the
simpler (but lop-sided) model of single dispatching. But the important thing
is that we need to cater for the situation of both things becoming more
specific. If we don't, then what we end up with is specialisations that are
lop-sided and are capable of modelling only the special case where only one
thing becomes more specialised. (This is what happens in Ada).

I think the choice in Eiffel of making specialisations functionally equivalent
to their generalisations is the right one in terms of modelling integrity.
The downside is having then to deal with the non-trivial problem of breaking
polymorphism. :(  By comparison, the Ada model is completely safe, but it
sacrifices modelling integrity to acheive it, IMO.


Juergen Schlegelmilch wrote:

:Hm, being not too familiar with Ada, I may be wrong, but in the subclass
:you have both operations available, while with Eiffel's redefinition you
:only have the redefined but not the inherited (unless you inherited once,
                                                                     ^^^^
                                                                     twice?

:but then you have to rename). Thus, in a piece of code where an operation 
:is applied to arguments suitable only for the inherited version, Eiffel 
:will signal a type error (system validity or by runtime crash :-), 

IMO, this is what ought to happen because because the operation has become 
more specific and so requires more specific parameters. The parameter 
combination provided is invalid, so the runtime system (correctly) raises an 
exception. This highlights the fact that there is an error in the client which 
must be fixed. If a more general operation realy *is* required, then you can 
define a *new* operation [(6) in my example] for this purpose. So, Eiffel 
dispatches to a more specific operation by default rather than to a more general 
one. This differs from Ada which ...

: will use the inherited (overloaded) version.

So, Ada dispatches to a more general operation by default rather than to a 
more specific one. This is the wrong way round, IMO. I think calling a more 
general operation ought to be the exception rather than the default. Some will 
not agree with me but that's okay. :)

:So, covariant redefinition is not a mechanism to implement/simulate 
:overloading.

Just as well I didn't say that then. :)

I *am* saying that because Eiffel is covariant, you don't have to re-invent
an operation as an overloaded operation due to inheriting some unwanted 
baggage that no longer reflects the specialisation of an abstraction. 


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 6%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-07  0:00  8%                 ` Don Harrison
  1996-11-07  0:00 11%                   ` Jon S Anthony
  1996-11-07  0:00 11%                   ` Juergen Schlegelmilch
@ 1996-11-07  0:00 13%                   ` Jon S Anthony
  1996-11-08  0:00 10%                   ` bill.williams
  3 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-07  0:00 UTC (permalink / raw)



In article <slrn5836sh.rl.schlegel@pella.informatik.uni-rostock.de> schlegel@pella.informatik.uni-rostock.de (Juergen Schlegelmilch) writes:

> In article <E0HKx9.8E3@syd.csa.com.au>, Don Harrison wrote:
> >
> >However, in relation to Eiffel, I'm saying that it has no *need* of an 
> >overloading mechanism because it is redundant due to the availability of 
> >covariance. An operation which you might choose to implement in Ada by 
> >overloading an inherited one (because they do the same job), you would 
> >implement in Eiffel as an overriding operation because it belongs in the 
> >same inheritance hierarchy (according to Eiffel's scheme of things).
> 
> Hm, being not too familiar with Ada, I may be wrong, but in the subclass
> you have both operations available, 

Correct.


> while with Eiffel's redefinition you only have the redefined but not
> the inherited (unless you inherited once, but then you have to
> rename). Thus, in a piece of code where an operation is applied to
> arguments suitable only for the inherited version, Eiffel will
> signal a type error (system validity or by runtime crash :-), while
> Ada will use the inherited (overloaded) version.

Correct.


> So, covariant redefinition is not a mechanism to implement/simulate
> overloading.

Interesting point.  The other way 'round though, does sound "right"...

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 13%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 11%         ` Don Harrison
                             ` (2 preceding siblings ...)
  1996-11-06  0:00  8%           ` Robert I. Eachus
@ 1996-11-07  0:00 12%           ` Jon S Anthony
  1996-11-07  0:00 10%           ` Robb Nebbe
  1996-11-12  0:00  8%           ` Jon S Anthony
  5 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-07  0:00 UTC (permalink / raw)



In article <6KJFAjVF3RB@herold.franken.de> jhd@herold.franken.de (Joachim Durchholz) writes:

> However, the central difference is that dynamic binding is always there in  
> Eiffel. You don't have to rewrite Eiffel code to make overloading work,  
> you just don't use polymorphism. You'd have to rewrite Ada code to go from  
> overloading to dynamic binding.

This is a category error.  Overloading is not the same sort of thing
as dynamic binding.  The counterpart that you want is static binding.
A reasonable (though certainly not exact) counter part ot overloading
in this context would be "covariance".  Overloading affects what
operation will be dynamically bound in an invocation, but it in no way
affects _whether_ the invocation is dynamically bound.

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 12%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-06  0:00 11%               ` Robb Nebbe
  1996-11-07  0:00  8%                 ` Don Harrison
@ 1996-11-07  0:00 12%                 ` Norman H. Cohen
  1 sibling, 0 replies; 99+ results
From: Norman H. Cohen @ 1996-11-07  0:00 UTC (permalink / raw)



Robb Nebbe wrote:

> Ignoring scoping rules we see that:
> 
> C uses just the name.
> 
> Eiffel uses the name and the type of one of the parameters.
> 
> Ada uses the name and the type of all the parameters.

Ada also distinguishes whether a call is a procedure call or a function
call and, in the case of a function call, considers the result type
expected in a given context.  Thus

   procedure P (X: in Integer; Y: out Float);
   function P (X: Integer; Y: Float) return Character;
   function P (X: Integer; Y: Float) return String;

can all be overloaded (which is not the case for the corresponding
declarations in C++ or Java). 

-- 
Norman H. Cohen
mailto:ncohen@watson.ibm.com
http://www.research.ibm.com/people/n/ncohen




^ permalink raw reply	[relevance 12%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-07  0:00  8%                 ` Don Harrison
  1996-11-07  0:00 11%                   ` Jon S Anthony
@ 1996-11-07  0:00 11%                   ` Juergen Schlegelmilch
  1996-11-08  0:00  6%                     ` Don Harrison
  1996-11-14  0:00 10%                     ` Jon S Anthony
  1996-11-07  0:00 13%                   ` Jon S Anthony
  1996-11-08  0:00 10%                   ` bill.williams
  3 siblings, 2 replies; 99+ results
From: Juergen Schlegelmilch @ 1996-11-07  0:00 UTC (permalink / raw)



In article <E0HKx9.8E3@syd.csa.com.au>, Don Harrison wrote:
>
>However, in relation to Eiffel, I'm saying that it has no *need* of an 
>overloading mechanism because it is redundant due to the availability of 
>covariance. An operation which you might choose to implement in Ada by 
>overloading an inherited one (because they do the same job), you would 
>implement in Eiffel as an overriding operation because it belongs in the 
>same inheritance hierarchy (according to Eiffel's scheme of things).

Hm, being not too familiar with Ada, I may be wrong, but in the subclass
you have both operations available, while with Eiffel's redefinition you
only have the redefined but not the inherited (unless you inherited once,
but then you have to rename). Thus, in a piece of code where an operation 
is applied to arguments suitable only for the inherited version, Eiffel 
will signal a type error (system validity or by runtime crash :-), while Ada 
will use the inherited (overloaded) version.

So, covariant redefinition is not a mechanism to implement/simulate 
overloading.

  Juergen Schlegelmilch

-- 
+-----------------------------------------------------------------------------+
 Dipl.-Inf. Juergen Schlegelmilch                 University of Rostock
 email: schlegel@Informatik.Uni-Rostock.de        Computer Science Department
 http://www.informatik.uni-rostock.de/~schlegel   Database Research Group 
 Tel: ++49 381 498 3402                           18051 Rostock 
 Fax: ++49 381 498 3426                           Germany
+-----------------------------------------------------------------------------+





^ permalink raw reply	[relevance 11%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-07  0:00  8%                 ` Don Harrison
@ 1996-11-07  0:00 11%                   ` Jon S Anthony
  1996-11-11  0:00 13%                     ` Don Harrison
  1996-11-07  0:00 11%                   ` Juergen Schlegelmilch
                                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 99+ results
From: Jon S Anthony @ 1996-11-07  0:00 UTC (permalink / raw)



In article <E0HKx9.8E3@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Robb Nebbe writes:
> 
> :To overload or not to overload is not the question IMO.
> :Overloading is a language mechanism that Ada has and Eiffel
> :doesn't; this is an apples and oranges problem. The real question
> :is how do languages figure out which method should be invoked.
> 
> Yes, a nice non-contentious topic of discussion is just that. Personally,
> I'm more interested in what is the simplest binding mechanism a language
> can provide which does everything you need and no more than you need.

Unfortunately, that depends on what you mean by "simple".  While
Eiffel is simple in some aspects here (has only one construct), it is
complex in others (who understands "broken" polymorphism and the
attendant system validity issues?)  Ada is simple in some aspects (no
broken pm or worries about what it may mean, while letting you
basically do what you want in this context [refine on non controlling
parameters]) but more complex in that it has another construct:
overloading and this might fool you at times.

The whole thing boils down to tradeoffs, which in turn depend in large
measure on the overall context.


> However, in relation to Eiffel, I'm saying that it has no *need* of an 
> overloading mechanism because it is redundant due to the availability of 
> covariance.

True.  But it pays a non-trivial price for this.


> So, for Eiffel, rather than dynamic binding overlapping with overloading,
> it obviates the need for it.

I think the real problem here is that dynamic binding is not the same
category of thing as overloading and so comparing the two leads to
confusion.

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 11%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 11%         ` Don Harrison
                             ` (3 preceding siblings ...)
  1996-11-07  0:00 12%           ` Eiffel and Java + Ada dispatching Jon S Anthony
@ 1996-11-07  0:00 10%           ` Robb Nebbe
  1996-11-12  0:00  8%           ` Jon S Anthony
  5 siblings, 0 replies; 99+ results
From: Robb Nebbe @ 1996-11-07  0:00 UTC (permalink / raw)



Joachim Durchholz wrote:

> However, the central difference is that dynamic binding is always there in
> Eiffel. You don't have to rewrite Eiffel code to make overloading work,
> you just don't use polymorphism. You'd have to rewrite Ada code to go from
> overloading to dynamic binding.

If you need dynamic binding then it certainly isn't overloading that you would
use to replace it. Overloading and dispatching are certainly related language
mechanisms but not in this way. Ada has both dispatching and overlaoding.
Eiffel has just dispatching. However, some of what Eiffel does with
dispatching Ada does with overloading.

This is because it is much easier to reason about polymorphism locally in Ada
than it is in Eiffel. When there is no dispatching Ada uses overloading to
resolve which operation is invoked. In contrast Eiffel always uses the
dispatching rules but the dispatch might be optimized away. So if someone says
overloading in Ada is bad do they mean the part that overlaps with dispatching
in Eiffel or the part that goes beyond what you can do in Eiffel?  

If you adopt an Eiffel point of view and ask yourself what would overloading
give me that Eiffel doesn't already provide then you come to the conclusion
that there really isn't any major reason to add overloading to Eiffel.
However, you can not conclude that you can just rip overloading out of any
language because it might play a more important role in some other language,
such as Ada.

Generalizing knowledge about one language to another language is very
difficult without an intimate understanding of the other language. The real
kicker is it is also very difficult to know when you have achieved this level
of undertanding :-)

Robb Nebbe




^ permalink raw reply	[relevance 10%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-06  0:00 11%               ` Robb Nebbe
@ 1996-11-07  0:00  8%                 ` Don Harrison
  1996-11-07  0:00 11%                   ` Jon S Anthony
                                     ` (3 more replies)
  1996-11-07  0:00 12%                 ` Norman H. Cohen
  1 sibling, 4 replies; 99+ results
From: Don Harrison @ 1996-11-07  0:00 UTC (permalink / raw)



Robb Nebbe writes:

:To overload or not to overload is not the question IMO.
:Overloading is a language mechanism that Ada has and Eiffel
:doesn't; this is an apples and oranges problem. The real question
:is how do languages figure out which method should be invoked.

Yes, a nice non-contentious topic of discussion is just that. Personally,
I'm more interested in what is the simplest binding mechanism a language
can provide which does everything you need and no more than you need.

:Ignoring scoping rules we see that:
:
:C uses just the name.
:
:Eiffel uses the name and the type of one of the parameters.
:
:Ada uses the name and the type of all the parameters.

Nice summary.

:C is broken. When you program in C you have to come up with naming
:schemes to avoid identifier clashes. 

We can always agree by throwing rocks at C. :)

:Eiffel and Ada work just
:fine. If Eiffel truly used just the name and nothing more then not
:only would every routine of every class have to have a different
:name but polymorphism would be impossible. 

Yes.

:Languages are essentially sets of mechanisms. You seem to be
:claiming that Ada has one mechanism and Eiffel doesn't when in
:fact even though Eiffel doesn't have the same mechanism it does
:have one that overlaps.

I think we're saying pretty much the same thing - that individual binding 
mechanisms should not be considered in isolation but in relation to each 
other. 

However, in relation to Eiffel, I'm saying that it has no *need* of an 
overloading mechanism because it is redundant due to the availability of 
covariance. An operation which you might choose to implement in Ada by 
overloading an inherited one (because they do the same job), you would 
implement in Eiffel as an overriding operation because it belongs in the 
same inheritance hierarchy (according to Eiffel's scheme of things).

[Before half the world disputes the latter part of this sentence, kindly note 
the qualifier in parentheses].

So, for Eiffel, rather than dynamic binding overlapping with overloading,
it obviates the need for it.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-06  0:00  7%             ` Jean-Marc Jezequel
@ 1996-11-07  0:00  8%               ` Robb Nebbe
  0 siblings, 0 replies; 99+ results
From: Robb Nebbe @ 1996-11-07  0:00 UTC (permalink / raw)



Jean-Marc Jezequel wrote:

> 
> May be we have a different idea on the meaning of `semantics', but IMHO 
> there is a difference. In one case it has to be done at compile time (and > e.g. implemented using unique names as you pointed out). In case of 
> dynamic binding, it has (conceptualy) to be deferred until run-time,and is 
> basically implemented with a test on the object dynamic type (Ada tag?) to 
> select the right procedure.

I'm using the the standard definition of semantics as it relates to the
meaning of a program. Semantics has to do with _what_ and NOT _when_; "when"
is closely related to "how" and is an implementation issue.

Do Eiffel compilers change the meaning of a program when they optimize away
a dispatching call? If not then it is not a semantic issue. I agree
completely that there is a difference but for me it is not related to the
semantics of the program.

>Robb Nebbe wrote:
> > When Eiffel compilers optimize away dispatching all they are really
> > doing is static overload resolution.

> I beg to differ. What they do is to determine statically that the 
> recipient of a call happends in a *given program* to be of exactly one 
> type. Since the runtime type test would then return a constant, they just 
> optimize out the test.

In Eiffel there are static and dynamic types where the static type is used
to type checking and the dynamic type for dispatching. In Ada there are
specific types and class-wide types. The relationship is as folows: A
dynamic type in Eiffel always corresponds to a specific-type in Ada. A
static type is either a specific type or a class-wide type. In some cases,
such as creation, it must be a specifc-type but most of the time it is
ambiguous and so in the absence of flow analysis it must be assumed to be a
class-wide type, which is the more general of the two cases.

Now there are two cases in Eiffel where you can optimize dispatching. The
first case is when you know that a static type is a specific type (for
exmple after creation). This means that you can optimize away the
dispatching because there will never be any need to dispatch in any program.
This is decidable locally in Eiffel. The second case is when you can
determine through analysis of the entire program that a static type is in
fact a specific-type then you can optimize away the dispatching because it
is never needed in that specific program. This is only decidable globally in
Eiffel.

In the first case the compiler can determine at compile time which routine
to call based on the name of the routine and the type (which is known to be
what Ada calls a specific type) of one of the "parameters" (the term is used
very loosely so use your imagination).

Can you see the analogy with overloading? I didn't mean to pretend that they
are precisely the same (which you would have been a reasonable
interpretation of my previous post :-) just that they are similar. Claiming
that Eiffel has no overloading, while technically correct, provides
virtually no insight into the relationship between Ada and Eiffel. I would
prefer that these discussions lead to a better understanding of this
relationship at some meaningful level.

Robb Nebbe




^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 10%         ` Don Harrison
@ 1996-11-06  0:00 13%           ` Jon S Anthony
  0 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-06  0:00 UTC (permalink / raw)



In article <E0F592.Iv3@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Jon S Anthony wrote (privately):
> 
> :News is clearly running behind and the note of my you were replying to
> :below was before I saw a few of your other posts which clearly show
> :you understand this stuff afterall.  Mea Culpa.  Guilty twit.  Grade A
> :stupid.  Whatever else you want to call me. ;-)
> 
> Grovelling apology accepted but I would have more respect for you if it
> were as public as your allegation.

This is not a "grovelling apology" - it is simply accurate.  I'm not sure
what you mean about "public allegation"??  Shrug.  There was no allegation
anywhere (that I can tell anyway).

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 13%]

* Re: To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-06  0:00  7%             ` To overload or not to overload (was Eiffel and Java + Ada dispatching) Don Harrison
@ 1996-11-06  0:00 11%               ` Robb Nebbe
  1996-11-07  0:00  8%                 ` Don Harrison
  1996-11-07  0:00 12%                 ` Norman H. Cohen
  0 siblings, 2 replies; 99+ results
From: Robb Nebbe @ 1996-11-06  0:00 UTC (permalink / raw)



To overload or not to overload is not the question IMO.
Overloading is a language mechanism that Ada has and Eiffel
doesn't; this is an apples and oranges problem. The real question
is how do languages figure out which method should be invoked.

Ignoring scoping rules we see that:

C uses just the name.

Eiffel uses the name and the type of one of the parameters.

Ada uses the name and the type of all the parameters.


C is broken. When you program in C you have to come up with naming
schemes to avoid identifier clashes. Eiffel and Ada work just
fine. If Eiffel truly used just the name and nothing more then not
only would every routine of every class have to have a different
name but polymorphism would be impossible. 

Languages are essentially sets of mechanisms. You seem to be
claiming that Ada has one mechanism and Eiffel doesn't when in
fact even though Eiffel doesn't have the same mechanism it does
have one that overlaps.

Robb




^ permalink raw reply	[relevance 11%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 11%         ` Don Harrison
  1996-11-05  0:00 10%           ` Robb Nebbe
  1996-11-05  0:00  9%           ` Joachim Durchholz
@ 1996-11-06  0:00  8%           ` Robert I. Eachus
  1996-11-08  0:00  7%             ` Don Harrison
  1996-11-07  0:00 12%           ` Eiffel and Java + Ada dispatching Jon S Anthony
                             ` (2 subsequent siblings)
  5 siblings, 1 reply; 99+ results
From: Robert I. Eachus @ 1996-11-06  0:00 UTC (permalink / raw)




   Okay... (This code is for demonstration purposes only...these
features are useful, but not often used with predefined types or small
generics.)

   generic
     with function "+"(L, R: Integer) return Integer is <>;
   procedure Test(X,Y: in Integer);
   
   
   with Text_IO;
   procedure Test(X,Y: in Integer) is 
   begin
     Text_IO.Put_Line(" The sum of" & Integer'IMAGE(X) & " and" &
               Integer'IMAGE(Y) & " is" & Integer'IMAGE(X+Y) & ".");
   end Test;

   with Test;
   procedure Main is
     procedure Test1 is new Test;

     function "+"(L,R: Integer) return Integer
     is begin return L*R; end "+";

     procedure Test2 is new Test;
   
  begin 
    Test1(5, 10);
    Test2(5, 10);
  end Main;

spectre% main
 The sum of 5 and 10 is 15.
 The sum of 5 and 10 is 50.

     Notice that a much more normal situation would have the two
instantiations in non-overlapping scopes, and the operator definitions
coming from a package which defined some generic formal type.

     What this is showing is not that it is possible to maliciously
mess with definition of "+", but that the fact that parameter matching
for generic formal subprogram parameters uses overloading rules is
significant.  It is a very useful feature to be able to instantiate a
generic in a scope and inherit the local statically enclosing
definitions of certain operations.  It is even more useful that the
operations are selected based on the name of the function AND the
parameter and return value profile.  You not only get the local
operator, you get the right version to match the other generic
formals.

     (Note that to get the local definitions of predefined operators
for types, generic formal and otherwise, you need to explicitly
declare those operators as generic formal subprograms.  But the at the
point of the instantiation, defaults allow the user to ignore these
"extra" formal parameters.)

     Now what does all this have to do with the no overloading model?
There are programs which take advantage of these rules that can be
rewritten--but not trivially--to work in the absence of overloading.
And the non-overloading version will be exponentially larger than the
version which uses overloading and generics.

     The case of generics with formal tagged type parameters is even
more complex.  (The ARG is trying to decide just how much more
complex. ;-)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 10%           ` Robb Nebbe
@ 1996-11-06  0:00  7%             ` Jean-Marc Jezequel
  1996-11-07  0:00  8%               ` Robb Nebbe
  1996-11-06  0:00  7%             ` To overload or not to overload (was Eiffel and Java + Ada dispatching) Don Harrison
  1996-11-08  0:00  8%             ` Eiffel and Java + Ada dispatching Robert I. Eachus
  2 siblings, 1 reply; 99+ results
From: Jean-Marc Jezequel @ 1996-11-06  0:00 UTC (permalink / raw)



In article <327F0D64.619A@iam.unibe.ch>, Robb Nebbe <nebbe@iam.unibe.ch> writes:
>On overloading:
>
>you need to keep in mind that a language is a tool. People become very frusterated
>with tools that interfere with doing work rather than help, unless they can
>rationalize this in terms of saftey or something. Overloading is the language
>getting out of your way so you can concentrate on what is really important.
>
>Think of it as separation of concerns. When you are writing software it is better
>to concentrate on finding meaningful names rather than "Did I already use that
>somewhere?" I have better things to do than manually resolving overloading.


Please let me use an example James Rogers sent me in a private mail:

type base_type is tagged record
   count : natural;
end record;

type derived_1 is new base_type with record
   Name : string(1..40);
end record;

type base_class_ptr is access all base_type'class;

Base_Obj : aliased base_type;
Derived_Obj : aliased derived_1;

Class_Ptr : base_class_ptr;

procedure print(Item : base_type);  -- (1)
procedure print(Item : derived_1);  -- (2)

-- Client side in Ada95

print(Base_Obj); -- static binding to (1)
print(base_type(Derived_Obj)); -- static binding to (1)
print(Derived_Obj);   -- static binding to (2)


-- Corresponding Client side in Eiffel (typical)

Base_Obj.print; --  binding to (1)
Derived_Obj.base_type_print; -- binding to (1)
Derived_Obj.print ;   --  binding to (2)


So usually finding a suitable name is not the problem when you lack overloading.
As for the preference on dotted or symetric syntax, someone already made the
point that it was no big deal.
And to be absolutely clear that this is not intented as an attack on Ada95, I claim
that I would be happy if I had to use Ada95 on a project (instead of say C++;-)

>You are correct in saying that there is no semantic difference between
>unique names and overloading. However, just because there is no semantic
>difference don't suppose that it doesn't play a critical role in how the language
>is defined. 

Yes, it does. For example by making things much more complicated;-)

>By the way, consider what Eiffel does. It determines which routine is to be called
>based on the name of the routine and the type of one of the parameters. The only
>difference with Ada is that Ada uses all the parameters. There is no semantic
>difference between determining statically or dynamically which method is invoked.

May be we have a different idea on the meaning of `semantics', but IMHO there is a 
difference. In one case it has to be done at compile time (and e.g. implemented using unique names as
you pointed out). In case of dynamic binding, it has (conceptualy) to be deferred until run-time,
and is basically implemented with a test on the object dynamic type (Ada tag?) to select
the right procedure.

In the head of the programmer, it makes a difference because she can assume that the most
"suitable" version of the procedure print will be called on x when she write x.print; 

Despite Ada95 being much more clear than C++ in this respect, in complex cases involving
both overloading and dynamic binding, it is still hardly possible to
explain in one short sentence (like above) the concept of what's going on.

My only point in this thread was that having both overloading (selecting the procedure at
compile time based on the static type of *all* the operands) and single distpatch (basically
selecting at runtime based on the dynamic type of one operand, plus minor Ada95 niceties) may
be confusing for some users. It's a matter of IMHO, so you won't need to agree with me.
BTW, I know it's not confusing for Ada95 experts (by definition;-)
But see the number of poeple who are still unsure whether Ada95 has multiple-dispatch a la CLOS,
or just an "augmented" single dispatch, e.g. the initiator of this thread.

Article Unavailable



^ permalink raw reply	[relevance 7%]

* To overload or not to overload (was Eiffel and Java + Ada dispatching)
  1996-11-05  0:00 10%           ` Robb Nebbe
  1996-11-06  0:00  7%             ` Jean-Marc Jezequel
@ 1996-11-06  0:00  7%             ` Don Harrison
  1996-11-06  0:00 11%               ` Robb Nebbe
  1996-11-08  0:00  8%             ` Eiffel and Java + Ada dispatching Robert I. Eachus
  2 siblings, 1 reply; 99+ results
From: Don Harrison @ 1996-11-06  0:00 UTC (permalink / raw)



Robb Nebbe writes:

:you need to keep in mind that a language is a tool. People become very frusterated
:with tools that interfere with doing work rather than help, unless they can
:rationalize this in terms of saftey or something. Overloading is the language
:getting out of your way so you can concentrate on what is really important.

This may be true in some cases (eg. for Ada) but there is also a downside. 
(See below).

:Think of it as separation of concerns. When you are writing software it is better
:to concentrate on finding meaningful names rather than "Did I already use that
:somewhere?" I have better things to do than manually resolving overloading.

IMO, operations that do the same thing should have the same name and there
should be only one operation per class that does a particular thing. In 
particular, overriding operations should retain the same name (unless a more
specific name is in order due to specialisation). Further, if two operations 
do similar but different things, they should still be given distinct names. 
My justification for this is that it is easier to understand an operation call 
if you can disregard the type of the non-dispatching parameters. Having to
consider their type just makes understanding more difficult.

Excluding overloading is reasonable for Eiffel but may not be for Ada. The 
reason I say this is that Eiffel is covariant and Ada avariant. As Jon pointed 
out, you may wish to use overloading to indicate that a 'covariant' operation 
does the same thing. Because in Eiffel such operations are truly covariant,
they are semantically related to their parent operations (by inheriatance)
and share the same name. So, Eiffel does not need overloading (for this 
purpose, at least).

Another related problem I see with overloading is that it is too liberal in
that it permits you to use a common name for completely unrelated operations.
Overloading can encourage you to be lazy by using an existing name instead 
of thinking of a more appropriate one. IMO, this freedom to name poorly
promotes obfuscation. 

:You are correct in saying that there is no semantic difference between
:unique names and overloading. 

Okay.

:However, just because there is no semantic
:difference don't suppose that it doesn't play a critical role in how the language
:is defined. 

Not sure what you mean here.

:By the way, consider what Eiffel does. It determines which routine is to be called
:based on the name of the routine and the type of one of the parameters. The only
:difference with Ada is that Ada uses all the parameters. 

Only in a special case, though.

:There is no semantic
:difference between determining statically or dynamically which method is invoked.
:When Eiffel compilers optimize away dispatching all they are really doing is
:static overload resolution. 

Yes, but this complexity is *hidden* form the user (as it ought to be).


Yes, a language is just a tool but a good tool will give you help where you
need it and this may mean curtailing your freedom where it will do you good.
An absence of overloading is a help rather than a hinderance, IMO.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 7%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-04  0:00  7%         ` Don Harrison
@ 1996-11-05  0:00 12%           ` Jon S Anthony
  0 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-05  0:00 UTC (permalink / raw)



In article <E0BKHr.3CC@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> I was able to infer from your note why Ada you cannot break
> polymorhism.  (Broken polymorphism is the problem in Eiffel - System
> Validity it's solution).  The reason is that Ada is avariant - when
> overriding dispatching operations, you cannot redefine
> non-dispatching parameters covariantly.

Right.  But part of the story for _how_ this is, is overloading.


> eg. Assuming type B descended from A and Q descended from P,
> 
> 1.  procedure op (a: A; p: P'Class);     -- dispatches on a
>     ...
> 2.  procedure op (b: B; p: P'Class);     -- dispatches on b (overriding op above)

Right.

>  But, as you point out below, a dispatching operation that has the
> same signature as another but a different non-dispatching parameter
> does not override the original, so cannot be called polymorphically
> wrt the original.

Right - it is an _overloading_ definition of the _specific_ types involved.


> 3.  procedure op (b: B; p: Q'Class); -- dispatches on b (distinct
>                                      -- operation from 1. above - does
>                                      -- not override it).

Right.


> What we can see from this is that overriding in Ada is implied (by
> the combination of descendant dispatching parameter, same
> non-dispatching parameter) rather than being explicit as in Eiffel
> (redefine clause).

Right (note that "parameter" for each sort may be plural).


> :The reason that OL enters into the puzzle is that it allows for the
> :definition of _new_ operations (on specific types) with descendent
> :controlling parameter(s) and a _non_ controlling descendent
> :parameter(s) but with the same name.  Now you can claim that this is
> :"confusing" (a value judgement), but that will most likely be because
> :you are not used to the differentiation between specific types and
> :class-wide types ...
> 
> Yes. I agree this may be confusing to some. I was one of them. :) 
> Personally, if writing Ada, I would prefer to use a different name rather 
> than overloading the old one to remove all confusion.

OK.  But then you lose some of the functionality.  Basically the OL
lets you have the "covariant" thingy, but forces you to supply the
exact definition for each possible such case.


> 4.  procedure new_op (b: B; p: Q'Class);   -- dispatches on b

Yes, but now this is not related to Op (in the sense I mention just
above).

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-04  0:00 10%     ` Don Harrison
@ 1996-11-05  0:00 11%       ` Jon S Anthony
  1996-11-05  0:00 10%         ` Don Harrison
  0 siblings, 1 reply; 99+ results
From: Jon S Anthony @ 1996-11-05  0:00 UTC (permalink / raw)



In article <E0BrFs.4st@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> It's plain that I simplified to help Vincent understand. It's better
> to present the usual case and then deal with exceptional cases later
> if, and when, necessary.  I dealt with the exceptional case when it
> Vincent showed that he was confused by the case of multiple
> dispatching parameters.

Check.


> It was also plain from my response that I *do* understand the semantics. 

Yes, I do agree from some of your other posts (especially the one about
"covariant" stuff) that you do understand the semantics.


> I don't know why you claim I was in error except perhaps to portray
> me as a fool. If so, I won't waste time discussing anything with
> you.

Nope.  Merely that in this particular note you only mentioned the
syntax aspects as being all there is.  This isn't (strictly speaking)
all there is and so was in error.  But, as you say you were just
avoiding the details.

While it is true that early in the "Real OO" thread I thought you were
a simple troller (for some very good reasons which we need not bring
up) I definitely changed my mind about this.  In fact, I have come to
see you as clearly contributing worth while stuff to the net.  One of
the few...

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 11%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-02  0:00 12%       ` Robert Dewar
  1996-11-04  0:00 13%         ` Norman H. Cohen
@ 1996-11-05  0:00 11%         ` Don Harrison
  1996-11-05  0:00 10%           ` Robb Nebbe
                             ` (5 more replies)
  1 sibling, 6 replies; 99+ results
From: Don Harrison @ 1996-11-05  0:00 UTC (permalink / raw)



Robert Dewar writes:

:Don Harrison says
:
:"Disagree. Overloading *is* syntactic sugar because it merely allows reuse
:of an identifier without any semantic difference (to using a different one).
:The reason Ada does not need checks on use of polymorphism is that
:it is avariant (no variance) compared with Eiffel which is covariant."
:
:... In particular, overloading plays quite
:an important role with respect to generic instantiation, and is much
:more than syntactic sugar in Ada.

You appear to be referring to RM 12.3(14) under Generic Instantiation, Static
Semantics which says

  "The interpretation of each construct within a generic declaration or body
   is determined using the overloading rules ...".

Maybe I don't understand what this means but it's not clear how this is any 
different from other uses of overloading (in which there is no semantic 
difference from using unique procedure names). If you can provide an example 
showing there is such a difference, I'll believe you.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 11%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 11%         ` Don Harrison
@ 1996-11-05  0:00 10%           ` Robb Nebbe
  1996-11-06  0:00  7%             ` Jean-Marc Jezequel
                               ` (2 more replies)
  1996-11-05  0:00  9%           ` Joachim Durchholz
                             ` (4 subsequent siblings)
  5 siblings, 3 replies; 99+ results
From: Robb Nebbe @ 1996-11-05  0:00 UTC (permalink / raw)



On overloading:

you need to keep in mind that a language is a tool. People become very frusterated
with tools that interfere with doing work rather than help, unless they can
rationalize this in terms of saftey or something. Overloading is the language
getting out of your way so you can concentrate on what is really important.

Think of it as separation of concerns. When you are writing software it is better
to concentrate on finding meaningful names rather than "Did I already use that
somewhere?" I have better things to do than manually resolving overloading.

You are correct in saying that there is no semantic difference between
unique names and overloading. However, just because there is no semantic
difference don't suppose that it doesn't play a critical role in how the language
is defined. 

By the way, consider what Eiffel does. It determines which routine is to be called
based on the name of the routine and the type of one of the parameters. The only
difference with Ada is that Ada uses all the parameters. There is no semantic
difference between determining statically or dynamically which method is invoked.
When Eiffel compilers optimize away dispatching all they are really doing is
static overload resolution. 

Don Harrison wrote:
> 
> Robert Dewar writes:
> 
> :... In particular, overloading plays quite
> :an important role with respect to generic instantiation, and is much
> :more than syntactic sugar in Ada.
> 
> You appear to be referring to RM 12.3(14) under Generic Instantiation, Static
> Semantics which says
> 
>   "The interpretation of each construct within a generic declaration or body
>    is determined using the overloading rules ...".
> 
> Maybe I don't understand what this means but it's not clear how this is any
> different from other uses of overloading (in which there is no semantic
> difference from using unique procedure names). If you can provide an example
> showing there is such a difference, I'll believe you.




^ permalink raw reply	[relevance 10%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 11%       ` Jon S Anthony
@ 1996-11-05  0:00 10%         ` Don Harrison
  1996-11-06  0:00 13%           ` Jon S Anthony
  0 siblings, 1 reply; 99+ results
From: Don Harrison @ 1996-11-05  0:00 UTC (permalink / raw)



Jon S Anthony wrote (privately):

:News is clearly running behind and the note of my you were replying to
:below was before I saw a few of your other posts which clearly show
:you understand this stuff afterall.  Mea Culpa.  Guilty twit.  Grade A
:stupid.  Whatever else you want to call me. ;-)

Grovelling apology accepted but I would have more respect for you if it
were as public as your allegation.

and publicly:

:While it is true that early in the "Real OO" thread I thought you were
:a simple troller (for some very good reasons which we need not bring
:up) I definitely changed my mind about this.  In fact, I have come to
:see you as clearly contributing worth while stuff to the net.  One of
:the few...

Well, the stuff that's not founded in ignorance, at least. :( 

BTW, I'm done with throwing rocks at other people's languages. It's not helpful
to criticise other people's efforts. In the case of Ada, I have a better
appreciation of why it was designed the way it was and think the Ada95 designers
were faced with a difficult task in having as their starting point an existing 
language which supported a different paridigm. If Ada were designed from scratch
today, it would look quite different, IMO.



Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 10%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-05  0:00 11%         ` Don Harrison
  1996-11-05  0:00 10%           ` Robb Nebbe
@ 1996-11-05  0:00  9%           ` Joachim Durchholz
  1996-11-06  0:00  8%           ` Robert I. Eachus
                             ` (3 subsequent siblings)
  5 siblings, 0 replies; 99+ results
From: Joachim Durchholz @ 1996-11-05  0:00 UTC (permalink / raw)



nebbe@iam.unibe.ch wrote 05.11.96:

> By the way, consider what Eiffel does. It determines which routine is to be
> called based on the name of the routine and the type of one of the
> parameters. The only difference with Ada is that Ada uses all the
> parameters.

I don't think so. Overloading in Ada determines which routine to call _at_  
_compile_ _time_. This is very different from Eiffel, which uses the type  
of one of the parameters to determine which routine to call, _at_ _run_  
_time_ (this is called dynamic binding).

> There is no semantic difference between determining statically
> or dynamically which method is invoked. When Eiffel compilers optimize away
> dispatching all they are really doing is static overload resolution.

In a sense, you are right. In the absence of polymorphism, dynamic binding  
degenerates to overloading. (No downplay on overloading intended - I found  
it quite useful, though it also makes a great pistol if you don't control  
the semantics very carefully. Dynamic binding is an even better pistol,  
but luckily the programming-by-contract rules provide an effective safety  
catch.)

However, the central difference is that dynamic binding is always there in  
Eiffel. You don't have to rewrite Eiffel code to make overloading work,  
you just don't use polymorphism. You'd have to rewrite Ada code to go from  
overloading to dynamic binding.

The situation is a bit similar to multiplication optimization. Compilers  
can optimize multiplications with a power of two by issuing left-shift  
instructions instead of multiplications. But programming languages don't  
require the programmer to write all multiplications in terms of left-shift  
operators (even C compilers don't enforce this ;) ), and programmers  
usually don't think about the difference.
Overloading on the first routine parameter is a similar case for an Eiffel  
programmer; there is no reason why he should consider this special case as  
anything peculiar.

Regards,
-Joachim

--
Looking for a new job. Resume available on request. WWW version of resume
available under http://www.franken.de/users/herold/jhd/resume/index.html




^ permalink raw reply	[relevance 9%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-02  0:00 12%       ` Robert Dewar
@ 1996-11-04  0:00 13%         ` Norman H. Cohen
  1996-11-05  0:00 11%         ` Don Harrison
  1 sibling, 0 replies; 99+ results
From: Norman H. Cohen @ 1996-11-04  0:00 UTC (permalink / raw)



Robert Dewar wrote:

> You only disagree because you don't really know the details of what you
> are talking about. You really need to know Ada 95 better before making
> incorrect statements like this. 

I disagree.  Understanding Ada has never been a prerequisite for making
incorrect statements about it.  ;-)

-- 
Norman H. Cohen
mailto:ncohen@watson.ibm.com
http://www.research.ibm.com/people/n/ncohen




^ permalink raw reply	[relevance 13%]

* Re: Eiffel and Java + Ada dispatching
  1996-10-30  0:00 11%   ` Jon S Anthony
@ 1996-11-04  0:00 10%     ` Don Harrison
  1996-11-05  0:00 11%       ` Jon S Anthony
  0 siblings, 1 reply; 99+ results
From: Don Harrison @ 1996-11-04  0:00 UTC (permalink / raw)



Jon S Anthony writes:

:Well, the problem is that Don is not an "ada specialist" and is in
:error about there not being any semantics to this (or maybe just
:simplifying to avoid the details).  

It's plain that I simplified to help Vincent understand. It's better to present
the usual case and then deal with exceptional cases later if, and when, necessary.
I dealt with the exceptional case when it Vincent showed that he was confused by
the case of multiple dispatching parameters. 

It was also plain from my response that I *do* understand the semantics. 

I don't know why you claim I was in error except perhaps to portray me as a 
fool. If so, I won't waste time discussing anything with you.

:Don's statement at face value is in error, but not on the salient part
:of multiple-dispatch.

I've already explained this is not true.

BTW, the "Real OO" thread was in the early months of this year (February-ish 
to May-ish 1996) - Northern hemisphere Spring, Southern hemishpere Autumn. 
Call Autumn 'Fall' if you wish. (People living near the Equator will know what 
you mean even though they have evergreen rather than deciduous trees).


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 10%]

* Re: Eiffel and Java + Ada dispatching
  1996-11-01  0:00 11%       ` Jon S Anthony
@ 1996-11-04  0:00  7%         ` Don Harrison
  1996-11-05  0:00 12%           ` Jon S Anthony
  0 siblings, 1 reply; 99+ results
From: Don Harrison @ 1996-11-04  0:00 UTC (permalink / raw)



Jon S Anthony writes:

:In article <E06F2B.Az7@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:
:
:> Jon S Anthony writes:
:> 
:> :> 2) but this is combined with the static overloading inherited from
:> :> Ada83; which is merely syntactic sugar for routine having
:> :> (statically) different signatures.
:> :
:> :Criminey!  This is wrong too.  It is not "merely syntactic sugar", as it
:> :is part and parcel of why Ada does not need any system validity checks!
:> 
:> Disagree. Overloading *is* syntactic sugar because it merely allows reuse
:> of an identifier without any semantic difference (to using a different one). 
:> The reason Ada does not need checks on use of polymorphism is that 
:> it is avariant (no variance) compared with Eiffel which is covariant.
:
:Go back and re-read that long note I wrote in the "Real OO" thread on
:why Ada does not have system validity problems and then the follow up
:which tried to point out your misunderstandings and you will see why
:you are wrong about this.

I was able to infer from your note why Ada you cannot break polymorhism.
(Broken polymorphism is the problem in Eiffel - System Validity it's solution).
The reason is that Ada is avariant - when overriding dispatching operations,
you cannot redefine non-dispatching parameters covariantly.

eg. Assuming type B descended from A and Q descended from P,

1.  procedure op (a: A; p: P'Class);     -- dispatches on a
    ...
2.  procedure op (b: B; p: P'Class);     -- dispatches on b (overriding op above)

But, as you point out below, a dispatching operation that has the same 
signature as another but a different non-dispatching parameter does not 
override the original, so cannot be called polymorphically wrt the original.

3.  procedure op (b: B; p: Q'Class);     -- dispatches on b (distinct operation from
                                         -- 1. above - does not override it).

What we can see from this is that overriding in Ada is implied (by the 
combination of descendant dispatching parameter, same non-dispatching parameter) 
rather than being explicit as in Eiffel (redefine clause).

:The reason that OL enters into the puzzle is that it allows for the
:definition of _new_ operations (on specific types) with descendent
:controlling parameter(s) and a _non_ controlling descendent
:parameter(s) but with the same name.  Now you can claim that this is
:"confusing" (a value judgement), but that will most likely be because
:you are not used to the differentiation between specific types and
:class-wide types ...

Yes. I agree this may be confusing to some. I was one of them. :) 
Personally, if writing Ada, I would prefer to use a different name rather 
than overloading the old one to remove all confusion.

4.  procedure new_op (b: B; p: Q'Class);   -- dispatches on b



Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 7%]

* Re: Eiffel and Java + Ada dispatching
    @ 1996-11-03  0:00 12% ` Joachim Durchholz
  1 sibling, 0 replies; 99+ results
From: Joachim Durchholz @ 1996-11-03  0:00 UTC (permalink / raw)



jsa@alexandria wrote 02.11.96:

> > *However*, there is a proposal floating around that allows static type
> > checking without having to resort to system-wide checks, and this is
> > commonly regarded as an advance over system validity and run-time checks.
>
> I've heard about this - is there a pointer to the details?  On the Eiffel
> home page?

Yes. Go to www.eiffel.com and follow the Technology Papers (or something  
like that) link.
BTW the proposal doesn't solve *all* problems. The real problem is with  
covariant parameter redefinitions, which are necessary to do certain neat  
stuff (like parallel type hierarchies as in TREE-BINARY_TREE and NODE- 
BINARY_NODE) and cause all sorts of trouble and type holes. I'm not aware  
of a good, elegant solution, however.

Regards,
-Joachim

--
Looking for a new job. Resume available on request. WWW version of resume
available under http://www.franken.de/users/herold/jhd/resume/index.html




^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
                       ` (5 preceding siblings ...)
  1996-11-02  0:00  9%   ` Jon S Anthony
@ 1996-11-02  0:00 13%   ` Jon S Anthony
  6 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-02  0:00 UTC (permalink / raw)



In article <6Jw2qfNk3RB@herold.franken.de> jhd@herold.franken.de (Joachim Durchholz) writes:

> jsa@alexandria wrote 31.10.96:
> 
> > I guess you like system validity problems.

I wish I hadn't said this - it was too flip.


> *However*, there is a proposal floating around that allows static type  
> checking without having to resort to system-wide checks, and this is  
> commonly regarded as an advance over system validity and run-time checks.

I've heard about this - is there a pointer to the details?  On the Eiffel
home page?

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 13%]

* Re: Eiffel and Java + Ada dispatching
       [not found]         ` <E06F2B.Az7@syd.csa.com.au>
  1996-11-01  0:00 11%       ` Jon S Anthony
@ 1996-11-02  0:00 12%       ` Robert Dewar
  1996-11-04  0:00 13%         ` Norman H. Cohen
  1996-11-05  0:00 11%         ` Don Harrison
  1 sibling, 2 replies; 99+ results
From: Robert Dewar @ 1996-11-02  0:00 UTC (permalink / raw)



Don Harrison says

"Disagree. Overloading *is* syntactic sugar because it merely allows reuse
of an identifier without any semantic difference (to using a different one).
The reason Ada does not need checks on use of polymorphism is that
it is avariant (no variance) compared with Eiffel which is covariant."

You only disagree because you don't really know the details of what you
are talking about. You really need to know Ada 95 better before making
incorrect statements like this. In particular, overloading plays quite
an important role with respect to generic instantiation, and is much
more than syntactic sugar in Ada.





^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
                       ` (4 preceding siblings ...)
  1996-10-31  0:00 11%   ` Joachim Durchholz
@ 1996-11-02  0:00  9%   ` Jon S Anthony
  1996-11-02  0:00 13%   ` Jon S Anthony
  6 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-02  0:00 UTC (permalink / raw)



In article <55c9e4$59m@tjnews.is.s.u-tokyo.ac.jp> jezequel@piccolo.is.s.u-tokyo.ac.jp (Jean-Marc Jezequel) writes:

> >> 2) but this is combined with the static overloading inherited from
> >> Ada83; which is merely syntactic sugar for routine having
> >> (statically) different signatures.
> >
> >Criminey!  This is wrong too.  It is not "merely syntactic sugar", as it
> >is part and parcel of why Ada does not need any system validity checks!
> 
> I do not claim to be any expert in Ada95: actually I practiced Ada83 only.
> So I might be wrong. In that case I would admit it without problem.
> But you cannot simply say: you are wrong and stay at this level of generality

Right - I wrote another note stating a bit about this.  The full knock down
drag out is in a thread called "Real OO" posted to c.l.a,c.l.e,comp.object
back in fall '95.


> What has "static overloading" to do with "system validity checks" ?
> If it is not syntactic sugar, please tell us what it is. Or if
> you're lazy, give a pointer to a relevant section of the reference
> manual, or to another easily accessible litterature.

Yes, I am getting lazy on this stuff - the pointer is above.  In fact,
I really should just stop wasting time on this...


> >> In this respect, it is exactly like C++ or Java, but for the
> >> symetric syntax.
> >
> >This isn't correct either.  There are some other semantic aspects
> >floating around that make it different from C++/Java in this area.
> 
> I didn't say (god forbid!) that Ada95 was anywhere the same as C++/Java!
> I was limiting the scope of my comment to the ability
> of having both *overloading* and *single dispatch*. 

So was I.  The "overloading" bit is different from J/C++ for a few
reasons which I pointed out in another note (and which depend in part
on the distinction between specific and class wide types, which are
analogous to Sather concrete and abstract classes).


> Do you find it funny to cut one's statements at strategic points to distort
> their meaning, or what? Sorry, but I still believe in good faith discussions.

No - and I didn't do this.  The important bit is "In this respect" -
which refers to the business of overloading - not languages in
general.  And to say that "in this respect" it (Ada) is _exactly_ like
the other two (C++/J) is not correct.


> And this has not to degenerate in a language war: Ada and Eiffel
> deserve better than that.

Right.  Besides, that's been done to death and its boring.


> My only point in this post was that mixing *overloading* (a static
> mechanism AFAIK) with *single dispatch* dynamic binding, using the
> same syntax for the call, was making things a bit confusing for the
> user of the language. Since this is a subjective point, I have no
> problem with you not agreeing with me. But I expect real arguments
> on your side to be able to explain it myself to others.

Sounds right.  As I point out in another note, this "confusing"
assesement stems in large part from not being familiar with the
distinction between specific and class-wide types.  It is worth noting
that in C++/J this distinction is not made and the confusion really
does have a more "objective" basis.


> But I do not claim Eiffel is perfect (can you claim Ada95 is?).

Are you kidding? :-) I have flamed Ada on a number of points.  What I
don't like is seeing someone make assertions which do not reflect
various facts.  I'm sure I've made these sort of assertions too as
people have "shown me the error of my ways".  I'm not going to go
around making assertions about Eiffel here without first making pretty
damn sure I understand the relevant bits in ETL and related
information.


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 9%]

* Re: Eiffel and Java  + Ada dispatching
    @ 1996-11-02  0:00  6% ` Jon S Anthony
  1 sibling, 0 replies; 99+ results
From: Jon S Anthony @ 1996-11-02  0:00 UTC (permalink / raw)



In article <55cl9q$59m@tjnews.is.s.u-tokyo.ac.jp> jezequel@piccolo.is.s.u-tokyo.ac.jp (Jean-Marc Jezequel) writes:

> >1) the dot notation makes the operation _look_ like a field of the object but
> >   in general this is _not_ true (some OOLs do have per object methods but
> >   not the usual ones like Eiffel, C++, Sather, etc...)

> What do you mean? Conceptually it *is* (can be though of as) a
> field of the object (if I gather well what you mean by field). That
> it uses to not be at runtime is a compiler optimization. Or do you
> mean something else?

In languages like Eiffel, Sather, C++, etc. it is not a compiler
optimization.  That the operation is not part of the object is part of
the semantics of the language.  You cannot change this operation on a
per object basis.  Now, you can say that Joe Programmer can think this
way (that the operation is part of the object), but that just means he
doesn't understand the language.


> >2) the dot is asymmetrical and makes many cummutative operations look
> >   lopsided.  For example, Union(set_a, set_b) = Union(set_b, set_a), and
> >   the notation should reflect this (infix would be even nicer here).  But
> >   in "dot land" you have set_a.Union(set_b) which looks like set_a _has_
> >   the operation and is "special" somehow.
> 
>
> The problem is much more profound, because if you have single
> dispatch only, it *is* "special" somehow, whatever the syntax you
> use to write it.

No it is not.  The object does not contain the operation.  The
language semantics do not allow this interpretation.  You can pretend
that it does, but it doesn't.  You are not actually sending a message
to set_a.  Now, if we were talking about a _delegation_ based
language, then you would definitely have a point.

There is nothing special about set_a from set_b.  They are both of the
same class.  Both have the exact same operation Union.  Hmmm, unless
you are thinking of the case where set_b and set_a are _not_ in the
same class.  While this can happen in Eiffel, it can't happen in Ada,
so maybe this is where the problem is.


> For binary operations, it seems that there is no other way that
> double-dispatch (built in as in CLOS, or emulated as everywhere
> else).  Check e.g. the recent article "On Binary Methods" by Bruce,
> Cardelli et al. in Theory and Practice of Object System. Static

Are you saying that only multi-dispatch semantics allow "proper"
binary operations?  If so, why???  Also, note that in CLOS with the
two operands of the same type, the effective method will simply be
what Ada does anyway - select their single operation and perform it.
It's just that in CLOS you aren't restricted to _only_ this outcome.


> binding of one of the paramater poses problem, and in this respect
> Ada95 does not bring anything new (and in this respect is no better
> than C++/Java/Eiffel/Sather etc.).

I'm not sure I understand you here.  Ada does not statically bind one
parameter and not the other.  That is illegal.  Either all the
controlling parameters are dynamic or they are all static.  In either
case they have to be of the same type.


> Prove me wrong, please, and win a paper in TPOS.  But please, do not
> quote me outside of the context this time.

I'm not sure what the question or assertion even _is_, much less
whether you are wrong or not.


> of Current and Other ...  but unless you redispatch on the dynamic
> type of 'other', it does not solve the problem.

What problem?


> >3) the function notation allows Ada to dispatch based on the _result_ of
> >   parameter which is a function call.  Or has the function dispatch to
> >   the right thing based on the other parameters.  Bob Duff gave a couple
> 
> I have trouble understanding these sentences. Could you please reformulate
> in English or even American English?

Yes, on reading them, the sentences have some typos.  Oh well.


> >   Union(My_Set, Singleton(X)), where Singleton's dispatching is the
> >   controlling _result_ and _not_ the argument (with X being an integer
> >   or something).  Here, Singleton would dispatch to the proper version
> >   based on the tag of My_Set.
> >
> >   (Singleton(X) + Singleton(Y)) * My_Set, where "+" is union and "*" is
> >   intersection.  Here the tag of My_Set would control the dispatch of
> >   the Singleton operations.
> 
> Well, I still cannot see what it buys you beyond being able to
> choose at *compile time* (i.e. statically) the position of the
> parameter that receives the dispatch

It is a kind of (very) simple multi-dispatch.  Sort of.  The function
call will dispatch to the proper operation _based on_ the dynamic tags
of the other parameters and then the "outer" operation (the one with
the function as one of its parameters) will dispatch.

It is indeed, very constrained and not something to get wildly excited
about, but it is neat and useful.


> (big deal, IMHO) ? Or do you mean something else?  In that case,
> please give us a more complete example. Or would a real Ada95 expert
> tell us? (Yvon, are you still there?)

My my, we are getting nasty now, aren't we?  The examples I gave above
(as I indicated) came from Bob Duff - co-designer of Ada95.  I'm not
sure why you don't understand the examples - they are pretty straight
forward.


> >Well, sort of...  Seems like pretty extraneous futzing to accomplish
> >such a simple and ordinary thing.
> 
> Dealing with binary methods whose both arguments can be instances
> of subtypes of the declared types is *not* a "simple and ordinary
> thing". Again, if you have such a simple solution, tell us! I'll
> praise you then.

Well, now we see the problem.  As has been stated several times, the
subtypes must be _the same_ and are checked dynamically (in a
dispatching case) and statically (in a compile time case) for this.
You are thinking (as in Eiffel) of _dispatching_ operations which can
take _variants_ of the types.  In Ada, only operations of class-wide
types can take such variants at runtime and they are not dispatching -
completely statically bound at compile time.  They can just take any
instance of any type covered by their class-wide parameters.

Here's a case of someone who only sees one way of looking at things,
doesn't understand the other model, and then says it can't be done
because he is thinking solely in terms of the model where it is "*not*
a simple and ordinary thing".  Shrug.


> >Actually, if you stated this as "for my areas, symmetric ops are
> >relatively few", I could buy it.  But in general symmetric operations
> >are all over the place.
> 
> How can you say that?

Easy.

> I agree that they are quite commonplace in
> math-related software (linear algebra, sets etc.), and could
> sometimes appear in other pieces,

Exactly.

> but not to the point of being ubiquitous.

No one said they were.

> But that's not the point. Well, what is your point anyway?

Just that - depends on the area.  What's your point?  I mean, you sort
of got my point.


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 6%]

* Re: Eiffel and Java + Ada dispatching
  1996-10-30  0:00  9%     ` Jean-Marc Jezequel
@ 1996-11-01  0:00 13%       ` Joachim Durchholz
  1996-11-01  0:00 10%       ` Don Harrison
  1 sibling, 0 replies; 99+ results
From: Joachim Durchholz @ 1996-11-01  0:00 UTC (permalink / raw)



donh@syd.csa.com.au wrote 01.11.96:

> Good point. Is this the (only) reason Eiffel does not have overloading?
> I remember thinking once that it would also complicate multiple inheritance
> but don't recall why I thought that.

Maybe because the 'rename' clause would not only have to list the original  
name, but the original signature as well?

Regards,
-Joachim

--
Looking for a new job. Resume available on request. WWW version of resume
available under http://www.franken.de/users/herold/jhd/resume/index.html




^ permalink raw reply	[relevance 13%]

* Re: Eiffel and Java + Ada dispatching
       [not found]         ` <E06F2B.Az7@syd.csa.com.au>
@ 1996-11-01  0:00 11%       ` Jon S Anthony
  1996-11-04  0:00  7%         ` Don Harrison
  1996-11-02  0:00 12%       ` Robert Dewar
  1 sibling, 1 reply; 99+ results
From: Jon S Anthony @ 1996-11-01  0:00 UTC (permalink / raw)



In article <E06F2B.Az7@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Jon S Anthony writes:
> 
> :> 2) but this is combined with the static overloading inherited from
> :> Ada83; which is merely syntactic sugar for routine having
> :> (statically) different signatures.
> :
> :Criminey!  This is wrong too.  It is not "merely syntactic sugar", as it
> :is part and parcel of why Ada does not need any system validity checks!
> 
> Disagree. Overloading *is* syntactic sugar because it merely allows reuse
> of an identifier without any semantic difference (to using a different one). 
> The reason Ada does not need checks on use of polymorphism is that 
> it is avariant (no variance) compared with Eiffel which is covariant.

Go back and re-read that long note I wrote in the "Real OO" thread on
why Ada does not have system validity problems and then the follow up
which tried to point out your misunderstandings and you will see why
you are wrong about this.  Well, I hope so - maybe you still don't get
get it.

The reason that OL enters into the puzzle is that it allows for the
definition of _new_ operations (on specific types) with descendent
controlling parameter(s) and a _non_ controlling descendent
parameter(s) but with the same name.  Now you can claim that this is
"confusing" (a value judgement), but that will most likely be because
you are not used to the differentiation between specific types and
class-wide types (which we went over in excrutiating detail...)

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 11%]

* Re: Eiffel and Java + Ada dispatching
  1996-10-30  0:00  9%     ` Jean-Marc Jezequel
  1996-11-01  0:00 13%       ` Joachim Durchholz
@ 1996-11-01  0:00 10%       ` Don Harrison
  1 sibling, 0 replies; 99+ results
From: Don Harrison @ 1996-11-01  0:00 UTC (permalink / raw)



Jean-Marc Jezequel writes:

:The only thing you really need to make use of OO polymorphism is dynamic binding.
:While having at the same time static overloading can make some code fragment more "natural" to
:write, the apparent proximity of this feature with dynamic binding yield so much confusion on
:the non-expert eyes ...

Good point. Is this the (only) reason Eiffel does not have overloading?
I remember thinking once that it would also complicate multiple inheritance but
don't recall why I thought that.

:As an aside, I once wrote a paper on how to emulate multiple dispatch in a parallel 
:linear algebra library in Eiffel, and it was refused on the ground that a well known 
:existing library had already solved the problem using C++ overloading. Even this
:"expert" C++ referee had no clue on the difference between static and dynamic binding :-(

Well, if it's been done in C++, then what more can you have to offer? :)

This reminds me of the Australian mathematician, Andrew? Prentice, who has 
trouble getting his papers on the origin of the Solar System published because 
he rejects the 'accepted wisdom' of established academia. The fact that many 
(all?) of his predictions about the outer planets have been confirmed by space 
probes doesn't seem significant to the assessors. He has found some friends in
applied astronomy (at the Jet Propulsion Laboratory), but theoreticians have 
largely snubbed him.



Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 10%]

* Re: Eiffel and Java + Ada dispatching
  1996-10-31  0:00 12%   ` Jon S Anthony
@ 1996-11-01  0:00  8%     ` Jean-Marc Jezequel
       [not found]         ` <E06F2B.Az7@syd.csa.com.au>
  1 sibling, 0 replies; 99+ results
From: Jean-Marc Jezequel @ 1996-11-01  0:00 UTC (permalink / raw)



In article <JSA.96Oct30213354@alexandria>, jsa@alexandria (Jon S Anthony) writes:
>In article <557ce3$ojh@tjnews.is.s.u-tokyo.ac.jp> jezequel@piccolo.is.s.u-tokyo.ac.jp (Jean-Marc Jezequel) writes:
>
>> 2) but this is combined with the static overloading inherited from
>> Ada83; which is merely syntactic sugar for routine having
>> (statically) different signatures.
>
>Criminey!  This is wrong too.  It is not "merely syntactic sugar", as it
>is part and parcel of why Ada does not need any system validity checks!

I do not claim to be any expert in Ada95: actually I practiced Ada83 only.
So I might be wrong. In that case I would admit it without problem.
But you cannot simply say: you are wrong and stay at this level of generality.
What has "static overloading" to do with "system validity checks" ?
If it is not syntactic sugar, please tell us what it is. Or if you're lazy,
give a pointer to a relevant section of the reference manual, or to another easily
accessible litterature.

>> In this respect, it is exactly like C++ or Java, but for the
>> symetric syntax.
>
>This isn't correct either.  There are some other semantic aspects
>floating around that make it different from C++/Java in this area.

I didn't say (god forbid!) that Ada95 was anywhere the same as C++/Java!
I was limiting the scope of my comment to the ability
of having both *overloading* and *single dispatch*. 
Do you find it funny to cut one's statements at strategic points to distort
their meaning, or what? Sorry, but I still believe in good faith discussions.
And this has not to degenerate in a language war: Ada and Eiffel deserve better than that.

My only point in this post was that mixing *overloading* (a static mechanism AFAIK)
with *single dispatch* dynamic binding, using the same syntax for the call, was
making things a bit confusing for the user of the language. Since this is a
subjective point, I have no problem with you not agreeing with me. But I expect
real arguments on your side to be able to explain it myself to others.

The rest of your post is thus a bit off-topic:

>> The only thing you really need to make use of OO polymorphism is
>> dynamic binding.  While having at the same time static overloading
>> can make some code fragment more "natural" to write, the apparent
>> proximity of this feature with dynamic binding yield so much
>> confusion on the non-expert eyes that you do not wonder why I prefer
>> to teach Eiffel rather than C++, Java or even Ada95.
>
>I guess you like system validity problems.

System validity is not a problem in Eiffel from the theoritical point of view (at least
when only close systems are considered). Anyway, what is *your* problem with
system validity checks? Have you written real, usefull Eiffel code that bite you lately?
I'd be curious to know...

But I do not claim Eiffel is perfect (can you claim Ada95 is?).
And yes, system validity is one of the weak points.

---
Jean-Marc Jezequel               | Tel : +81 (3) 3812-2111 ext. 4116
IRISA/CNRS, currently visiting:  | Fax : +81 (3) 5689-4365
Dept. of Information Science     | e-mail : jezequel@irisa.fr  or
Faculty of Science               | e-mail : jezequel@is.s.u-tokyo.ac.jp
The University of Tokyo          | http://www.irisa.fr/pampa/PROF/jmj.html   
Hongo Bunkyo-Ku, Tokyo 113, JAPAN






^ permalink raw reply	[relevance 8%]

* Re: Eiffel and Java  + Ada dispatching
  @ 1996-11-01  0:00  7%   ` Jean-Marc Jezequel
  0 siblings, 0 replies; 99+ results
From: Jean-Marc Jezequel @ 1996-11-01  0:00 UTC (permalink / raw)



In article <JSA.96Oct30181901@alexandria>, jsa@alexandria (Jon S Anthony) writes:

>Actually, while it is not multiple dispatching (multi-methods), the
>syntax does indeed allow several little niceties that the dot notation
>flubs.  It is this stuff that is the "justification" - not any so called
>"hybrid" aspects.
>
>
>1) the dot notation makes the operation _look_ like a field of the object but
>   in general this is _not_ true (some OOLs do have per object methods but
>   not the usual ones like Eiffel, C++, Sather, etc...)

What do you mean? Conceptually it *is* (can be though of as) a field of the object
(if I gather well what you mean by field). That it uses to not be at runtime is a 
compiler optimization. Or do you mean something else?


>2) the dot is asymmetrical and makes many cummutative operations look
>   lopsided.  For example, Union(set_a, set_b) = Union(set_b, set_a), and
>   the notation should reflect this (infix would be even nicer here).  But
>   in "dot land" you have set_a.Union(set_b) which looks like set_a _has_
>   the operation and is "special" somehow.

The problem is much more profound, because if you have single dispatch only, it *is*
"special" somehow, whatever the syntax you use to write it.
For binary operations, it seems that there is no other way
that double-dispatch (built in as in CLOS, or emulated as everywhere else).
Check e.g. the recent article "On Binary Methods" by Bruce, Cardelli et al. in 
Theory and Practice of Object System. Static binding of one of the paramater poses
problem, and in this respect Ada95 does not bring anything new (and in this respect is no
better than C++/Java/Eiffel/Sather etc.). Prove me wrong, please, and win a paper in TPOS.
But please, do not quote me outside of the context this time.

BTW you could write: set_c := set_a + set_b in Eiffel, with the declaration
infix "+" (other: SET): SET is
-- returns union of Current and Other
...

but unless you redispatch on the dynamic type of 'other', it does not solve
the problem.

>3) the function notation allows Ada to dispatch based on the _result_ of
>   parameter which is a function call.  Or has the function dispatch to
>   the right thing based on the other parameters.  Bob Duff gave a couple

I have trouble understanding these sentences. Could you please reformulate
in English or even American English?

>   Union(My_Set, Singleton(X)), where Singleton's dispatching is the
>   controlling _result_ and _not_ the argument (with X being an integer
>   or something).  Here, Singleton would dispatch to the proper version
>   based on the tag of My_Set.
>
>   (Singleton(X) + Singleton(Y)) * My_Set, where "+" is union and "*" is
>   intersection.  Here the tag of My_Set would control the dispatch of
>   the Singleton operations.

Well, I still cannot see what it buys you beyond being able to choose 
at *compile time* (i.e. statically) the position of the parameter that receives
the dispatch (big deal, IMHO) ? Or do you mean something else?
In that case, please give us a more complete example. Or would a real
Ada95 expert tell us? (Yvon, are you still there?)


>> it is special. The downside is that symmetric operations do not
>> appear as such. Well, not really, because you can always regain it
>> by inventing another class for performing symmetric operations:

>> eg. class SET_OPS
>>       ...
>>       union (a, b: SET): SET is ...
>>       intersection (a, b: SET): SET is ...
>>       ...
>>     end

>Well, sort of...  Seems like pretty extraneous futzing to accomplish
>such a simple and ordinary thing.


Dealing with binary methods whose both arguments can be instances of subtypes of the declared
types is *not* a "simple and ordinary thing". Again, if you have such a simple solution,
tell us! I'll praise you then.

>Actually, if you stated this as "for my areas, symmetric ops are
>relatively few", I could buy it.  But in general symmetric operations
>are all over the place.

How can you say that? I agree that they are quite commonplace in math-related software
(linear algebra, sets etc.), and could sometimes appear in other pieces, but not to the
point of being ubiquitous. But that's not the point. Well, what is your point anyway?

---
Jean-Marc Jezequel               | Tel : +81 (3) 3812-2111 ext. 4116
IRISA/CNRS, currently visiting:  | Fax : +81 (3) 5689-4365
Dept. of Information Science     | e-mail : jezequel@irisa.fr  or
Faculty of Science               | e-mail : jezequel@is.s.u-tokyo.ac.jp
The University of Tokyo          | http://www.irisa.fr/pampa/PROF/jmj.html   
Hongo Bunkyo-Ku, Tokyo 113, JAPAN





^ permalink raw reply	[relevance 7%]

* Re: Eiffel and Java + Ada dispatching
                       ` (2 preceding siblings ...)
  1996-10-30  0:00 11%   ` Jon S Anthony
@ 1996-10-31  0:00 12%   ` Jon S Anthony
  1996-11-01  0:00  8%     ` Jean-Marc Jezequel
       [not found]         ` <E06F2B.Az7@syd.csa.com.au>
  1996-10-31  0:00 11%   ` Joachim Durchholz
                     ` (2 subsequent siblings)
  6 siblings, 2 replies; 99+ results
From: Jon S Anthony @ 1996-10-31  0:00 UTC (permalink / raw)



In article <557ce3$ojh@tjnews.is.s.u-tokyo.ac.jp> jezequel@piccolo.is.s.u-tokyo.ac.jp (Jean-Marc Jezequel) writes:

> 2) but this is combined with the static overloading inherited from
> Ada83; which is merely syntactic sugar for routine having
> (statically) different signatures.

Criminey!  This is wrong too.  It is not "merely syntactic sugar", as it
is part and parcel of why Ada does not need any system validity checks!


> In this respect, it is exactly like C++ or Java, but for the
> symetric syntax.

This isn't correct either.  There are some other semantic aspects
floating around that make it different from C++/Java in this area.


> May be the confusion comes form the fact that in CLOS, this symetric
> syntax is used for the real thing: multiple dispatch.

Well, you got this right at any rate...


> The only thing you really need to make use of OO polymorphism is
> dynamic binding.  While having at the same time static overloading
> can make some code fragment more "natural" to write, the apparent
> proximity of this feature with dynamic binding yield so much
> confusion on the non-expert eyes that you do not wonder why I prefer
> to teach Eiffel rather than C++, Java or even Ada95.

I guess you like system validity problems.


> As an aside, I once wrote a paper on how to emulate multiple
> dispatch in a parallel linear algebra library in Eiffel, and it was
> refused on the ground that a well known existing library had already
> solved the problem using C++ overloading. Even this "expert" C++
> referee had no clue on the difference between static and dynamic
> binding :-(

I am having a bit of the same suspicion here...

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 12%]

* Re: Eiffel and Java + Ada dispatching
                       ` (3 preceding siblings ...)
  1996-10-31  0:00 12%   ` Jon S Anthony
@ 1996-10-31  0:00 11%   ` Joachim Durchholz
  1996-11-02  0:00  9%   ` Jon S Anthony
  1996-11-02  0:00 13%   ` Jon S Anthony
  6 siblings, 0 replies; 99+ results
From: Joachim Durchholz @ 1996-10-31  0:00 UTC (permalink / raw)



jsa@alexandria wrote 31.10.96:

> I guess you like system validity problems.

No, Eiffel fanatics don't like system validity either (too complicated,  
difficult to ascertain correctness of checking code). In fact, there  
doesn't seem to be a compiler in existence that can do this check at  
compile-time.

Current technology seems to do the checks at run-time, which isn't worse  
than anything used to solve similar problems in other languages (typecasts  
in C++ especially if typesafe, typecase constructs and similar stuff).

*However*, there is a proposal floating around that allows static type  
checking without having to resort to system-wide checks, and this is  
commonly regarded as an advance over system validity and run-time checks.

Regards,
-Joachim

--
Looking for a new job. Resume available on request. WWW version of resume
available under http://www.franken.de/users/herold/jhd/resume/index.html




^ permalink raw reply	[relevance 11%]

* Re: Eiffel and Java + Ada dispatching
  1996-10-30  0:00  7%     ` Don Harrison
@ 1996-10-30  0:00 13%       ` Jon S Anthony
  0 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-10-30  0:00 UTC (permalink / raw)



In article <E02Lu2.In3@syd.csa.com.au> donh@syd.csa.com.au (Don Harrison) writes:

> Sorry, I don't qualify as an Ada specialist (and comp.lang.ada will back me
> up here). :)  However, ...

:-)


> Notice he's (you're) saying "only one effective effective operation"
> (single dispatching). What I didn't mention is that in Ada, control
> over dispatching can be *shared* by multiple parameters, but for a
> call to be valid the actual dispatching parameters must have the
> same type ensuring that binding to a unique procedure occurs.

Right.


> It almost appears that having B as a dispatching parameter is redundant 
> but it conveys the extra information that it must have the same type as A.

Right.


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 13%]

* Re: Eiffel and Java + Ada dispatching
    1996-10-29  0:00 10%   ` Eiffel and Java + Ada dispatching Vincent WEBER
  1996-10-30  0:00  7%   ` Robert I. Eachus
@ 1996-10-30  0:00 11%   ` Jon S Anthony
  1996-11-04  0:00 10%     ` Don Harrison
  1996-10-31  0:00 12%   ` Jon S Anthony
                     ` (3 subsequent siblings)
  6 siblings, 1 reply; 99+ results
From: Jon S Anthony @ 1996-10-30  0:00 UTC (permalink / raw)



In article <5563vp$1of@buggy.news.easynet.net> Sacha@easynet.fr (Vincent WEBER) writes:

> In article <E00t53.CG2@syd.csa.com.au>, donh@syd.csa.com.au says...
> 
> >
> >Don't mistake Ada's symmetrical syntax for multiple dispatching (binding
> >driven by more than one parameter). Ada is still single dispatched so for
> >dispatching operations, the symmetry is syntactic rather than semantic.  
> >
>
> Hum... I'm lost, two ada specialists saying two different things :)

Well, the problem is that Don is not an "ada specialist" and is in
error about there not being any semantics to this (or maybe just
simplifying to avoid the details).  There are indeed semantic aspects
as I point out in another note, but these do not imply multiple
dispatch.  So, that part is certainly correct.


> Let me cote an article from the french magazine "L'Objet" (Vol 1, no
> 1, Spring 95), by Antoine Bertier (Tomson Software Products) and
> Pascal Plisson (Alsys). I tried to translate from french to english,
> please apologize the mistakes if any :) "It is important to note
> than tags of all the parameters have to be identical at run-time to
> have the dispatching done to only one effective operation.
> Therefore there is no priviliged parameter for dispatching as it is
> the case in other languages. This is an important advantage of Ada
> 95 's model compared to other languages such as C++, that break the
> natural symetry of some operations in privileging the parameter used
> for the dispatching ( et need a way to reference this parameter :
> "this" in C++). For instance :

Yes, this is true and captures some (I suppose most) of the semantic
aspects.  But note that there is no conflict here with the assertion
that these are _not_ multi-dispatch.


> Well I think that one of the two parts is wrong :) any comment ?

Don's statement at face value is in error, but not on the salient part
of multiple-dispatch.


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
Belmont, MA 02178
617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 11%]

* Re: Eiffel and Java + Ada dispatching
  1996-10-29  0:00 10%   ` Eiffel and Java + Ada dispatching Vincent WEBER
@ 1996-10-30  0:00  9%     ` Jean-Marc Jezequel
  1996-11-01  0:00 13%       ` Joachim Durchholz
  1996-11-01  0:00 10%       ` Don Harrison
  1996-10-30  0:00  7%     ` Don Harrison
  1 sibling, 2 replies; 99+ results
From: Jean-Marc Jezequel @ 1996-10-30  0:00 UTC (permalink / raw)
  To: Vincent WEBER



In article <5563vp$1of@buggy.news.easynet.net>, Sacha@easynet.fr (Vincent WEBER) writes:
>In article <E00t53.CG2@syd.csa.com.au>, donh@syd.csa.com.au says...


>>Don't mistake Ada's symmetrical syntax for multiple dispatching (binding
>>driven by more than one parameter). Ada is still single dispatched so for
>>dispatching operations, the symmetry is syntactic rather than semantic.  

>Hum... I'm lost, two ada specialists saying two different things :) Let me cote 
>an article from the french magazine "L'Objet" (Vol 1, no 1, Spring 95), by 

>  type TILABLE_WINDOW is new WINDOW;
>  TILE(A,B : TILABLE_WINDOW);
>    -- display the two window one under the other
>    -- in covering all the screen
>  MAIN_WINDOW, MESSAGE_WINDOW : TILABLE_WINDOW;
>  TILE(MAIN_WINDOW, MESSAGE_WINDOW);
>    -- the call is perfectly symetric. the parameters can be swapped
>    -- in C++ we would have had a dissymetric call like:
>    -- MAIN_WINDOW.TILE(MESSAGE_WINDOW);

>Well I think that one of the two parts is wrong :) any comment ?

No. Both are (seems to be, cause the Ada95 fragment lacks details) right.

1) Ada95 is still single dispatched
2) but this is combined with the static overloading inherited from Ada83; which is merely
syntactic sugar for routine having (statically) different signatures. In this respect, it is
exactly like C++ or Java, but for the symetric syntax. 
May be the confusion comes form the fact that in CLOS, this symetric syntax is used for
the real thing: multiple dispatch.


The only thing you really need to make use of OO polymorphism is dynamic binding.
While having at the same time static overloading can make some code fragment more "natural" to
write, the apparent proximity of this feature with dynamic binding yield so much confusion on
the non-expert eyes that you do not wonder why I prefer to teach Eiffel rather 
than C++, Java or even Ada95.


As an aside, I once wrote a paper on how to emulate multiple dispatch in a parallel 
linear algebra library in Eiffel, and it was refused on the ground that a well known 
existing library had already solved the problem using C++ overloading. Even this
"expert" C++ referee had no clue on the difference between static and dynamic binding :-(




---
Jean-Marc Jezequel               | Tel : +81 (3) 3812-2111 ext. 4116
IRISA/CNRS, currently visiting:  | Fax : +81 (3) 5689-4365
Dept. of Information Science     | e-mail : jezequel@irisa.fr  or
Faculty of Science               | e-mail : jezequel@is.s.u-tokyo.ac.jp
The University of Tokyo          | http://www.irisa.fr/pampa/PROF/jmj.html   
Hongo Bunkyo-Ku, Tokyo 113, JAPAN






^ permalink raw reply	[relevance 9%]

* Re: Eiffel and Java + Ada dispatching
  1996-10-29  0:00 10%   ` Eiffel and Java + Ada dispatching Vincent WEBER
  1996-10-30  0:00  9%     ` Jean-Marc Jezequel
@ 1996-10-30  0:00  7%     ` Don Harrison
  1996-10-30  0:00 13%       ` Jon S Anthony
  1 sibling, 1 reply; 99+ results
From: Don Harrison @ 1996-10-30  0:00 UTC (permalink / raw)



Vincent WEBER writes:

:In article <E00t53.CG2@syd.csa.com.au>, donh@syd.csa.com.au says...
:
:>
:>Don't mistake Ada's symmetrical syntax for multiple dispatching (binding
:>driven by more than one parameter). Ada is still single dispatched so for
:>dispatching operations, the symmetry is syntactic rather than semantic.  
:>
:
:Hum... I'm lost, two ada specialists saying two different things :) 

Sorry, I don't qualify as an Ada specialist (and comp.lang.ada will back me
up here). :)  However, ...

:Let me cote 
:an article from the french magazine "L'Objet" (Vol 1, no 1, Spring 95), by 
:Antoine Bertier (Tomson Software Products) and Pascal Plisson (Alsys). I tried 
:to translate from french to english, please apologize the mistakes if any :)

Don't know how the French was, but the English is pretty good. :)

:"It is important to note than tags of all the parameters have to be identical 
:at run-time to have the dispatching done to only one effective operation. 

Notice he's (you're) saying "only one effective effective operation" 
(single dispatching). What I didn't mention is that in Ada, control over
dispatching can be *shared* by multiple parameters, but for a call to be valid
the actual dispatching parameters must have the same type ensuring that
binding to a unique procedure occurs. In the example below, type TILABLE_WINDOW 
is presumably tagged so both parameters A and B jointly control dispatching. 
However, MAIN_WINDOW and MESSAGE_WINDOW must have the same type; otherwise, an exception is raised).

It almost appears that having B as a dispatching parameter is redundant 
but it conveys the extra information that it must have the same type as A.

:Therefore there is no priviliged parameter for dispatching as it is the case in 
:other languages. This is an important advantage of Ada 95 's model compared to 
:other languages such as C++, that break the natural symetry of some operations 
:in privileging the parameter used for the dispatching ( et need a way to 
:reference this parameter : "this" in C++). For instance :
:  
:  type TILABLE_WINDOW is new WINDOW;
:  TILE(A,B : TILABLE_WINDOW);
:    -- display the two window one under the other
:    -- in covering all the screen
:  MAIN_WINDOW, MESSAGE_WINDOW : TILABLE_WINDOW;
:  TILE(MAIN_WINDOW, MESSAGE_WINDOW);
:    -- the call is perfectly symetric. the parameters can be swapped
:    -- in C++ we would have had a dissymetric call like:
:    -- MAIN_WINDOW.TILE(MESSAGE_WINDOW);
:
:  " (end of quotation).

A symmetrical solution in Eiffel which also conveys the fact that the windows
must have the same type might be:

class TILABLE_WINDOW is ...
class TILABLE_WINDOW_OPS is
  ...
  tile (a, b: TILABLE_WINDOW) is 
  require same_type (a, b)
  do ... end
  ...
end

and somewhere:

  main_window, message_window : TILABLE_WINDOW
  window_ops: TILABLE_WINDOW_OPS
  ...
  window_ops.tile (main_window, message_window)

We've had to invent another class to get symmetry. Oh, well at least it's 
obvious we are using single-dispatching.


Don.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Don Harrison             donh@syd.csa.com.au






^ permalink raw reply	[relevance 7%]

* Re: Eiffel and Java + Ada dispatching
    1996-10-29  0:00 10%   ` Eiffel and Java + Ada dispatching Vincent WEBER
@ 1996-10-30  0:00  7%   ` Robert I. Eachus
  1996-10-30  0:00 11%   ` Jon S Anthony
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 99+ results
From: Robert I. Eachus @ 1996-10-30  0:00 UTC (permalink / raw)



In article <557ce3$ojh@tjnews.is.s.u-tokyo.ac.jp> jezequel@piccolo.is.s.u-tokyo.ac.jp (Jean-Marc Jezequel) writes:

  > The only thing you really need to make use of OO polymorphism is
  > dynamic binding.  While having at the same time static overloading
  > can make some code fragment more "natural" to write, the apparent
  > proximity of this feature with dynamic binding yield so much
  > confusion on the non-expert eyes that you do not wonder why I
  > prefer to teach Eiffel rather than C++, Java or even Ada95.

   But you just teach it like we have always taught Ada
overloading--if the compiler is happy you don't have a problem. ;-)

   Seriously the combination of dispatching on multiple parameters in
Ada and overloading allows some really neat stuff--but the "simple"
examples are so nasty I'm not going to write them, lest someone copy
without understanding.  Basically if a subprogram has multiple
parameters which it dispatches on, and this can include the return
value, and there is one and only one way to interpret the expression
containing the call, then the dispatching resolves to a single
controlling type.

    If you want the effect of dispatching on multiple parameters, and
this is sometimes useful, you have to break the symmetry in your
declarations:

    function "+"(L: Object; R: Object'CLASS) return Object'CLASS;

    will dispatch only on the first parameter, and you may have a
second dispatching call to complete the dispatch.  (It is the nature
of these completing calls that they should be declared as generics
immediately in the scope containing the type declaration, and
instantiated elsewhere if they need both parameters.) Yes, you can
end up doing N**2 or even N**3 instantiations if the implementation of
the operation requires it.  But that is still a win, since you would
have had to write the individual operations anyway, but the generic
can do part of the work.

    The other case, which is much more useful is where you can use a
single intermediate type.  Now you end up with at most 2N or 3N
functions to write, and often using inheritance to eliminate most of
those.  For example suppose you have a tagged type, and you want to
define heterogenous list type over the class.  No problem, and no
generics or additional declarations required, including for the
operation:

    function "+"(L: Element, R: Element'CLASS) return Element_List;

    The body is:

    function "+"(L: Element, R: Element'CLASS) return Element_List is
    begin return L+New_List(R); end "+";
    
    This body has two dispatching operations.  New_List dispatches on
R, and the + dispatches to the + defined for L's type and List. No
overriding or additional declarations required, since the List type
acts as an intermediate.

    (You can do the same thing with method notation, but it is a lot
harder to get right.  Try it. ;-)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[relevance 7%]

* Re: Eiffel and Java + Ada dispatching
  @ 1996-10-29  0:00 10%   ` Vincent WEBER
  1996-10-30  0:00  9%     ` Jean-Marc Jezequel
  1996-10-30  0:00  7%     ` Don Harrison
  1996-10-30  0:00  7%   ` Robert I. Eachus
                     ` (5 subsequent siblings)
  6 siblings, 2 replies; 99+ results
From: Vincent WEBER @ 1996-10-29  0:00 UTC (permalink / raw)



In article <E00t53.CG2@syd.csa.com.au>, donh@syd.csa.com.au says...

>
>Don't mistake Ada's symmetrical syntax for multiple dispatching (binding
>driven by more than one parameter). Ada is still single dispatched so for
>dispatching operations, the symmetry is syntactic rather than semantic.  
>

Hum... I'm lost, two ada specialists saying two different things :) Let me cote 
an article from the french magazine "L'Objet" (Vol 1, no 1, Spring 95), by 
Antoine Bertier (Tomson Software Products) and Pascal Plisson (Alsys). I tried 
to translate from french to english, please apologize the mistakes if any :)

"It is important to note than tags of all the parameters have to be identical 
at run-time to have the dispatching done to only one effective operation. 
Therefore there is no priviliged parameter for dispatching as it is the case in 
other languages. This is an important advantage of Ada 95 's model compared to 
other languages such as C++, that break the natural symetry of some operations 
in privileging the parameter used for the dispatching ( et need a way to 
reference this parameter : "this" in C++). For instance :
  
  type TILABLE_WINDOW is new WINDOW;
  TILE(A,B : TILABLE_WINDOW);
    -- display the two window one under the other
    -- in covering all the screen
  MAIN_WINDOW, MESSAGE_WINDOW : TILABLE_WINDOW;
  TILE(MAIN_WINDOW, MESSAGE_WINDOW);
    -- the call is perfectly symetric. the parameters can be swapped
    -- in C++ we would have had a dissymetric call like:
    -- MAIN_WINDOW.TILE(MESSAGE_WINDOW);

  " (end of quotation).

Well I think that one of the two parts is wrong :) any comment ?





^ permalink raw reply	[relevance 10%]

* Re: "use" clauses and Ada 95 OOP
  @ 1996-07-25  0:00  0% ` JamesS1889
  0 siblings, 0 replies; 99+ results
From: JamesS1889 @ 1996-07-25  0:00 UTC (permalink / raw)



In article <JSA.96Jul23220309@alexandria>, jsa@alexandria (Jon S Anthony)
writes:

>Well, this still does not answer my question, but maybe it does not
>matter.  I think I now see that the issue is that in Ada, dispatching
>is a local issue and does _not_ occur by default - rather it occurs
>for primitive ops of tagged tyes iff you pass in a "class-wide" actual
>to a controlling formal parameter.  To not dispatch you simply use an
>actual of a specific type and then the operation will be statically
>bound.  So, dispatching or not has nothing to do with qualified names.

And I actually don't know as much as I should about dispatching in C++. 
You're right, it probably doesn't matter.  I was actually talking about
syntactic analogy.  Semantically, you are right.

>In Java and C++ (with"virtual"...)  dispatching is a global issue and
>the default is to dispatch, and to not dispatch you have to explicitly
>request non-dispatching with a qualified name.  So, you appear to have
>linked up qualified name notation with explicit calls to the function
>so qualified.  OK, yes, this is different than the situation in Ada
>and notice that the use of "use" does not change the semantics of this
>only the visual appearance.

Agreed.

>I suppose the route that you would be more comfortable with then is the
>one that I mentioned in a previous post, viz., the use of abstract base
>types for any extension that provides _new_ primitive operations.  You
>then use dispatching invocations only on the abstract operation.  You
>would then typically (well I suppose) use qualified naming but since
>the operation is abstract it would not seem "funny" that it dispatched
>to wherever (based on the type indicator):

Maybe so.  It's under consideration ;-)

James Squire                                      
mailto:ja_squire@csehp3.mdc.com
MDA Avionics Tools & Processes
McDonnell Douglas Aerospace              http://www.mdc.com
Opinions expressed here are my own and NOT my company's
"Only one Earth Captain has ever survived battle with a Minbari fleet.  He
is behind me.
You are in front of me.  If you value your lives, be somewhere else!"
           -- Delenn, "Severed Dreams"




^ permalink raw reply	[relevance 0%]

* Re: "use" clauses and Ada 95 OOP
  @ 1996-07-24  0:00 13% ` Jon S Anthony
  0 siblings, 0 replies; 99+ results
From: Jon S Anthony @ 1996-07-24  0:00 UTC (permalink / raw)



In article <4t349j$lll@newsbf02.news.aol.com> jamess1889@aol.com (JamesS1889) writes:

> In article <JSA.96Jul19191630@alexandria>, jsa@alexandria (Jon S Anthony)
> writes:
> 
> >What do either of you mean by "the function that is associated with X
> >at runtime" here?  In the environment we are talking about here there
> >is no "_the_ func associated with X".  X contains a value which will
> >have a type indicator which will provide access to the proper jump
> >table entry.  Since the value of X can change (e.g., in C++ or Java up
> >level assignments) the func "associated" with X can change (and not
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not specific!
> >necessarily be the one defined in the class of which X was a declared
> >instance).  Seems pretty much like the exact same issue.
> 
> You are speaking of the value of X, and you are treating func as if it
> were a specific function.

Actually, I am definitely _not_ treating func as if it were a specific
function.

> In C++ and Java, functions that operate on objects are defined
> syntactically within the definition of the object, on the same level with
> the attributes of the object.  The corollary in Ada (which would be
> illegal) would to all function definitions to appear between the "type x
> is tagged record..." and the "end record;" - sort of like what Ada95 DOES
> do with protected objects.

No, the "corollary in Ada" is that all such operations (primitive) are
those defined within the same immediate package specification as the
tagged type.  So, _only_ those within the same immediated spec are
"dispatchable" operations - just like _only_ those within a class def
(and in C++ tagged with "virtual") are dispatching (note the "able"
and "ing" suffixes!)


> In C++ and Java, you can write x.func.  In Ada95, you have to write
> Pkg2.Func(x), UNLESS you use the "use clause", which is the question this
> whole thread is about.
> 
> Now, do you understand?

Well, this still does not answer my question, but maybe it does not
matter.  I think I now see that the issue is that in Ada, dispatching
is a local issue and does _not_ occur by default - rather it occurs
for primitive ops of tagged tyes iff you pass in a "class-wide" actual
to a controlling formal parameter.  To not dispatch you simply use an
actual of a specific type and then the operation will be statically
bound.  So, dispatching or not has nothing to do with qualified names.

In Java and C++ (with"virtual"...)  dispatching is a global issue and
the default is to dispatch, and to not dispatch you have to explicitly
request non-dispatching with a qualified name.  So, you appear to have
linked up qualified name notation with explicit calls to the function
so qualified.  OK, yes, this is different than the situation in Ada
and notice that the use of "use" does not change the semantics of this
only the visual appearance.

I suppose the route that you would be more comfortable with then is the
one that I mentioned in a previous post, viz., the use of abstract base
types for any extension that provides _new_ primitive operations.  You
then use dispatching invocations only on the abstract operation.  You
would then typically (well I suppose) use qualified naming but since
the operation is abstract it would not seem "funny" that it dispatched
to wherever (based on the type indicator):

package Pkg2 is
    type T is abstract ...
    function Func ( x : T ) return ... is abstract;
...
end Pkg2;

package Pkg2.Concrete_T is
    type New_T is new T with ...        -- no longer abstract...
    function Func ( x : T ) return ...; -- no longer abstract...
...
end Pkg2.Concrete_T;

...etc...

-- Somewhere sometime later

    X : Pkg2.T'Class := ...
...
    Pkg2.Func(X);  -- Dispatch to proper func which _can't_ be
                   -- Pkg2.Func since it is _abstract_

Maybe this is jives more with your sensitivities here...

/Jon






-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





^ permalink raw reply	[relevance 13%]

* Re: Real OO
  1996-03-22  0:00 12%   ` Norman H. Cohen
@ 1996-03-27  0:00 12%     ` Don Harrison
  0 siblings, 0 replies; 99+ results
From: Don Harrison @ 1996-03-27  0:00 UTC (permalink / raw)


Norman H. Cohen wrote:

:In article <DonJqn.755@assip.csasyd.oz>, donh@syd.csa.com.au
:(Don Harrison) writes: 
:
:|>                                         In Eiffel, there is only one species of
:|> type - the class - which may be viewed as specific or class-wide depending on
:|> the context. This makes modelling considerably easier.
:|>
:|> Ada complicates matters by forcing an atificial distinction of specific versus
:|> classwide depending on usage. Since the formal and actual parameters of an
:|> operation may be either specific or classwide, the number of possible
:|> combinations is 4 compared with 1 in Eiffel. To my mind, this is 4 times more
:|> complicated than is really needed.
:
:This is not an artificial distinction.  Let us consider actual parameters
:and formal parameters separately.

I note that you spell better than I do :-).

Whether we call it 'artificial' or not doesn't matter too much, I guess. What is
significant, is whether it is necessary to make such a distinction. There are a
number of issues:

  a) Is there a significant difference in efficiency between the two approaches?
     Quantitatively, what is the relative difference in efficiency of Jump to
     Subroutine compared with an Indirect Jump to Subroutine?
     As Joachim pointed out, Eiffel compilers typically optimise where possible.
     Perhaps optimisation by the developer would be more effective but remember
     that efficiency is being traded off against the power and flexibility of
     dynamic binding.

  b) What is more important for the job at hand - flexibility and reusability 
     or efficiency? As Joachim indicated, Eiffel developers would be more 
     concerned with flexibility and reusability, prefering to maximise dynamic
     binding rather than squeezing every last clock cycle out of the processor.
     Admittedly, however, an Ada developer implementing a real-time system with 
     stringent timing constraints may be more interested in efficiency.

  c) How do the mechanisms compare wrt clarity of expression?
     IMO, the Eiffel mechanism simplifies reasoning.

:In the case of actual parameters, it is a formalization of the
:distinction that Bertrand Meyer recognizes between the static type and
:the dynamic type of a reference.  Think of an Ada actual parameter of a
:specific type as an Eiffel reference whose dynamic type is known to be
:identical to its static type.  A method call can be far more efficient if
:this knowledge is conveyed to the compiler, and it is common in practice
:for this knowledge to be available.  (The extra efficiency arises not
:only from saving a cycle or two for an indirect jump, but also because of
:the possibility of inlining the method body or performing precise
:interprocedural analysis.)

I guess the difference in performance here would depend on how effectively Eiffel
compilers optimise (by staticly binding and inlining) and how much slower an 
indirect jump is. 

:In the case of formal parameters, the use of a classwide type or specific
:type reflects the distinction between a single type and the hierarchy of
:types descended (in zero or more steps) from that type.  (In Eiffel, the
:word "class" refers to any one of these types; in Ada, the word "class"
:refers to the hierarchy, so "classwide" means "hierarchy-wide".)  A
:classwide subprogram (i.e., one with classwide formal parameters) is one
:whose algorithm is the same for all objects in the hierarchy.  A
:dispatching subprogram (i.e., one with specific formal parameters) is one
:whose algorithm depends on the tag (in Eiffel terms, the dynamic type) of
:the actual parameter.  The body of a classwide subprogram relies only on
:properties common to all types in the hierarchy, i.e., features
:introduced at the root of the hierarchy.  These may include record
:components, other classwide subprograms, and dispatching operations.

An Eiffel operation may effectively be made 'classwide' by declaring it 'frozen'.
The real purpose of 'frozen' is to prevent the implementation being changed in
descendants so that they may rely on fixed universal semantics. Freezing features
for efficiency purposes is a hack as pointed out by Bob Duff. Note that you 
generally would not want to freeze an implementation because flexibility is 
reduced. (You can both freeze and provide an overridable version by using two
copies but that's another matter).

:For a one-parameter subprogram, the effect of a classwide subprogram
:could be achieved by a dispatching subprogram that is never overridden.
:Making it classwide simply documents the fact that the algorithm does not
:depend on the tag of the parameter, and causes the compiler to catch any
:attempt to override.  The real power of a classwide program arises with
:multiple parameters.  In Eiffel, dispatching is controlled by the one
:object whose method is invoked (the x in x.f()).  In an Ada dispatching
:subprogram, there can be multiple parameters controlling the dispatching.
:Consider a hierarchy for geometric figures, with Shape_Type at the root
:and types such as Circle_Type, Triangle_Type, and Rectangle_Type at the
:leaves.

They may all be regarded as controlling dispatching only because they happen 
to be of the same type. It is really the common type of the operands that is 
controlling dispatching rather than the operands per se. The operation being 
executed belongs to the class, not the instances of the class - the same as 
Eiffel.

I prefer the dot notation of the Eiffel syntax because all the parameters in the 
parentheses have the same status - they are all effectively classwide - and the 
controlling operand is clearly identified because it the target of the call. 
There is no need to put up a signpost to say which is classwide and which is not 
as is necessary with co-encapsulation. The information is implicit. In the case 
of 'frozen', that information is explicit but conveys different semantics.  

:  There may be a dispatching operation Corresponding_Parts_Equal
:defined (as an abstract function) for Shape_Type and overridden for each
:shape.  For example: 
:
:   function Corresponding_Parts_Equal (C1, C2: Circle_Type) return Boolean is
:   begin
:      return C1.Radius = C2.Radius;
:   end Corresponding_Parts_Equal;
:
:
:   function Corresponding_Parts_Equal
:      (R1, R2: Rectangle_Type) return Boolean is
:   begin
:      return
:         (R1.Base = R2.Base and R1.Height = R2.Height) or
:         (R1.Base = R2.Height and R1.Height = R2.Base);
:   end Corresponding_Parts_Equal;
:
:Each time a new kind of shape is introduced to the hierarchy, a new
:overriding version of Corresponding_Parts_Equal, concerned only with the
:features of that kind of shape, is written.
:
:The call Corresponding_Parts_Equal(Shape1, Shape2), where Shape1 and
:Shape2 are of type Shape_Type'Class (in Eiffel terms, their static types
:are Shape_Type and their dynamic types are unknown), will dispatch to the
:first body above if the dynamic types of Shape1 and Shape2 are both
:Circle_Type, to the second body above if the dynamic types are both
:Rectangle_Type, and so forth.  But if Shape1 and Shape2 have different
:dynamic tags, there is no sensible way to check that their corresponding
:parts are equal, and a run-time error results.  That leaves the problem
:of how to determine whether two arbitrary Shape_Type'Class values,
:possibly with different tags, are congruent, and this is where classwide
:subprograms come in.  There is no requirement that the parameters of a
:classwide subprogram have the same tag.  Therefore, we can write: 
:
:    function Congruent (Shape1, Shape2: Shape_Type'Class) return Boolean is
:    begin
:       return
:          Shape1'Tag = Shape2'Tag and then
:          Corresponding_Parts_Equal (Shape1, Shape2);
:    end Congruent;
:
:When the shapes have different tags, the function immediately returns
:False without invoking Corresponding_Parts_Equal.

This might be done in Eiffel by:

class CONGRUENCY
inherit INTERNAL
feature
  congruent (a, b: SHAPE): BOOLEAN is
  do
    Result := (dynamic_type (a) = dynamic_type (b)) and then equal (a, b)
  end
end

Yes, short circuit booleans were stolen from Ada. Thanks, Ada :-).

Note that equal may be protected with a precondition thus:

  equal (a, b: ANY): BOOLEAN is
  require
    same_type: dynamic_type (a) = dynamic_type (b)
  deferred
  end

(Not sure of the details, but you see what I mean).

:--
:Norman H. Cohen    ncohen@watson.ibm.com

Don.










^ permalink raw reply	[relevance 12%]

* Re: Real OO
    1996-03-22  0:00 12%   ` Norman H. Cohen
@ 1996-03-23  0:00  0%   ` Joachim Durchholz
  1 sibling, 0 replies; 99+ results
From: Joachim Durchholz @ 1996-03-23  0:00 UTC (permalink / raw)


ncohen@watson.ibm.com wrote 22.03.96 on Re: Real OO:

> ...a specific type as an Eiffel reference whose dynamic type is known to be
> identical to its static type.  A method call can be far more efficient if
> this knowledge is conveyed to the compiler, and it is common in practice
> for this knowledge to be available.

The Eiffel paradigma is that it should *not* be possible to fix a formal  
parameter's dynamic type to its static types. Such a thing is considered  
an unnecessary limitation introduced on the routine, for efficiency  
reasons that aren't even valid because a compiler can determine wether  
such an optimization is possible.
In fact, all Eiffel literature on the subject strongly encourages compiler  
writers to replace dynamic cally by static calls whenever possible, and to  
inline code wherever it makes sense.

> For a one-parameter subprogram, the effect of a classwide subprogram
> could be achieved by a dispatching subprogram that is never overridden.

Agreed.

> Making it classwide simply documents the fact that the algorithm does not
> depend on the tag of the parameter, and causes the compiler to catch any
> attempt to override.

This assumes that the writer of a module knows that his routines never  
need to be overridden. While this may be true when writing a program with  
a fixed and well-understood task, this isn't true when writing libraries,  
or when programs are modified in the future and in ways that weren't  
anticipated.
Considering the fact that fixed and well-understood tasks don't need OO  
(structured programming and functional decomposition should suffice for  
this type of tasks), this argument gains some weight.

> The real power of a classwide program arises with
> multiple parameters.  In Eiffel, dispatching is controlled by the one
> object whose method is invoked (the x in x.f()).  In an Ada dispatching
> subprogram, there can be multiple parameters controlling the dispatching.
>
> [Omitting details on dispatching based on the dynamic type of multiple
> parameters]

The type of dispatching noted here can easily be achieved with anchored  
types in Eiffel. In an Ada-style notation, this would look as follows:

  function Corresponding_Parts_Equal
    (Self: Shape_Type; Other: like Self)
  return Boolean

The "like Self" part requires Other to have the same dynamic type as Self,  
or a type that is a descendant of Self's type.

I'm not sure wether this is enough to handle all cases that arise in  
practice, but it goes a long way.

BTW I see serious problems with the Congruent function given.

Consider descandant types "Filled_Circle", "Hatched_Circle" etc. - with  
the understanding that these don't have any new geometric properties that  
should influence Corresponding_Parts_Equal or Congruent.
First of all, it would be necessary to define a Corresponding_Parts_Equal  
function for each pair of Circle_Type descendants - this can become quite  
a formidable task if the number of direct and indirect descandants grows.
In addition, the Congruent code will break - Shape1'Tag and Shape2'Tag  
will not be equal, making Congruent return false even if a Filled_Circle  
and a Hatched_Circle actually have equal corresponding parts.


-Joachim

--
Im speaking for myself here.
## CrossPoint v3.1 ##




^ permalink raw reply	[relevance 0%]

* Re: Real OO
  @ 1996-03-22  0:00 12%   ` Norman H. Cohen
  1996-03-27  0:00 12%     ` Don Harrison
  1996-03-23  0:00  0%   ` Joachim Durchholz
  1 sibling, 1 reply; 99+ results
From: Norman H. Cohen @ 1996-03-22  0:00 UTC (permalink / raw)


In article <DonJqn.755@assip.csasyd.oz>, donh@syd.csa.com.au
(Don Harrison) writes: 

|>                                         In Eiffel, there is only one species of
|> type - the class - which may be viewed as specific or class-wide depending on
|> the context. This makes modelling considerably easier.
|>
|> Ada complicates matters by forcing an atificial distinction of specific versus
|> classwide depending on usage. Since the formal and actual parameters of an
|> operation may be either specific or classwide, the number of possible
|> combinations is 4 compared with 1 in Eiffel. To my mind, this is 4 times more
|> complicated than is really needed.

This is not an artificial distinction.  Let us consider actual parameters
and formal parameters separately.

In the case of actual parameters, it is a formalization of the
distinction that Bertrand Meyer recognizes between the static type and
the dynamic type of a reference.  Think of an Ada actual parameter of a
specific type as an Eiffel reference whose dynamic type is known to be
identical to its static type.  A method call can be far more efficient if
this knowledge is conveyed to the compiler, and it is common in practice
for this knowledge to be available.  (The extra efficiency arises not
only from saving a cycle or two for an indirect jump, but also because of
the possibility of inlining the method body or performing precise
interprocedural analysis.)

In the case of formal parameters, the use of a classwide type or specific
type reflects the distinction between a single type and the hierarchy of
types descended (in zero or more steps) from that type.  (In Eiffel, the
word "class" refers to any one of these types; in Ada, the word "class"
refers to the hierarchy, so "classwide" means "hierarchy-wide".)  A
classwide subprogram (i.e., one with classwide formal parameters) is one
whose algorithm is the same for all objects in the hierarchy.  A
dispatching subprogram (i.e., one with specific formal parameters) is one
whose algorithm depends on the tag (in Eiffel terms, the dynamic type) of
the actual parameter.  The body of a classwide subprogram relies only on
properties common to all types in the hierarchy, i.e., features
introduced at the root of the hierarchy.  These may include record
components, other classwide subprograms, and dispatching operations.

For a one-parameter subprogram, the effect of a classwide subprogram
could be achieved by a dispatching subprogram that is never overridden.
Making it classwide simply documents the fact that the algorithm does not
depend on the tag of the parameter, and causes the compiler to catch any
attempt to override.  The real power of a classwide program arises with
multiple parameters.  In Eiffel, dispatching is controlled by the one
object whose method is invoked (the x in x.f()).  In an Ada dispatching
subprogram, there can be multiple parameters controlling the dispatching.
Consider a hierarchy for geometric figures, with Shape_Type at the root
and types such as Circle_Type, Triangle_Type, and Rectangle_Type at the
leaves.  There may be a dispatching operation Corresponding_Parts_Equal
defined (as an abstract function) for Shape_Type and overridden for each
shape.  For example: 

   function Corresponding_Parts_Equal (C1, C2: Circle_Type) return Boolean is
   begin
      return C1.Radius = C2.Radius;
   end Corresponding_Parts_Equal;


   function Corresponding_Parts_Equal
      (R1, R2: Rectangle_Type) return Boolean is
   begin
      return
         (R1.Base = R2.Base and R1.Height = R2.Height) or
         (R1.Base = R2.Height and R1.Height = R2.Base);
   end Corresponding_Parts_Equal;

Each time a new kind of shape is introduced to the hierarchy, a new
overriding version of Corresponding_Parts_Equal, concerned only with the
features of that kind of shape, is written.

The call Corresponding_Parts_Equal(Shape1, Shape2), where Shape1 and
Shape2 are of type Shape_Type'Class (in Eiffel terms, their static types
are Shape_Type and their dynamic types are unknown), will dispatch to the
first body above if the dynamic types of Shape1 and Shape2 are both
Circle_Type, to the second body above if the dynamic types are both
Rectangle_Type, and so forth.  But if Shape1 and Shape2 have different
dynamic tags, there is no sensible way to check that their corresponding
parts are equal, and a run-time error results.  That leaves the problem
of how to determine whether two arbitrary Shape_Type'Class values,
possibly with different tags, are congruent, and this is where classwide
subprograms come in.  There is no requirement that the parameters of a
classwide subprogram have the same tag.  Therefore, we can write: 

    function Congruent (Shape1, Shape2: Shape_Type'Class) return Boolean is
    begin
       return
          Shape1'Tag = Shape2'Tag and then
          Corresponding_Parts_Equal (Shape1, Shape2);
    end Congruent;

When the shapes have different tags, the function immediately returns
False without invoking Corresponding_Parts_Equal.

--
Norman H. Cohen    ncohen@watson.ibm.com




^ permalink raw reply	[relevance 12%]

Results 1-99 of 99 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
     [not found]     <4id031$cf9@dayuc.dayton.saic.com>
1996-03-22  0:00     ` Real OO Don Harrison
1996-03-22  0:00 12%   ` Norman H. Cohen
1996-03-27  0:00 12%     ` Don Harrison
1996-03-23  0:00  0%   ` Joachim Durchholz
1996-07-22  0:00     "use" clauses and Ada 95 OOP Stephen Schmid
1996-07-24  0:00 13% ` Jon S Anthony
1996-07-23  0:00     Robert I. Eachus
1996-07-25  0:00  0% ` JamesS1889
1996-10-27  0:00     Eiffel and Java Vincent WEBER
1996-10-29  0:00     ` Don Harrison
1996-10-29  0:00 10%   ` Eiffel and Java + Ada dispatching Vincent WEBER
1996-10-30  0:00  9%     ` Jean-Marc Jezequel
1996-11-01  0:00 13%       ` Joachim Durchholz
1996-11-01  0:00 10%       ` Don Harrison
1996-10-30  0:00  7%     ` Don Harrison
1996-10-30  0:00 13%       ` Jon S Anthony
1996-10-30  0:00  7%   ` Robert I. Eachus
1996-10-30  0:00 11%   ` Jon S Anthony
1996-11-04  0:00 10%     ` Don Harrison
1996-11-05  0:00 11%       ` Jon S Anthony
1996-11-05  0:00 10%         ` Don Harrison
1996-11-06  0:00 13%           ` Jon S Anthony
1996-10-31  0:00 12%   ` Jon S Anthony
1996-11-01  0:00  8%     ` Jean-Marc Jezequel
     [not found]         ` <E06F2B.Az7@syd.csa.com.au>
1996-11-01  0:00 11%       ` Jon S Anthony
1996-11-04  0:00  7%         ` Don Harrison
1996-11-05  0:00 12%           ` Jon S Anthony
1996-11-02  0:00 12%       ` Robert Dewar
1996-11-04  0:00 13%         ` Norman H. Cohen
1996-11-05  0:00 11%         ` Don Harrison
1996-11-05  0:00 10%           ` Robb Nebbe
1996-11-06  0:00  7%             ` Jean-Marc Jezequel
1996-11-07  0:00  8%               ` Robb Nebbe
1996-11-06  0:00  7%             ` To overload or not to overload (was Eiffel and Java + Ada dispatching) Don Harrison
1996-11-06  0:00 11%               ` Robb Nebbe
1996-11-07  0:00  8%                 ` Don Harrison
1996-11-07  0:00 11%                   ` Jon S Anthony
1996-11-11  0:00 13%                     ` Don Harrison
1996-11-07  0:00 11%                   ` Juergen Schlegelmilch
1996-11-08  0:00  6%                     ` Don Harrison
1996-11-08  0:00  9%                       ` Don Harrison
1996-11-14  0:00 10%                         ` Jon S Anthony
1996-11-14  0:00 10%                     ` Jon S Anthony
1996-11-07  0:00 13%                   ` Jon S Anthony
1996-11-08  0:00 10%                   ` bill.williams
1996-11-11  0:00  7%                     ` Don Harrison
1996-11-07  0:00 12%                 ` Norman H. Cohen
1996-11-08  0:00  8%             ` Eiffel and Java + Ada dispatching Robert I. Eachus
1996-11-05  0:00  9%           ` Joachim Durchholz
1996-11-06  0:00  8%           ` Robert I. Eachus
1996-11-08  0:00  7%             ` Don Harrison
1996-11-08  0:00 12%               ` Robert A Duff
1996-11-12  0:00  8%                 ` Don Harrison
1996-11-12  0:00 12%                   ` Joachim Durchholz
1996-11-15  0:00  8%                     ` Richard Riehle
1996-11-16  0:00  7%                     ` Interfacing contracts (Was: Eiffel and Java + Ada dispatching) Geert Bosch
1996-11-17  0:00 13%                       ` Robert A Duff
1996-11-12  0:00 12%                   ` Eiffel and Java + Ada dispatching Robert A Duff
1996-11-13  0:00 10%                     ` Don Harrison
1996-11-13  0:00 11%                       ` Robert A Duff
1996-11-14  0:00  9%                         ` Don Harrison
1996-11-13  0:00 12%                       ` Jon S Anthony
1996-11-15  0:00 12%                         ` Don Harrison
1996-11-19  0:00 13%                           ` Jon S Anthony
1996-11-20  0:00 12%                             ` Don Harrison
1996-11-08  0:00 11%               ` Jon S Anthony
1996-11-14  0:00  8%               ` Robert I. Eachus
1996-11-14  0:00 13%                 ` Robert A Duff
1996-11-15  0:00  8%                 ` Don Harrison
1996-11-15  0:00  5%                   ` Robert I. Eachus
1996-11-19  0:00  8%                     ` Don Harrison
1996-11-18  0:00 10%                       ` Vincent Celier
1996-11-22  0:00  9%                         ` Don Harrison
1996-11-19  0:00 12%                 ` Jon S Anthony
1996-11-15  0:00  9%               ` portmanteau (was Re: Eiffel and Java + Ada dispatching) Robert I. Eachus
1996-11-07  0:00 12%           ` Eiffel and Java + Ada dispatching Jon S Anthony
1996-11-07  0:00 10%           ` Robb Nebbe
1996-11-12  0:00  8%           ` Jon S Anthony
1996-10-31  0:00 11%   ` Joachim Durchholz
1996-11-02  0:00  9%   ` Jon S Anthony
1996-11-02  0:00 13%   ` Jon S Anthony
1996-11-03  0:00 12% ` Joachim Durchholz
1996-10-28  0:00     Eiffel and Java Matthew Heaney
1996-10-30  0:00     ` Jon S Anthony
1996-11-01  0:00  7%   ` Eiffel and Java + Ada dispatching Jean-Marc Jezequel
1996-11-02  0:00  6% ` Jon S Anthony
1997-07-11  0:00  9% Dispatching and different types Phillip Durbin
1999-06-16  0:00     Object,Subject,Verb, and Phrase (Sentence) Oriented Programming Fernando D. Mato Mira
     [not found]     ` <19990617103727.07296.00000475@ng34.aol.com>
1999-06-18  0:00 11%   ` Fernando D. Mato Mira
1999-06-18  0:00 14%     ` Matthew Heaney
1999-06-18  0:00  0%       ` Fernando Mato Mira
2000-01-15  0:00     bitwise comparators Alexander Van Hecke
2000-01-16  0:00     ` DuckE
2000-01-17  0:00       ` Alexander Van Hecke
2000-01-17  0:00         ` Jeff Carter
2000-01-17  0:00           ` Alexander Van Hecke
2000-01-21  0:00             ` Ada vs. C/C++ (was re: bitwise something-or-other) Mark Lundquist
2000-01-24  0:00 12%           ` Hyman Rosen
2001-06-16 17:31     virtual functions in ada95 Thomas Nebel
2001-06-16 19:43  9% ` tmoran
2003-12-07  7:53     Question about OO programming in Ada Hyman Rosen
2003-12-07 15:34     ` James Rogers
2003-12-07 18:30       ` Martin Krischik
2003-12-07 20:25         ` James Rogers
2003-12-08  3:36           ` Hyman Rosen
2003-12-08  4:42             ` Chad Bremmon
2003-12-08  8:42               ` Hyman Rosen
2003-12-08  9:34                 ` Dmitry A. Kazakov
2003-12-08 13:25                   ` Hyman Rosen
2003-12-08 15:05                     ` Dmitry A. Kazakov
2003-12-09  4:38                       ` Hyman Rosen
2003-12-09  8:19                         ` Dmitry A. Kazakov
2003-12-09 13:29 10%                       ` Hyman Rosen
2003-12-09 14:36  0%                         ` Dmitry A. Kazakov
2009-06-19  0:36     Ada and EDF in Win32? Günther Wimpassinger
2009-06-19 15:52  9% ` sjw
2010-06-02 16:24     ANN: Ahven 1.8 Tero Koskinen
2010-06-03 12:08     ` Stephen Leake
2010-06-03 19:36       ` Dan
2010-06-04  9:17         ` Stephen Leake
2010-06-04 17:12           ` Dan
2010-06-05  4:08  9%         ` Stephen Leake
2013-03-11 19:42     Is this expected behavior or not Anh Vo
2013-03-15 21:46     ` Robert A Duff
2013-03-16  5:52       ` Shark8
2013-03-16  7:41         ` Dmitry A. Kazakov
2013-03-16 16:55           ` Shark8
2013-03-16 17:36             ` Dmitry A. Kazakov
2013-03-16 21:51               ` Shark8
2013-03-17  9:36                 ` Dmitry A. Kazakov
2013-03-18 23:13                   ` Randy Brukardt
2013-03-19  9:12                     ` Dmitry A. Kazakov
2013-03-19 21:19                       ` Randy Brukardt
2013-03-20 11:21                         ` Dmitry A. Kazakov
2013-03-20 23:57                           ` Randy Brukardt
2013-03-21 10:30                             ` Dmitry A. Kazakov
2013-03-21 23:27                               ` Randy Brukardt
2013-03-22 16:07                                 ` Dmitry A. Kazakov
2013-03-23  2:33                                   ` Randy Brukardt
2013-03-23  9:53                                     ` Dmitry A. Kazakov
2013-03-25 22:58                                       ` Randy Brukardt
2013-03-26 10:52                                         ` Dmitry A. Kazakov
2013-03-26 21:31                                           ` Randy Brukardt
2013-03-27  9:37                                             ` Dmitry A. Kazakov
2013-03-27 19:42  5%                                           ` Randy Brukardt
2013-03-28 13:50  0%                                             ` Dmitry A. Kazakov
2013-03-28 21:55  0%                                               ` Randy Brukardt
2013-03-29 12:26  0%                                                 ` Dmitry A. Kazakov
2013-07-31 18:30  6% C++/Ada dispatching Tarek Ghaleb
2014-03-25 21:41     Your wish list for Ada 202X Stoik
2014-03-26  6:25     ` Shark8
2014-03-26 20:41       ` Randy Brukardt
2014-03-27  9:20         ` Shark8
2014-03-27 21:50           ` Randy Brukardt
2014-03-28  8:17             ` Dmitry A. Kazakov
2014-03-28 21:27               ` Randy Brukardt
2014-03-29  9:44                 ` Dmitry A. Kazakov
2014-03-31 23:55                   ` Randy Brukardt
2014-04-01  8:20                     ` Dmitry A. Kazakov
2014-04-02 22:39                       ` Randy Brukardt
2014-04-05 11:10                         ` Dmitry A. Kazakov
2014-04-08  1:15                           ` Randy Brukardt
2014-04-08  9:15                             ` Dmitry A. Kazakov
2014-04-08 23:37                               ` Randy Brukardt
2014-04-09 10:40                                 ` Dmitry A. Kazakov
2014-04-10  3:28                                   ` Randy Brukardt
2014-04-10 15:31                                     ` Dmitry A. Kazakov
2014-04-11 19:04                                       ` Niklas Holsti
2014-04-11 20:43                                         ` Dmitry A. Kazakov
2014-04-11 22:04                                           ` Niklas Holsti
2014-04-12  8:20                                             ` Dmitry A. Kazakov
2014-04-13 19:43                                               ` Niklas Holsti
2014-04-15  0:08                                                 ` Randy Brukardt
2014-04-16 21:44                                                   ` Niklas Holsti
2014-04-16 22:27                                                     ` Randy Brukardt
2014-04-18 19:59                                                       ` Niklas Holsti
2014-04-18 21:28 11%                                                     ` Randy Brukardt
2014-04-10 10:41     Asynchronous Transfer of Control AdaMagica
2014-04-10 15:15 11% ` Adam Beneschan
2014-04-10 22:49 13%   ` Randy Brukardt
2014-04-10 23:16  0%     ` Adam Beneschan
2017-07-09  6:54     How to check syntax with GNAT? Victor Porton
2017-07-13  5:47  8% ` Simon Wright

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox