--
You received this message because you are subscribed to the Google Groups "ParaSail Programming Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to parasail-programming...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Yes, ParaSail is type-sound and supports constant-time method lookup, including when calling through interfaces. I'd be happy to elaborate if your are interested. The most recent publication on ParaSail is at:This paper doesn't discuss the issue of constant-time method lookup specifically, but I'd be happy to elaborate if you had any questions. ParaSail shares a feature with Ada 95 in its handling of operations with multiple operands that control dispatching, using covariance consistently for all parameters and for the result type. This approach is simpler to understand in my experience, and matches the normal way that operators like "+" work for abstract data types. ParaSail has a somewhat more efficient approach than Ada 2005 to handling multiple inheritance from interfaces, allowing method lookup to be constant time.The ParaSail reference manual is at: https://adacore.github.io/ParaSail/images/parasail_ref_manual.pdfIf you'd like to download ParaSail, visit http://parasail-lang.orgTake care,-Tucker Taft
An important thing to understand about both ParaSail and Ada 95, 2005, and 2012, is that they distinguish between "specific" types like "T" and the set of types that are derived from T, directly or indirectly. In ParaSail, that set is denoted by "T+". In Ada, it is denoted by "T'Class". In ParaSail, T+ is called a "polymorphic" type, and a parameter of type T+ can accept T or any type derived from T. In Ada, it is called a "class-wide" type. Run-time dispatching only occurs when you have an actual parameter of a polymorphic/class-wide type, and you pass it to an operation of the "root" type of the set of types (T in this case). Because of the rules of inheritance, all operations of the root type have corresponding operations in the derived types, either by inheriting an operation, or by overriding an operation with a new definition. All of this is pretty similar to C++, Java, etc., except that ParaSail/Ada provide static binding when operands are all of a "specific" type, and only does dynamic binding when the operands are polymorphic/class-wide. In C++, a similar distinction exists, but it is based more on whether the object is identified by a pointer vs. identified by a stack-resident object.In any case, the terms "covariance" and "contravariance" I am familiar with have to do with how the types of the formal parameters of an operation are adjusted upon inheritance and for the purposes of overriding. The general rule is you can override using "contravariance" in the parameter types, and "covariance" in the result type. In ParaSail and Ada, covariance is used in all cases. This is sound because on dynamically dispatched calls, all parameters that "control" dispatching are required to be of the same type, which is checked at run-time if necessary. Unlike in most languages, there is no single controlling parameter. All parameters that are of the "controlling" type are treated symmetrically.
WikiPedia has a longer discussion of covariance and contravariance:It is the discussion about inheritance in object-oriented languages that is most relevant.I realize this might not have answered your question, so feel free to send a follow-up. I also encourage you to download the release, look at the extensive examples, read the reference manual, etc.
...
Very clear. I have no question about this kind of covariance. But I'll take opportunity to re-formulate my previous question, in a simpler way. Let Queue<T> be a generic class describing a queue of T (the type of elements of the queue). Is there any relation between Queue<TCP> and Queue<IP>, two instances of Queue<T>, if type TCP extends (i.e. is derived from) type IP?
Thank you.
Process_Queue(qIP);
Process_Queue(qTCP);
I meant whether it is possible to use a Queue<TCP> object where a Queue<IP> object is expected, for example
Process_Queue(qIP);
Process_Queue(qTCP);
where qIP is a queue of IP elements (probably declared as Queue<IP> or Queue<IP+> or Queue<IP>+) and, similarly, qTCP is a queue of TCP elements.In order to be so, Queue<TCP> has to be a "subtype" or "supertype" of Queue<IP> by language definition. As ParaSail follows Ada model, I don't think that's possible (unless of course TCP is equivalent to IP).Is my guess correct?
Thank you.
On Tuesday, April 23, 2019 at 2:55:02 AM UTC+7, Tucker Taft wrote:On Mon, Apr 22, 2019 at 2:05 PM Zing Chen wrote:...Very clear. I have no question about this kind of covariance. But I'll take opportunity to re-formulate my previous question, in a simpler way. Let Queue<T> be a generic class describing a queue of T (the type of elements of the queue). Is there any relation between Queue<TCP> and Queue<IP>, two instances of Queue<T>, if type TCP extends (i.e. is derived from) type IP?When you declare Queue, you have to specify something about "T." You might want it to be merely Assignable, or perhaps Comparable or Hashable or Imageable. E.g.:interface Queue<T is Comparable<>> is...end interface QueueAt some later point, you could define another interface that required a Queue, and at that point, you could further constrain "T", so you could write:interface Queuing_System<Network_Q is Queue<T => IP<>>> is ...by specifying some limitations on T in the formal type for Network_Q we limit what sort of Queue can be passed when instantiating Queuing_System. Hence the following is an illegal instantiation of Queuing_System:type Simple_Queuing_System isQueuing_System<Network_Q => Queue<Integer>> // Illegalwhereas this is a legal instantiation:type Better_Queuing_System isQueuing_System<Network_Q => Queue<TCP>> // LegalI hope that at least partially addresses your question.