* User-defined type attributes @ 2008-03-12 18:58 Eric Hughes 2008-03-12 21:23 ` Dmitry A. Kazakov 2008-03-14 1:46 ` Randy Brukardt 0 siblings, 2 replies; 29+ messages in thread From: Eric Hughes @ 2008-03-12 18:58 UTC (permalink / raw) In light of the recent discussion of formal package parameters, I have been wondering about user-defined type attributes. They don't currently exist in any version of Ada. First, a historical question: Was there a proposal for user attributes that was considered for Ada 2005? My interest in them is akin to my interest in formal package parameters. The prefixed views for functions and procedures (dot- notation) of Ada 2005 are directly analogous to what would be required for attribute syntax. This notation hints at the possibility of a kind of visibility related to formal type parameters, one which would make ordinary subprograms and attribute functions visible without making the entire definition package visible. The idea is that a formal type parameter create a visibility related only to that type itself. In order to make this really useful, attribute functions would be needed to forestall the use of an entire package, rather than only a single type. If this seems abstruse, just consider the character traits that the C+ + standard library uses. And a related historical question: Why does the prefixed view of a subprogram only apply to tagged types? It seems like a syntax eminently suited for any subprogram. An attribute function must evaluate at compile-time, or perhaps more subtly, prior to elaboration time. Much of the requisite apparatus is already present with static expressions and preelaborable packages. The standard would require an additional definition of the ability to pre-elaborate a function body. While such a body might be restricted to returning a single static expression, that seem a bit restrictive. My overall motivation (as before) is to enable better, more flexible library support. Library support gates usability and enables cost- justifiable selection of Ada in a greater number of application domains. These kinds of features are not so critical for a single team writing their own software, but rather come into their own when writing libraries for other people to use in not-yet-anticipated ways. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-12 18:58 User-defined type attributes Eric Hughes @ 2008-03-12 21:23 ` Dmitry A. Kazakov 2008-03-13 18:32 ` Eric Hughes 2008-03-14 1:46 ` Randy Brukardt 1 sibling, 1 reply; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-12 21:23 UTC (permalink / raw) On Wed, 12 Mar 2008 11:58:29 -0700 (PDT), Eric Hughes wrote: > An attribute function must evaluate at compile-time, or perhaps more > subtly, prior to elaboration time. Much of the requisite apparatus is > already present with static expressions and preelaborable packages. > The standard would require an additional definition of the ability to > pre-elaborate a function body. While such a body might be restricted > to returning a single static expression, that seem a bit restrictive. Attributes in Ada aren't necessarily static, even type's attributes aren't. To me static functions is an independent, yet important issue. In my view attributes should be primitive operations. I would handle them similarly to prefix notation. I.e. X(Y,Z), Y.X(Z), Y'X(Z) considered equivalent. When applied to types, that should be treated just as a parameter of the type Tag. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-12 21:23 ` Dmitry A. Kazakov @ 2008-03-13 18:32 ` Eric Hughes 2008-03-13 19:58 ` Dmitry A. Kazakov 0 siblings, 1 reply; 29+ messages in thread From: Eric Hughes @ 2008-03-13 18:32 UTC (permalink / raw) On Mar 12, 3:23 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > Attributes in Ada aren't necessarily static, even type's attributes aren't. > To me static functions is an independent, yet important issue. Most attributes are completely static. The ones that aren't (like T'Callable, E'Caller) seem all to be of a kind that (1) statically return a function (2) whose first parameter is the type of the object, and then (3) apply it to that object. Given that this is at least in the spirit of a preelaborable attribute, there's the possibility of treating these cases as syntactic shorthand: Obj'Attr for Obj'Attr( Obj ), or alternately for Obj.Obj'Attr. I did a brief scan of ARM05/Annex-K just now, and this applies to all the cases I found (which were all tasking or type attributes). So I'll modify my idea to deal with historical syntax: 1) The definition of an attribute function has a static expression. 2) The syntax for invoking an attribute may imply a dynamic function call. Such implicit calls generate a syntax ambiguity between "attribute procedure Op( X : T )" and "attribute procedure Op( X : T ; Y : T )" when invoking with only positional parameters. What would Obj'Op( Obj ) mean? I assume this can be adequately addressed. > In my view attributes should be primitive operations. I would handle them > similarly to prefix notation. I.e. X(Y,Z), Y.X(Z), Y'X(Z) considered > equivalent. The whole point of user attributes is to gain cleaner syntax for referring to the environment of a type or object, that which is available at pre-elaboration time, and supports generic programming better. Without such a syntax there are lots more formal parameters that need to be forwarded around. Just making attributes run-time functions eliminates a useful distinction. Functions on a type are part of the tradition algebraic specification of a type. Attributes on a type are part of the language environment inside of which a type specification is expressed. These are very different. > When applied to types, that should be treated just as a > parameter of the type Tag. That seems like the right way to treat the first parameter of an implicit function call for an attribute on a type. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-13 18:32 ` Eric Hughes @ 2008-03-13 19:58 ` Dmitry A. Kazakov 2008-03-14 1:46 ` Randy Brukardt ` (3 more replies) 0 siblings, 4 replies; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-13 19:58 UTC (permalink / raw) On Thu, 13 Mar 2008 11:32:23 -0700 (PDT), Eric Hughes wrote: > On Mar 12, 3:23 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> > wrote: >> Attributes in Ada aren't necessarily static, even type's attributes aren't. >> To me static functions is an independent, yet important issue. > > Most attributes are completely static. The ones that aren't (like > T'Callable, E'Caller) seem all to be of a kind that (1) statically > return a function (2) whose first parameter is the type of the object, > and then (3) apply it to that object. In which sense function is static? If understand what you wrote, it simply means that the name "Callable" is static. Yes it is. > Given that this is at least in > the spirit of a preelaborable attribute, there's the possibility of > treating these cases as syntactic shorthand: Obj'Attr for > Obj'Attr( Obj ), or alternately for Obj.Obj'Attr. Yes, as well as, Attr (Obj), which would be IMO a better way. I think everybody is tired writing Integer'Image(X) rather than X'Image. > I did a brief scan > of ARM05/Annex-K just now, and this applies to all the cases I found > (which were all tasking or type attributes). Nevertheless the result is not static, thus it cannot be used, say, in a declaration of a modular type. I consider this issue as fully independent. We need static functions beyond attributes. Consider pattern matching: loop if Match (Text, Pattern ("*.ada")) then there is no way to define Pattern in a way that would force the compiler to translate "*.ada" at compile time. > So I'll modify my idea to deal with historical syntax: > 1) The definition of an attribute function has a static expression. > 2) The syntax for invoking an attribute may imply a dynamic function > call. > > Such implicit calls generate a syntax ambiguity between "attribute > procedure Op( X : T )" and "attribute procedure Op( X : T ; Y : T )" > when invoking with only positional parameters. What would > Obj'Op( Obj ) mean? I assume this can be adequately addressed. > >> In my view attributes should be primitive operations. I would handle them >> similarly to prefix notation. I.e. X(Y,Z), Y.X(Z), Y'X(Z) considered >> equivalent. > > The whole point of user attributes is to gain cleaner syntax for > referring to the environment of a type or object, that which is > available at pre-elaboration time, and supports generic programming > better. Without such a syntax there are lots more formal parameters > that need to be forwarded around. Why? The only thing you need is formal generic ADTs. Ada's generics lack ADTs, which is the reason why you need to pass operations together with the formal types. There exist formal built-in types like "private", "<>", "digits <>" etc, but there is no user-defined ones. Add these and all primitive operations will go with the actual type just per magic. It would be IMO a natural step for anybody who wanted generics to evolve in an Ada-way. (Not for me, as you know, I prefer generics removed from the language.) > Just making attributes run-time functions eliminates a useful > distinction. Functions on a type are part of the tradition algebraic > specification of a type. Attributes on a type are part of the > language environment inside of which a type specification is > expressed. These are very different. I don't see why this distinction is important. Anyway it leaks, because you certainly need constrained types in the types algebra. This brings discriminants with it. Do you want to introduce attributes for the discriminants of a subtype? Like X'Tag? which is of course merely a discriminant. I think it would be an overkill. Then what would you do with 'Pos, 'Succ, 'Adjacent etc attributes which have nothing to do with types algebra? In my view this distinction just does not hold since Ada 95, because that introduced user-defined classes. In my view attributes in Ada 83 meant mere "magical things", meta-subprograms which profiles cannot be spelt in the language. This has changed, we can spell most of them now as proper primitive subprograms. More elaborated class model of Ada will become less "magical things" will remain. I think now X'Y notation should be considered as pure syntax sugar, with no semantics. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-13 19:58 ` Dmitry A. Kazakov @ 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 1:46 ` Randy Brukardt ` (2 subsequent siblings) 3 siblings, 0 replies; 29+ messages in thread From: Randy Brukardt @ 2008-03-14 1:46 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:965suhjl0bxt$.74se2ylyksin.dlg@40tude.net... ... > Why? The only thing you need is formal generic ADTs. Ada's generics lack > ADTs, which is the reason why you need to pass operations together with the > formal types. There exist formal built-in types like "private", "<>", > "digits <>" etc, but there is no user-defined ones. Add these and all > primitive operations will go with the actual type just per magic. It would > be IMO a natural step for anybody who wanted generics to evolve in an > Ada-way. (Not for me, as you know, I prefer generics removed from the > language.) Generic formal derived types are the way to bring an ADT into a generic. After all, they do bring in all of the primitive operations of the ADT. The only problem is that they can't be used on unrelated types, but that's not very relevant if you are using tagged types (and you might as well being doing so if you're defining any sort of composite type). Randy. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-13 19:58 ` Dmitry A. Kazakov 2008-03-14 1:46 ` Randy Brukardt @ 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 3:55 ` User-defined type attributes Eric Hughes 3 siblings, 0 replies; 29+ messages in thread From: Randy Brukardt @ 2008-03-14 1:46 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:965suhjl0bxt$.74se2ylyksin.dlg@40tude.net... ... > Why? The only thing you need is formal generic ADTs. Ada's generics lack > ADTs, which is the reason why you need to pass operations together with the > formal types. There exist formal built-in types like "private", "<>", > "digits <>" etc, but there is no user-defined ones. Add these and all > primitive operations will go with the actual type just per magic. It would > be IMO a natural step for anybody who wanted generics to evolve in an > Ada-way. (Not for me, as you know, I prefer generics removed from the > language.) Generic formal derived types are the way to bring an ADT into a generic. After all, they do bring in all of the primitive operations of the ADT. The only problem is that they can't be used on unrelated types, but that's not very relevant if you are using tagged types (and you might as well being doing so if you're defining any sort of composite type). Randy. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-13 19:58 ` Dmitry A. Kazakov 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 1:46 ` Randy Brukardt @ 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 9:00 ` Dmitry A. Kazakov 2008-03-14 14:31 ` User-defined type attributes (replacing genericity) Georg Bauhaus 2008-03-14 3:55 ` User-defined type attributes Eric Hughes 3 siblings, 2 replies; 29+ messages in thread From: Randy Brukardt @ 2008-03-14 1:46 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:965suhjl0bxt$.74se2ylyksin.dlg@40tude.net... ... > Why? The only thing you need is formal generic ADTs. Ada's generics lack > ADTs, which is the reason why you need to pass operations together with the > formal types. There exist formal built-in types like "private", "<>", > "digits <>" etc, but there is no user-defined ones. Add these and all > primitive operations will go with the actual type just per magic. It would > be IMO a natural step for anybody who wanted generics to evolve in an > Ada-way. (Not for me, as you know, I prefer generics removed from the > language.) Generic formal derived types are the way to bring an ADT into a generic. After all, they do bring in all of the primitive operations of the ADT. The only problem is that they can't be used on unrelated types, but that's not very relevant if you are using tagged types (and you might as well being doing so if you're defining any sort of composite type). Randy. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-14 1:46 ` Randy Brukardt @ 2008-03-14 9:00 ` Dmitry A. Kazakov 2008-03-14 14:36 ` User-defined type attributes (replacing genericity) Georg Bauhaus 2008-03-15 3:04 ` User-defined type attributes Randy Brukardt 2008-03-14 14:31 ` User-defined type attributes (replacing genericity) Georg Bauhaus 1 sibling, 2 replies; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-14 9:00 UTC (permalink / raw) On Thu, 13 Mar 2008 20:46:41 -0500, Randy Brukardt wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > news:965suhjl0bxt$.74se2ylyksin.dlg@40tude.net... > ... >> Why? The only thing you need is formal generic ADTs. Ada's generics lack >> ADTs, which is the reason why you need to pass operations together with the >> formal types. There exist formal built-in types like "private", "<>", >> "digits <>" etc, but there is no user-defined ones. Add these and all >> primitive operations will go with the actual type just per magic. It would >> be IMO a natural step for anybody who wanted generics to evolve in an >> Ada-way. (Not for me, as you know, I prefer generics removed from the >> language.) > > Generic formal derived types are the way to bring an ADT into a generic. > After all, they do bring in all of the primitive operations of the ADT. > > The only problem is that they can't be used on unrelated types, but that's > not very relevant if you are using tagged types (and you might as well being > doing so if you're defining any sort of composite type). Right, but this also implies that there is no need to have generics at all. A class-wide object does all what needed: generic type S is new T with private; procedure Foo (X : in out S); can be replaced by: procedure Foo (X : in out T'Class); -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 9:00 ` Dmitry A. Kazakov @ 2008-03-14 14:36 ` Georg Bauhaus 2008-03-15 3:04 ` User-defined type attributes Randy Brukardt 1 sibling, 0 replies; 29+ messages in thread From: Georg Bauhaus @ 2008-03-14 14:36 UTC (permalink / raw) On Fri, 2008-03-14 at 15:31 +0100, Georg Bauhaus wrote: > Without generics, there is only one Is_Highest, as might be > expected. <Important-addendum> A really general Is_Highest, even when looking at the disassembly. There are computed addresses, indirect references all over the listing, everything purely mechanical, no trace of anything concrete. And not fast.</> ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-14 9:00 ` Dmitry A. Kazakov 2008-03-14 14:36 ` User-defined type attributes (replacing genericity) Georg Bauhaus @ 2008-03-15 3:04 ` Randy Brukardt 2008-03-15 9:33 ` Dmitry A. Kazakov 1 sibling, 1 reply; 29+ messages in thread From: Randy Brukardt @ 2008-03-15 3:04 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:pqup5kf1u34t$.19kwms4bw12hs.dlg@40tude.net... > On Thu, 13 Mar 2008 20:46:41 -0500, Randy Brukardt wrote: > > > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > > news:965suhjl0bxt$.74se2ylyksin.dlg@40tude.net... > > ... > >> Why? The only thing you need is formal generic ADTs. Ada's generics lack > >> ADTs, which is the reason why you need to pass operations together with the > >> formal types. There exist formal built-in types like "private", "<>", > >> "digits <>" etc, but there is no user-defined ones. Add these and all > >> primitive operations will go with the actual type just per magic. It would > >> be IMO a natural step for anybody who wanted generics to evolve in an > >> Ada-way. (Not for me, as you know, I prefer generics removed from the > >> language.) > > > > Generic formal derived types are the way to bring an ADT into a generic. > > After all, they do bring in all of the primitive operations of the ADT. > > > > The only problem is that they can't be used on unrelated types, but that's > > not very relevant if you are using tagged types (and you might as well being > > doing so if you're defining any sort of composite type). > > Right, but this also implies that there is no need to have generics at all. > A class-wide object does all what needed: > > generic > type S is new T with private; > procedure Foo (X : in out S); > > can be replaced by: > > procedure Foo (X : in out T'Class); Not if you need other generic parameters along with the type. And this is a way to do mixins, which otherwise can't be done in Ada 95 because type can't derive from a class-wide type: generic type S is new T with private; package Foo is type New_S is new S with private; procedure New_Operation (Op : in out New_S); end Foo; It's a nice way to add persistence, for instance. (Interfaces only allow you to add, umm, interfaces, not code.) Randy. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-15 3:04 ` User-defined type attributes Randy Brukardt @ 2008-03-15 9:33 ` Dmitry A. Kazakov 0 siblings, 0 replies; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-15 9:33 UTC (permalink / raw) On Fri, 14 Mar 2008 22:04:53 -0500, Randy Brukardt wrote: > Not if you need other generic parameters along with the type. And this is a > way to do mixins, which otherwise can't be done in Ada 95 because type can't > derive from a class-wide type: > > generic > type S is new T with private; > package Foo is > type New_S is new S with private; > procedure New_Operation (Op : in out New_S); > end Foo; > > It's a nice way to add persistence, for instance. (Interfaces only allow you > to add, umm, interfaces, not code.) Speaking of language enhancements proper multiple inheritance would be a better way to do this. But actually I would like to have "supertypes" in order to be able to add interfaces and code to existing types: type T is ...; -- Defined independently on Persistent type Persistent is abstract...; -- Oops, we forgot to do it before T type Bridge is new Persistent and old T; --- (:-)) Bridge is a subtype of Persistent and a supertype of T. This injects Bridge's implementation of Persistent into T within Bridge's scope. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 9:00 ` Dmitry A. Kazakov @ 2008-03-14 14:31 ` Georg Bauhaus 2008-03-14 14:48 ` Dmitry A. Kazakov 2008-03-14 16:58 ` Georg Bauhaus 1 sibling, 2 replies; 29+ messages in thread From: Georg Bauhaus @ 2008-03-14 14:31 UTC (permalink / raw) On Fri, 2008-03-14 at 10:00 +0100, Dmitry A. Kazakov wrote: > Right, but this also implies that there is no need to have generics at all. > A class-wide object does all what needed: > > generic > type S is new T with private; > procedure Foo (X : in out S); > > can be replaced by: > > procedure Foo (X : in out T'Class); I assume your answer to what follows will be that Ada semantics should be put under programmer control, that range should be and interface type, etc. ;-) But anyway, even that doesn't change things. I just looked at the effects. Not promising on two accounts, but more rattling regularity. Which might have its place. Replacing genericity means every generic instance is replaced with an invocation of just one procedure. However, for objects of specially crafted types. One type needs to be available for mimicking each generic. I had two types type Simple is range 1 .. 100; -- predefined "<=" type Data is record amount: Natural; wpi: Float; end record; function "<="(a, b: Data) return Boolean; According to the suggestion to abandon generics I have had instead, basically, procedure Foo (X, Y, Z : in out T'Class) is function Is_Highest(V: T) return Boolean is begin return X <= V and then Y <= V and then Z <= V; end Is_Highest; begin ... The comparison function "<=" needs to be one of the primitive operations of all types in T'Class. (Hence a wrapper type becomes necessary for range type Simple.) (I'll leave out the problem of local variables of type T'Class.) (I'll leave out required variance programming work, too.) With generics, I got two nicely specialized instances of Foo, one for the range type, the other for the composite type. The effect is that function Is_Highest will use "<=" as I would expect for a range type. Small code, obvious, and efficient. Similarly, the "<=" of the Data instance's Is_Highest function corresponds directly to both the definition and to the expectation. Without generics, there is only one Is_Highest, as might be expected. Inlining did not help. In fact, I wouldn't expect inlining to be readily available with 'Class---unless of course replacing generics should also entail compilers that look at the entire program. Then, maybe, a few more thing can be "optimized" at compile time. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 14:31 ` User-defined type attributes (replacing genericity) Georg Bauhaus @ 2008-03-14 14:48 ` Dmitry A. Kazakov 2008-03-14 17:51 ` Eric Hughes 2008-03-14 16:58 ` Georg Bauhaus 1 sibling, 1 reply; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-14 14:48 UTC (permalink / raw) On Fri, 14 Mar 2008 15:31:40 +0100, Georg Bauhaus wrote: > On Fri, 2008-03-14 at 10:00 +0100, Dmitry A. Kazakov wrote: > >> Right, but this also implies that there is no need to have generics at all. >> A class-wide object does all what needed: >> >> generic >> type S is new T with private; >> procedure Foo (X : in out S); >> >> can be replaced by: >> >> procedure Foo (X : in out T'Class); > > I assume your answer to what follows will be that Ada semantics > should be put under programmer control, What's wrong with having control over the semantics? > that range should be and interface type, etc. ;-) Shouldn't it? > But anyway, even that doesn't change things. > > I just looked at the effects. Not promising on two accounts, > but more rattling regularity. Which might have its place. > > Replacing genericity means every generic instance is replaced > with an invocation of just one procedure. No, only calls to instances of generic bodies. > However, for objects of > specially crafted types. One type needs to be available for > mimicking each generic. > > I had two types > > type Simple is range 1 .. 100; > -- predefined "<=" > > type Data is record > amount: Natural; > wpi: Float; > end record; > > function "<="(a, b: Data) return Boolean; > > According to the suggestion to abandon generics I have had instead, > basically, > > procedure Foo (X, Y, Z : in out T'Class) is > function Is_Highest(V: T) return Boolean is > begin > return X <= V and then Y <= V and then Z <= V; > end Is_Highest; > begin > ... > > The comparison function "<=" needs to be one of the primitive > operations of all types in T'Class. (Hence a wrapper type becomes > necessary for range type Simple.) No, what you need is an interface implemented by both. You need to declare Simple implementing Ordered. That will tell the compiler that the predefined "<=" is an implementation of Ordered's "<=". > (I'll leave out the problem of local variables of type T'Class.) > (I'll leave out required variance programming work, too.) > > With generics, I got two nicely specialized instances of Foo, > one for the range type, the other for the composite type. > The effect is that function Is_Highest will use "<=" as I > would expect for a range type. Small code, obvious, and > efficient. Similarly, the "<=" of the Data instance's > Is_Highest function corresponds directly to both the definition > and to the expectation. > > Without generics, there is only one Is_Highest, as might be > expected. Why there have to be two? The whole idea of generics was to have *one* generic body. This is why it is called generic [programming]. > Inlining did not help. In fact, I wouldn't expect inlining to be > readily available with 'Class---unless of course > replacing generics should also entail compilers that look at > the entire program. Then, maybe, a few more thing can be > "optimized" at compile time. You mixing two different problems. BTW, I answered both in my earlier posts. So I repeat it short. If you want to constrain the dispatching table to the diagonal you do it procedure Foo (X, Y, Z : in out T) This requires X, Y, Z to have exactly same type. The language of constraints is a different theme. Do not sell a limitation of generics to a certain type of constraint as genuine advantage. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 14:48 ` Dmitry A. Kazakov @ 2008-03-14 17:51 ` Eric Hughes 2008-03-14 18:58 ` Dmitry A. Kazakov 2008-03-15 4:01 ` Randy Brukardt 0 siblings, 2 replies; 29+ messages in thread From: Eric Hughes @ 2008-03-14 17:51 UTC (permalink / raw) On Fri, 14 Mar 2008 15:31:40 +0100, Georg Bauhaus wrote: > Without generics, there is only one Is_Highest, as might be > expected. On Mar 14, 8:48 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > Why there have to be two? The whole idea of generics was to have *one* > generic body. This is why it is called generic [programming]. Here's the nut of the problem. There is one generic body in the code of the programming language. When you substitute type parameters into that generic body, you get multiple different manifestations of that original generic body, that is, multiple bodies, one for each type. And that means multiple versions as translated into machine code. This is indeed the primary desideratum of generic programming. Having said this, there's a standard technique of converting type operations into virtual function calls. I feel like I need to say this--these aren't the same thing. This allows the reduction of the manifestation a generic body to a single canonical form. This has a single version in machine code. A realistic system for generic programming should support both modes of code generation. This allows the developer to determine their own answer to the code-size vs. performance trade-off. Ada has already taken the stance, as evidenced by representation clauses, that it will support both high and low levels of abstraction. Eliminating generics would force everything into virtual function calls, choose code-size over performance, and make that choice on behalf of every programmer. If you go down the road of requiring all method calls to be virtual, of requiring that there be run-time manifestations of all meta- language features, you get Java. Java has its place. So does Ada. These aren't the same place. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 17:51 ` Eric Hughes @ 2008-03-14 18:58 ` Dmitry A. Kazakov 2008-03-14 20:19 ` Eric Hughes 2008-03-15 4:01 ` Randy Brukardt 1 sibling, 1 reply; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-14 18:58 UTC (permalink / raw) On Fri, 14 Mar 2008 10:51:25 -0700 (PDT), Eric Hughes wrote: > On Fri, 14 Mar 2008 15:31:40 +0100, Georg Bauhaus wrote: >> Without generics, there is only one Is_Highest, as might be >> expected. > > On Mar 14, 8:48 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> > wrote: >> Why there have to be two? The whole idea of generics was to have *one* >> generic body. This is why it is called generic [programming]. > > Here's the nut of the problem. There is one generic body in the code > of the programming language. When you substitute type parameters into > that generic body, you get multiple different manifestations of that > original generic body, that is, multiple bodies, one for each type. > And that means multiple versions as translated into machine code. No, Ada is not like that. In fact much efforts, at least in Ada 83, was paid in order to allow sharing of generic bodies. AFAIK, Janus Ada shares them. > This is indeed the primary desideratum of generic programming. Having > said this, there's a standard technique of converting type operations > into virtual function calls. I feel like I need to say this--these > aren't the same thing. This allows the reduction of the manifestation > a generic body to a single canonical form. This has a single version > in machine code. It is optimization technique. You could instruct the compiler to inline a class-wide body. You could require to generate a separate instance for each used combination of argument types. Semantically the body is still same. > A realistic system for generic programming should support both modes > of code generation. This allows the developer to determine their own > answer to the code-size vs. performance trade-off. Ada has already > taken the stance, as evidenced by representation clauses, that it will > support both high and low levels of abstraction. If that were true it would be a premature optimization. Anyway semantically there is no any difference between generic and class-wide bodies. Both act on a class of types. To be honest, there are formal generic parameters beyond types: 1. Formal objects. These are not required and covered by plain functions. Normally they are used to work around language limitations, usually in types algebra, which is the weak point. 2. Formal packages. This looks like a useful thing, but child packages and better classes might make them superfluous. > Eliminating generics > would force everything into virtual function calls, choose code-size > over performance, and make that choice on behalf of every programmer. > If you go down the road of requiring all method calls to be virtual, Note that class-wide bodies do not dispatch. > of requiring that there be run-time manifestations of all meta- > language features, you get Java. Java has its place. So does Ada. > These aren't the same place. Similarly I could argue that Ada generics (at least as you an George describe them) is a preprocessor. There are many. Right, they are poorly designed, untyped etc. But who said that Java was designed properly? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 18:58 ` Dmitry A. Kazakov @ 2008-03-14 20:19 ` Eric Hughes 0 siblings, 0 replies; 29+ messages in thread From: Eric Hughes @ 2008-03-14 20:19 UTC (permalink / raw) On Mar 14, 12:58 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > Anyway semantically > there is no any difference between generic and class-wide bodies. Both act > on a class of types. Not every similarity between types is also a class-wide similarity. Without this essential distinction, I cannot begin to have a useful discussion about generics. I'm out. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 17:51 ` Eric Hughes 2008-03-14 18:58 ` Dmitry A. Kazakov @ 2008-03-15 4:01 ` Randy Brukardt 1 sibling, 0 replies; 29+ messages in thread From: Randy Brukardt @ 2008-03-15 4:01 UTC (permalink / raw) "Eric Hughes" <eric.eh9@gmail.com> wrote in message news:821256cd-2d20-46dd-92d2-cdd21181dbb8@s8g2000prg.googlegroups.com... > On Mar 14, 8:48 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> > wrote: > > Why there have to be two? The whole idea of generics was to have *one* > > generic body. This is why it is called generic [programming]. > > Here's the nut of the problem. There is one generic body in the code > of the programming language. When you substitute type parameters into > that generic body, you get multiple different manifestations of that > original generic body, that is, multiple bodies, one for each type. > And that means multiple versions as translated into machine code. That has nothing whatsoever to do with Ada. Most Ada implementations work that way, but there is no requirement that they do. Indeed, there are a lot of rules in Ada specifically to allow the sharing of generic bodies. A number of Ada 83 compilers used to do it as a matter of course; Janus/Ada is the only one that I know that still does for Ada 95 and later. This sort of performance is best handled by inlining, IMHO. It's virtually impossible to share something that is generated separately (I know, I did that extensively to shoehorn our compilers onto Z80s back in the dark ages); it's a lot easier to "unshare" something that is shared than the reverse. Janus/Ada was designed around this plan; unfortunately, circumstances (and the underpowered machines of the late 1980's and early 1990's) meant that the inlining linker never got built. It actually wouldn't be all that much work (I think a couple of man-months), but it is still too much to tackle at the moment. > A realistic system for generic programming should support both modes > of code generation. This allows the developer to determine their own > answer to the code-size vs. performance trade-off. Actually, much of the time the compiler has a pretty good idea. All it needs are some hints. This is one thing that Java compilers have over Ada ones, because the Java program usually already has been running a while before it is compiled, so the areas that need to be concentrated on for speed are known. In any case, 95% of programs are fast enough without any fancy optimization. And 4% of the rest don't need much. Most people spend way too much time worrying about the last 1% (probably because it is more interesting than getting work done -- just like answering your note is. ;-) > Ada has already taken the stance, as evidenced by representation clauses, > that it will support both high and low levels of abstraction. Eliminating generics > would force everything into virtual function calls, choose code-size > over performance, and make that choice on behalf of every programmer. Yup, and that probably would be the right choice most of the time. Moreover, there is no problem using static binding, partial evaluation, and inlining to get rid of the majority of the virtual overhead. Remember, Ada statically binds calls to tagged types; it's pretty hard to write dispatching calls. (I know of a number of bugs in that area in Janus/Ada, yet no one has yet written a program that has hit any of them. Or at least they've never reported them. Obviously, they're not that high of a priority to get fixed...) > If you go down the road of requiring all method calls to be virtual, > of requiring that there be run-time manifestations of all meta- > language features, you get Java. Java has its place. So does Ada. > These aren't the same place. How you compile makes all the difference. The language doesn't make that much (it does make some), as long as there is reasonably strong typing so that calls can be statically bound. But I realize few people agree with me on this; had we actually been able to build the entire compiler system that we had envisioned (with C and Ada front-ends, and three backends: checkout interpreter, conventional fast compiler, and highly optimizing link-time compiler) I suspect that either a lot more people would agree or no one (including me) would. Randy. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 14:31 ` User-defined type attributes (replacing genericity) Georg Bauhaus 2008-03-14 14:48 ` Dmitry A. Kazakov @ 2008-03-14 16:58 ` Georg Bauhaus 2008-03-14 18:39 ` Dmitry A. Kazakov 1 sibling, 1 reply; 29+ messages in thread From: Georg Bauhaus @ 2008-03-14 16:58 UTC (permalink / raw) On Fri, 2008-03-14 at 15:48 +0100, Dmitry A. Kazakov wrote: > > I assume your answer to what follows will be that Ada semantics > > should be put under programmer control, > > What's wrong with having control over the semantics? (Control over the semantics of the language. I'm not a compiler, and I'm not imagining I am as good as someone who can routinely master the advanced parts of implementing Ada in user programs. That is what I think will be wrong. It is certainly possible to imagine some meta-flavoring for Ada. But I don't want to inspect such pieces of sophistication when they come out of the hands of ordinary programmers and have errors. There will be at least one more level of linguistic indirection between me and the LRM: the programmer's language interpretation as implemented in his semantics control.) > No, what you need is an interface implemented by both. You need to declare > Simple implementing Ordered. That will tell the compiler that the > predefined "<=" is an implementation of Ordered's "<=". Actually, it doesn't matter whether "<=" is predefined. It could just as well have been a user defined "<=". The Foo(...'Class) would have had one one general ("generic"?) implementation of Is_Highest, as described. This Is_Highest will have no specialization, but it will feature highly stylized indirection, dispatching to the implementing code for the respective "<=". > > Without generics, there is only one Is_Highest, as might be > > expected. > > Why there have to be two? The whole idea of generics was to have *one* > generic body. This is why it is called generic [programming]. I *can* have and I *did* have just one body in *source* code. We both know that Ada does not anywhere require that generics must not yield more than one lists of object code per generic. This would seem like a stupid restriction, one that I think no one has wanted to put in the minds of the language makers. > If you want to constrain the dispatching table > to the diagonal I don't want that language to inflict a dispatching table on me when that offers no advantage at all! - I don't need any dispatching here, - My code is more efficient without it, - Review of the generated code is simpler because there are fewer indirections. - There still is abstraction. If that doesn't count as advantages ... > Do not sell a limitation of generics to a > certain type of constraint as genuine advantage. >From looking at generated code, the genuine advantage seems to be the total absence of dispatching code. Absence of code whose major contribution can, by the impression of the assembly listing, roughly be expressed as X.all.Call_Maker.all.Invoke instead of X.all.Call in the generic case ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 16:58 ` Georg Bauhaus @ 2008-03-14 18:39 ` Dmitry A. Kazakov 2008-03-15 9:39 ` Dmitry A. Kazakov 0 siblings, 1 reply; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-14 18:39 UTC (permalink / raw) On Fri, 14 Mar 2008 17:58:46 +0100, Georg Bauhaus wrote: > On Fri, 2008-03-14 at 15:48 +0100, Dmitry A. Kazakov wrote: > >>> I assume your answer to what follows will be that Ada semantics >>> should be put under programmer control, >> >> What's wrong with having control over the semantics? > > (Control over the semantics of the language. I'm not a compiler, > and I'm not imagining I am as good as someone who can routinely > master the advanced parts of implementing Ada in user programs. > That is what I think will be wrong. But the compiler is in an even worse position. It cannot know your intent when you introduce a new operation, type, object etc. It is up to you to define the semantics of. > It is certainly possible to imagine some meta-flavoring for > Ada. But I don't want to inspect such pieces of sophistication > when they come out of the hands of ordinary programmers > and have errors. There will be at least one more > level of linguistic indirection between me and the LRM: > the programmer's language interpretation as implemented in > his semantics control.) Sorry, but it is generics which constitute a meta language, so this argument you should address to yourself. Further, it seems that you believe that Ada defines some meta-level semantics of attributes and operations like "+", "-", etc. But, it does not. You can define "+" to perform multiplication or to act on tasks. BUT, if you wanted to do that (I don't), then again the first step should be away from generics, towards proper classes. For example, to define a class of additive objects and to forbid use of "+" for anything outside the class. >> No, what you need is an interface implemented by both. You need to declare >> Simple implementing Ordered. That will tell the compiler that the >> predefined "<=" is an implementation of Ordered's "<=". > > Actually, it doesn't matter whether "<=" is predefined. It could > just as well have been a user defined "<=". The Foo(...'Class) would > have had one one general ("generic"?) implementation of Is_Highest, > as described. This Is_Highest will have no specialization, but > it will feature highly stylized indirection, dispatching to the > implementing code for the respective "<=". In fact, your code will not compile. It should be: function Is_Highest (V: T'Class) return Boolean is begin return X <= V and then Y <= V and then Z <= V; end Is_Highest; So what was the problem? >>> Without generics, there is only one Is_Highest, as might be >>> expected. >> >> Why there have to be two? The whole idea of generics was to have *one* >> generic body. This is why it is called generic [programming]. > > I *can* have and I *did* have just one body in *source* code. Yes this is what I meant. > We both know that Ada does not anywhere require that generics > must not yield more than one lists of object code per > generic. This would seem like a stupid restriction, one that > I think no one has wanted to put in the minds of the language > makers. I didn't meant the implementation. Semantically there is one body even if instantiations expand it. >> If you want to constrain the dispatching table to the diagonal > > I don't want that language to inflict a dispatching table > on me when that offers no advantage at all! Dispatching table is not a physical object. It is a formal model to describe operations defined on a class. Such polymorphic operations have type-specific implementations (because the language is strongly typed). The dispatching table lists them according to the order relation (subtyping) of the types of the arguments. How and if to implement it is up to the compiler. > - I don't need any dispatching here, You have to. Dispatch is a selection of a type-specific body responsible for the implementation of a generic (polymorphic) one for the given combination of argument types. When you instantiate a generic body it is an act of dispatching, performed manually. > - My code is more efficient without it, It is not Ada's objective. Then with statically known types and inlined bodies you could have the same code GNAT generics produce. > - Review of the generated code is simpler because > there are fewer indirections. I never review generated code. I wrote large (then) programs about 20K SLOC, now I am using Ada, I don't want back. > - There still is abstraction. Where? In the object code? >> Do not sell a limitation of generics to a >> certain type of constraint as genuine advantage. > > From looking at generated code, the genuine advantage seems > to be the total absence of dispatching code. You don't need any code when dispatch is static. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes (replacing genericity) 2008-03-14 18:39 ` Dmitry A. Kazakov @ 2008-03-15 9:39 ` Dmitry A. Kazakov 0 siblings, 0 replies; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-15 9:39 UTC (permalink / raw) On Fri, 14 Mar 2008 19:39:57 +0100, Dmitry A. Kazakov wrote: > I never review generated code. I wrote large (then) programs about 20K > SLOC, in assembler, I mean. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-13 19:58 ` Dmitry A. Kazakov ` (2 preceding siblings ...) 2008-03-14 1:46 ` Randy Brukardt @ 2008-03-14 3:55 ` Eric Hughes 2008-03-14 9:01 ` Dmitry A. Kazakov 3 siblings, 1 reply; 29+ messages in thread From: Eric Hughes @ 2008-03-14 3:55 UTC (permalink / raw) On Mar 13, 1:58 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > In which sense function is static? If understand what you wrote, it simply > means that the name "Callable" is static. That's not what I meant. Here's some sample notation, whose syntax is merely illustrative. -- Declaration of an attribute generic task type T ; function T'Callable return boolean ; -- Declaration of a (static) implementation function generic task type T ; function Callable_Impl return access function( X : T ) return boolean is static ; -- Binding of an implementation to an attribute generic task type T ; Obj : T ; for Obj'Callable use Callable_Impl.all( X => Obj ) ; Regardless of whatever syntax is appropriate, one of the things that makes me uncomfortable about attributes is that their definitions don't have the same rigor of notation in their definitions as, say, the standard libraries do. In the spirit of separation compilation, I'd like to see attribute definitions in specification packages, even if their bodies exist solely within a compiler's implementation. I wrote: > Functions on a type are part of the tradition algebraic > specification of a type. Attributes on a type are part of the > language environment inside of which a type specification is > expressed. These are very different. "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > I don't see why this distinction is important. I'm afraid I don't know how to argue this point briefly. It's the difference between language (in the proof theory sense) and metalanguage. I guess I've done too much formal logic too see this distinction and its import as anything other than obvious. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-14 3:55 ` User-defined type attributes Eric Hughes @ 2008-03-14 9:01 ` Dmitry A. Kazakov 2008-03-14 18:04 ` Eric Hughes 0 siblings, 1 reply; 29+ messages in thread From: Dmitry A. Kazakov @ 2008-03-14 9:01 UTC (permalink / raw) On Thu, 13 Mar 2008 20:55:27 -0700 (PDT), Eric Hughes wrote: > On Mar 13, 1:58 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> > wrote: >> In which sense function is static? If understand what you wrote, it simply >> means that the name "Callable" is static. > > That's not what I meant. Here's some sample notation, whose syntax is > merely illustrative. > > -- Declaration of an attribute > generic > task type T ; > function T'Callable return boolean ; > > -- Declaration of a (static) implementation function > generic > task type T ; > function Callable_Impl return access function( X : T ) return > boolean is static ; Hmm, what is static here? An instance of the body or the result of execution of an instance? Let I declare T in a nested block, then instantiate Callable_Impl there, would it go? > -- Binding of an implementation to an attribute > generic > task type T ; > Obj : T ; > for Obj'Callable use Callable_Impl.all( X => Obj ) ; > > Regardless of whatever syntax is appropriate, one of the things that > makes me uncomfortable about attributes is that their definitions > don't have the same rigor of notation in their definitions as, say, > the standard libraries do. Right, because to make it rigorously you have to make "task type" a proper class. That means, tasks must be tagged, there must be Root_Task type and a class of. Then you could simply and rigorously write: function "'Callable" (T : Root_Task) return Boolean; > In the spirit of separation compilation, > I'd like to see attribute definitions in specification packages, even > if their bodies exist solely within a compiler's implementation. Sure. Nevertheless this or that way you have to be able to specify that a body is static (contract on the implementation). That the body is pure (a permission to derive static result from static arguments). Or do you want compile-time bodies written in some other (meta) language, like they are in C and PL/1 preprocessors? > I wrote: >> Functions on a type are part of the tradition algebraic >> specification of a type. Attributes on a type are part of the >> language environment inside of which a type specification is >> expressed. These are very different. > > "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: >> I don't see why this distinction is important. > > I'm afraid I don't know how to argue this point briefly. It's the > difference between language (in the proof theory sense) and > metalanguage. I guess I've done too much formal logic too see this > distinction and its import as anything other than obvious. I see where you are going. It is to consider (some) attributes automatically instantiated generic functions. Am I right? That would be indeed a metalanguage. But I am quite uncomfortable with all three: metalanguage, generics as one, automatic instantiation. As you said, a metalanguage shall be clearly separated from the object one. This is the reason why generics are bad, they slip through the barrier and exist at run time. Similarly attributes inevitably will. IMO it would much "simpler" (and more useful): 1. to make classes available for all types 2. to introduce pure and static bodies 3. to allow "'X" sugar for user-defined subprograms 4. to specify existing attributes in terms of 1..3. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-14 9:01 ` Dmitry A. Kazakov @ 2008-03-14 18:04 ` Eric Hughes 0 siblings, 0 replies; 29+ messages in thread From: Eric Hughes @ 2008-03-14 18:04 UTC (permalink / raw) On Mar 14, 3:01 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > Right, because to make it rigorously you have to make "task type" a proper > class. That means, tasks must be tagged, there must be Root_Task type and a > class of. No, you don't. If your only conception of generic programming is to virtualize everything, then this statement would be true to you. But this conclusion rests upon an invalid premise about the nature of generic programming. > I see where you are going. It is to consider (some) attributes > automatically instantiated generic functions. Am I right? Basically correct. Yet I also mean generic functions in their full sense and not in the sense where they are instantiated merely with virtual function calls. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-12 18:58 User-defined type attributes Eric Hughes 2008-03-12 21:23 ` Dmitry A. Kazakov @ 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 4:41 ` Eric Hughes 1 sibling, 1 reply; 29+ messages in thread From: Randy Brukardt @ 2008-03-14 1:46 UTC (permalink / raw) "Eric Hughes" <eric.eh9@gmail.com> wrote in message news:d9065e94-8586-4889-b5c7-a8ca9e8f2248@d21g2000prf.googlegroups.com... ... > First, a historical question: Was there a proposal for user attributes > that was considered for Ada 2005? Not seriously. It had been rejected for Ada 95, and in general, we didn't want to rehash that old ground. ... > And a related historical question: Why does the prefixed view of a > subprogram only apply to tagged types? It seems like a syntax > eminently suited for any subprogram. There are ambiguity problems because "any type" includes access types. Recall that '.' in Ada always includes an implicit dereference (and the prefixed notation also supports the reverse, an implicit 'Access). That is, A.B(C); could mean B(A, C); or B(A.all, C); or B(A'access, C); The latter should not be allowed for untagged types (they're not implicitly aliased). But, also it would be possible for it to mean B(A.all.all, C); and B(A.all.all.all, C); and so on forever. That caused definitional and implementation problems. So we only allowed tagged types. That's OK, because only tagged types work "right" in Ada. There are a number of bizarre behaviors (one involves "=" of types with components, and another with the "reemergence" of predefined operations inside of a generic) that had to be retained from Ada 83 for compatibility reasons. These language mistakes are corrected with tagged types. Thus, I think virtually all new composite types should be tagged in Ada programs; you'll be a lot happier for it. Keep in mind that the only runtime overhead for a tagged object in Ada is the space for the tag and the time to fill it in on initialization; calls are statically bound unless you use T'Class somewhere. I usually go further and say all new types should be controlled (so as to get user-defined finalization), but that does have a small runtime overhead if not used. Randy. > An attribute function must evaluate at compile-time, or perhaps more > subtly, prior to elaboration time. Much of the requisite apparatus is > already present with static expressions and preelaborable packages. > The standard would require an additional definition of the ability to > pre-elaborate a function body. While such a body might be restricted > to returning a single static expression, that seem a bit restrictive. > > My overall motivation (as before) is to enable better, more flexible > library support. Library support gates usability and enables cost- > justifiable selection of Ada in a greater number of application > domains. These kinds of features are not so critical for a single > team writing their own software, but rather come into their own when > writing libraries for other people to use in not-yet-anticipated ways. > > Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-14 1:46 ` Randy Brukardt @ 2008-03-14 4:41 ` Eric Hughes 2008-03-15 3:20 ` Randy Brukardt 0 siblings, 1 reply; 29+ messages in thread From: Eric Hughes @ 2008-03-14 4:41 UTC (permalink / raw) On Mar 13, 7:46 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: [re: consideration of user attributes] > Not seriously. It had been rejected for Ada 95, and in general, we didn't > want to rehash that old ground. Hmm. I do admit, unless you're specifically support heavy generic programming, it's not all that useful. I wrote: > > And a related historical question: Why does the prefixed view of a > > subprogram only apply to tagged types? It seems like a syntax > > eminently suited for any subprogram. > There are ambiguity problems because "any type" includes access types. [...] > That caused definitional and implementation problems. So we only allowed > tagged types. OK. That's a can of worms. I'm writing here, though, not to solve that problem but to provide motivation about why a solution is important. > That's OK, because only tagged types work "right" in Ada. [...] > > Thus, I think virtually all new composite types should be tagged in Ada > programs [...] I'm with you on the general idea. In my own code, most of my types are tagged. But the requirement to have them tagged in order to use the "." operator forces a trade-off: either (a) restrict generic parameters to tagged types or (b) avoid "." notation and be required to pull in whole packages rather than only single types. This doesn't match up with the separation of concerns (a.k.a. orthogonality) which is one of the hallmarks of Ada and one of the things I appreciate most about the language. The power of generic programming is to reinterpret the notation within a generic body through the parametric meaning of that notation. Today, for method invocations, that means "call through the virtual function table". That's certainly right for tagged types. It's too restrictive for other types. My goal is to envision a reasonable way of introducing into visibility all the affordances of a type with just the type name and not its whole package of definition. A hypothetical attribute such as T'Package isn't the right thing, since it would expand visibility (even if it were feasible to implement). What about tagging the function rather than the type? Imaginary example: function Op( X : T ) return X is tagged ; The sole purpose of the tag in this example is to mark a particular function signature as available through "." notation. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-14 4:41 ` Eric Hughes @ 2008-03-15 3:20 ` Randy Brukardt 2008-03-17 4:38 ` Eric Hughes 0 siblings, 1 reply; 29+ messages in thread From: Randy Brukardt @ 2008-03-15 3:20 UTC (permalink / raw) "Eric Hughes" <eric.eh9@gmail.com> wrote in message news:928f737d-955f-415b-93b1-ddbd24fbf81e@e25g2000prg.googlegroups.com... > On Mar 13, 7:46 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: ... > > That's OK, because only tagged types work "right" in Ada. [...] > > > > Thus, I think virtually all new composite types should be tagged in Ada > > programs [...] > > I'm with you on the general idea. In my own code, most of my types > are tagged. But the requirement to have them tagged in order to use > the "." operator forces a trade-off: either (a) restrict generic > parameters to tagged types or (b) avoid "." notation and be required > to pull in whole packages rather than only single types. This doesn't > match up with the separation of concerns (a.k.a. orthogonality) which > is one of the hallmarks of Ada and one of the things I appreciate most > about the language. I agree. Indeed, that is a frequent gripe that we (the ARG) have, and something we try to avoid introducing more of. But I doubt that it can really be fixed, simply because of compatibility. We can't change the semantics of existing programs in ways that would break much of the existing Ada code. We went about as far as we would ever go that way with the deletion of return-by-reference in the Amendment. And there was a lot of concern that we went too far (but I think that most people have agreed that the pain was worth the benefits). It's the problem that occurs when you're working on something with a substantial installed base, be it a programming language, compiler, or OS. You don't get a blank page; you have to support most of what went before. Witness Microsoft's problems with Windows Vista as an example of what can happen if you don't pay attention to it. Thus you get things like tagged types which simply work better than other kinds of types. That was introduced in Ada 95, and we have been happy to continue it going forward. In any case, I don't think a massive overhaul in this (or any other area) is very likely for Ada. Even if the result would make more sense. Randy. The power of generic programming is to > reinterpret the notation within a generic body through the parametric > meaning of that notation. Today, for method invocations, that means > "call through the virtual function table". That's certainly right for > tagged types. It's too restrictive for other types. > > My goal is to envision a reasonable way of introducing into visibility > all the affordances of a type with just the type name and not its > whole package of definition. A hypothetical attribute such as > T'Package isn't the right thing, since it would expand visibility > (even if it were feasible to implement). > > What about tagging the function rather than the type? Imaginary > example: > function Op( X : T ) return X is tagged ; > The sole purpose of the tag in this example is to mark a particular > function signature as available through "." notation. > > Eric > > > ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-15 3:20 ` Randy Brukardt @ 2008-03-17 4:38 ` Eric Hughes 2008-03-17 21:03 ` Randy Brukardt 0 siblings, 1 reply; 29+ messages in thread From: Eric Hughes @ 2008-03-17 4:38 UTC (permalink / raw) On Mar 14, 9:20 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > Indeed, that is a frequent gripe that we (the ARG) have, and > something we try to avoid introducing more of. But I doubt that it can > really be fixed, simply because of compatibility. We can't change the > semantics of existing programs in ways that would break much of the existing > Ada code. Well, I don't think any of the ideas I've had recently about dot- notation are in the realm of changing pre-existing semantics. Instead, I'm concerned with keeping existing syntax patterns, enlarging the domain of applicability of that syntax, and creating new semantics that match existing practice. While that becomes more difficult as time goes forward, I think Ada's been pretty good about making conservative choices that attenuate the consequences of otherwise-rash decisions. > Thus you get things like tagged types which simply work better than other > kinds of types. That was introduced in Ada 95, and we have been happy to > continue it going forward. Tagged types do work better, sure. But they're not a panacea, either. It would a mistake to address other difficulties with types by shoehorning "solutions" to them into tags. And in the last couple of days I've realized the problems with untagged types as formal parameters is much greater than the absence of dot-notation. So here's a brief example. I'm writing a smart accessor package set right now. As something of an exercise, I'm doing this as generically as possible. So I'm looking to write code that can use both intrusive (part of the managed object) and accretive (separate from the managed object) allocation strategies for reference counts. And I want to do it without making the accessor types tagged. Since an intrusive accessor is simple a wrapped-up access object, adding a tag would double the machine size of an object. I consider this a poor result for a system-level library. My first foray at solving this was to use a formal type parameter for the implementation of the accessor. The intrusive implementation would contain just an access object; the accretive one would have that plus an access to a reference count. Pretty simple, so I thought. But without using a tagged type in the formal parameter definition, there's no visibility either for record components or for implicit visibility of operators on that type. Thus I couldn't get at components either directly or indirectly. I discarded that approach. It's a shame really, because it would otherwise be a natural representation of variety of in possible implementations. I'm still looking at other ways of approaching the problem. I'm beginning to suspect that doing this may be impossible, but I don't have an argument yet. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-17 4:38 ` Eric Hughes @ 2008-03-17 21:03 ` Randy Brukardt 2008-03-17 21:58 ` Eric Hughes 0 siblings, 1 reply; 29+ messages in thread From: Randy Brukardt @ 2008-03-17 21:03 UTC (permalink / raw) "Eric Hughes" <eric.eh9@gmail.com> wrote in message news:c6b7e0b5-6b81-486a-8054-becd0df9842b@h11g2000prf.googlegroups.com... ... > Tagged types do work better, sure. But they're not a panacea, > either. It would a mistake to address other difficulties with types > by shoehorning "solutions" to them into tags. And in the last couple > of days I've realized the problems with untagged types as formal > parameters is much greater than the absence of dot-notation. > > So here's a brief example. I'm writing a smart accessor package set > right now. As something of an exercise, I'm doing this as generically > as possible. So I'm looking to write code that can use both intrusive > (part of the managed object) and accretive (separate from the managed > object) allocation strategies for reference counts. And I want to do > it without making the accessor types tagged. Since an intrusive > accessor is simple a wrapped-up access object, adding a tag would > double the machine size of an object. I consider this a poor result > for a system-level library. > > My first foray at solving this was to use a formal type parameter for > the implementation of the accessor. The intrusive implementation > would contain just an access object; the accretive one would have that > plus an access to a reference count. Pretty simple, so I thought. > But without using a tagged type in the formal parameter definition, > there's no visibility either for record components or for implicit > visibility of operators on that type. Thus I couldn't get at > components either directly or indirectly. I discarded that approach. > > It's a shame really, because it would otherwise be a natural > representation of variety of in possible implementations. I'm still > looking at other ways of approaching the problem. I'm beginning to > suspect that doing this may be impossible, but I don't have an > argument yet. In cases like these, you have to pass accessor routines explicitly. Something like: generic type T is private; procedure Increment_Count (Obj : in out T) is <>; function Count (Obj : in T) is <>: ... package Whatever is ... Note the use of <> in these formal subprogram declarations. It gives a default for the subprograms such that a routine with the right name and profile automatically matches. (Why you can't have such defaults for types is unknown by me...) This makes the instantiations less annoying (but you do need to declare the appropriate routines somewhere). You can wrap these things up and use them as formal packages if they are common, so you don't necessarily have to end up with lots of generics with a hundred parameters. I would prefer to use an interface or tagged type here, but obviously you can't do that. This is not a perfect solution, but it works and is commonly used. Randy. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: User-defined type attributes 2008-03-17 21:03 ` Randy Brukardt @ 2008-03-17 21:58 ` Eric Hughes 0 siblings, 0 replies; 29+ messages in thread From: Eric Hughes @ 2008-03-17 21:58 UTC (permalink / raw) On Mar 17, 3:03 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > In cases like these, you have to pass accessor routines explicitly. Yeah, I figured that out this morning. I should know better to post at the end of the day before I've slept on it. > It gives a > default for the subprograms [...] (Why you can't have such defaults for types > is unknown by me...) Yeah, we just had that discussion two weeks ago. > I would prefer to use an interface or tagged type here, but obviously you > can't do that. This is not a perfect solution, but it works and is commonly > used. Notationally, it would be better, sure. The problem, as you acknowledge, is that it's a bad idea for a system library to require any particular inheritance in order to work. Working on this little project has given substance to an idea I've had for a while about non- inheritance type relationships. In brief, it's to give a name to the set of types that satisfy a certain set of signatures that, critically, need _not_ be sufficient to form an abstract type. This specification constitutes a partial type. To pick a simple example, the set of trichotomous types is that which have a total ordering that satisfy the standard trichotomy axioms (\forall a,b : a < b \land b < a \implies a = b). Trichotomy is a partial type. It's a natural parameter for generic ordered containers. Indeed, partial types are the natural kind of formal type parameter for any generic. Right now in Ada they have to be simulated by passing some set of formal parameters. The spirit of Ada would be better served by giving them an explicit representation. Eric ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2008-03-17 21:58 UTC | newest] Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-03-12 18:58 User-defined type attributes Eric Hughes 2008-03-12 21:23 ` Dmitry A. Kazakov 2008-03-13 18:32 ` Eric Hughes 2008-03-13 19:58 ` Dmitry A. Kazakov 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 9:00 ` Dmitry A. Kazakov 2008-03-14 14:36 ` User-defined type attributes (replacing genericity) Georg Bauhaus 2008-03-15 3:04 ` User-defined type attributes Randy Brukardt 2008-03-15 9:33 ` Dmitry A. Kazakov 2008-03-14 14:31 ` User-defined type attributes (replacing genericity) Georg Bauhaus 2008-03-14 14:48 ` Dmitry A. Kazakov 2008-03-14 17:51 ` Eric Hughes 2008-03-14 18:58 ` Dmitry A. Kazakov 2008-03-14 20:19 ` Eric Hughes 2008-03-15 4:01 ` Randy Brukardt 2008-03-14 16:58 ` Georg Bauhaus 2008-03-14 18:39 ` Dmitry A. Kazakov 2008-03-15 9:39 ` Dmitry A. Kazakov 2008-03-14 3:55 ` User-defined type attributes Eric Hughes 2008-03-14 9:01 ` Dmitry A. Kazakov 2008-03-14 18:04 ` Eric Hughes 2008-03-14 1:46 ` Randy Brukardt 2008-03-14 4:41 ` Eric Hughes 2008-03-15 3:20 ` Randy Brukardt 2008-03-17 4:38 ` Eric Hughes 2008-03-17 21:03 ` Randy Brukardt 2008-03-17 21:58 ` Eric Hughes
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox