CVS difference for ais/ai-00260.txt

Differences between 1.5 and version 1.6
Log of other versions for file ais/ai-00260.txt

--- ais/ai-00260.txt	2001/07/14 00:01:48	1.5
+++ ais/ai-00260.txt	2001/09/08 01:42:48	1.6
@@ -739,3 +739,504 @@
 Right.
 
 ****************************************************************
+
+From: Pascal Obry
+Sent: Tuesday, July 17, 2001 4:09 PM
+
+After thinking about this issue we have already S'Class'Input, S'Class'Output,
+S'Class'Read and S'Class'Write.
+
+'Class being an attribute and 'Output, 'Input, 'Read 'Write too.
+
+So 'External_Tag'Read is not that different, is it ?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, July 17, 2001 4:55 PM
+
+'Class (and 'Base) is a special case throughout Ada compilers. It represents
+a type, so the only place that it is necessary to handle this is for types.
+Essentially, S'Class names a type, just as an identifier does.
+
+'External_Tag is a value.
+
+In the Janus/Ada compiler, the handling of values is completely separate
+from the handling of type names. To allow nesting of values in this way in
+the attribute definition clause would require a lot of extra code.
+
+In any case, I've now concluded that this very special case solution is the
+wrong way to handle the problem. The REAL problem is that it is impossible
+to usefully write a custom version of S'Class'Read. That's because there is
+no way to dispatch on a tag that you've read in.
+
+If THAT problem was solved with an appropriate building block, we would have
+a much more general solution that would be useful for a lot more than
+solving a single problem.
+
+Therefore, I've withdrawn my support for this solution, at least until we've
+properly investigated methods for dispatching on a tag value.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, July 17, 2001 9:47 PM
+
+This also means that to implement S'Class'Read you have to do very peculiar
+things in any Ada compiler, since you cannot represent this as lower level
+Ada operations.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, July 17, 2001 5:56 PM
+
+I think this is throwing the baby out with the bathwater.
+There is no real harm in keeping the tag_read and tag_write
+operational attributes.  They provide a useful capability in
+a straightforward fashion.
+
+The building block solution we would all love has been investigated
+before (probably several times) and I am not optimistic we will
+find an elegant solution in our lifetime.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, July 17, 2001 6:27 PM
+
+I'm not convinced that the solution has to be that elegant, just functional.
+And in any case, I don't see (or remember, for that matter) much of a serious
+effort to solve this problem. (The parent type issue, yes. Dispatching control,
+no.) I've only seen impossible suggestions involving runtime types, which will
+never work in the Ada model. Is there an LSN or other record of the MRT's work
+on this issue?
+
+I proposed a solution last week ('Convert), which has been met with the typical
+silence. I proposed a solution using syntax a month ago, which was dismissed as
+"ugly" -- I knew the syntax itself was no good, but no one suggested an
+alternative.
+
+All I want to see is an effort to solve the problem. If there is no good
+solution, then so be it. But right now, I see a kludgy solution to a very
+specific problem, when a solution with a similar level of kludginess (and
+similar or even less implementation effort) appears to solve a bunch of
+problems. I'd rather use the more general kludge than the specific one...
+
+****************************************************************
+
+From: Pascal Obry
+Sent: Wednesday, July 18, 2001 1:26 AM
+
+Randy Brukardt writes:
+ > 'Class (and 'Base) is a special case throughout Ada compilers. It represents
+ > a type, so the only place that it is necessary to handle this is for types.
+ > Essentially, S'Class names a type, just as an identifier does.
+ >
+ > 'External_Tag is a value.
+
+Ok, I see. So let's keep current proposal. It is ok to me.
+
+****************************************************************
+
+From: Christoph Grein
+Sent: Wednesday, July 18, 2001 12:03 AM
+
+I cannot remember having received such a proposal ('Convert). There was silence
+on this problem last week. Could you please repeat this proposal?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, July 18, 2001 2:47 PM
+
+I sent two messages on Friday. A check of the mail server logs shows that
+they all were delivered, so I won't repeat the entire message here (I'll
+send the entire message to Christoph).
+
+The proposal was buried in a longer message, so people might have missed it:
+(note that I'm not excited about the name "Convert"; perhaps someone has a
+better one?)
+
+---
+
+...
+
+The real goal here is to get a dynamic view conversion where the type is
+identified by a tag value, rather than by name. Going further than that
+brings in a truckload of worms. Perhaps we just need to define such an
+attribute:
+
+    T'Class'Convert (Obj : in out T'Class; Tag : in Ada.Tags.Tag)
+
+"Returns a view conversion of Obj to the type identified by tag. This
+attribute is considered dynamically tagged for dispatching purposes. Raises
+Constraint_Error if Tag does not identify a type in T'Class, or if the tag
+of Obj does not identify a type that is covered by or descended from the
+classwide type identified by Tag (this is 4.6(42)). Note: The tag of <Obj>
+is unchanged, as in all view conversions."
+
+...
+
+My preference for 'Parent_Tag is that it is illegal on non-derived,
+non-tagged types. But making it illegal on non-derived type probably is a
+contract model problem. So, I suppose it probably ought to return Null_Tag
+on non-derived types (which means we'd have to define that, too). Similarly,
+it ought to return the parent tag even for private types (skipping levels of
+derivation would cause problems in practice, and would make it worthless for
+the "calling the parent" problem. That means the parent tag of the full
+type, which should not be a problem to do (this is not a static expression,
+and certainly at runtime the parent tag is known. Indeed, Ada
+implementations have to store this in the tag already in order to be able to
+make the type conversion checks of 4.6(42) - I would expect that this is
+precisely what would be returned. If the compiler has the information, why
+shouldn't the programmer be able to use it??)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, July 18, 2001 4:55 PM
+
+Well, I remember seeing this, but I will admit I couldn't figure out
+what you meant by a view conversion to a type determined by a tag.
+
+A view conversion has no run-time effect, it
+only has a compile-time effect.  Tags, on the other hand,
+exist at run-time.  So what are the compile-time and run-time
+effects of doing the "view conversion"?  Is it really that you
+want to dispatch to something other than the tag of the controlling
+object?  That is the controlling tag is not the same as the tag of
+the controlling object?
+
+If so, I'm not sure you clarify things by calling it a view conversion.
+
+Can you show how the "view" conversion (or is it tag
+substitution?) would be used in a larger example?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, July 18, 2001 4:55 PM
+
+> ... Is it really that you
+> want to dispatch to something other than the
+> tag of the controlling object?  That is the controlling
+> tag is not the same as the tag of the controlling object?
+
+Yes, that is correct.
+
+> If so, I'm not sure you clarify things by calling
+> it a view conversion.
+
+I agree, I'd much rather have a syntax solution for this problem. But everyone
+here said that was too heavy, so I'm casting about for other ways to do it.
+
+> Can you show how the "view" conversion (or is it tag
+> substitution?) would be used in a larger example?
+
+Sure. Consider the problem of calling the parent operation without naming the
+type:
+
+    My_Operation (Root'Class'Convert (Obj, Obj'Parent_Tag), ...);
+
+This would make a dispatching call to the My_Operation for Obj'Parent_Tag. If
+the parent type of Obj was Parent, this would be equivalent to the statically
+bound call of:
+
+    My_Operation (Parent (Obj), ...);
+
+A compiler could optimize the code to static binding if the tag in a 'Convert
+was statically known, but I don't think we want to think about including that
+in the semantics.
+
+Similarly, the problem posed by Christoph could be solved by:
+
+    function Closest_Equal (Left, Right : in S'Class) return Boolean is
+        GCA : Ada.Tags.Tag :=
+              Figure_Greatest_Common_Ancestor (Left'Tag, Right'Tag);
+    begin
+        return "=" (S'Class'Convert (Left, GCA), S'Class'Convert (Right, GCA));
+    end Closest_Equal;
+
+which would test the equality of the common parts (whatever those are) of Left
+and Right.
+
+---
+
+The reason for making this a funny "view conversion" is to get a way to inject
+the proper tag without inventing any new syntax or semantics (other than for
+the attribute itself). After all, a view conversion is precisely how we do
+that in Ada 95. The only odd thing here is the tag that 'Convert provides for
+dynamic dispatching purposes.
+
+---
+
+Unfortunately, this doesn't work on a dispatching function call. For that, we'd
+need another attribute, more magic than this one:
+
+    S'Class'Give_Tag
+         function (Obj : in S'Class; Tag : in Ada.Tags.Tag) return S'Class;
+
+which would give the "Obj" parameter "Tag" for dispatching purposes. "Obj" is
+then returned as the result of the attribute. This would be used in something
+like:
+
+    return S'Class'Give_Tag (S'Input (Stream), Tag_I_Read);
+
+---
+
+More thought appears needed here. Perhaps there is a better way to describe
+these attributes.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Wednesday, July 18, 2001 8:23 PM
+
+> The reason for making this a funny "view conversion" is to get a way to
+> inject the proper tag without inventing any new syntax or semantics (other
+> than for the attribute itself). After all, a view conversion is precisely
+> how we do that in Ada 95. The only odd thing here is the tag that 'Convert
+> provides for dynamic dispatching purposes.
+
+The problem is that you need to make a copy of the value in order
+to insert a new tag (assuming the conventional implementation of
+tagged objects), and that's just not consistent with the semantics
+of a view conversion.  I guess you're thinking in terms of using
+this funny conversion only in special contexts, specifically on
+dispatching calls, but presumably these conversions would have
+to be allowed in other contexts as well (e.g., return statements,
+as well as noncontrolling parameters), and there has to be
+well-defined semantics for the conversion, which seems to imply
+a copy of the object for purposes of substituting the proper tag.
+Besides not fitting with the notion of view conversions, that
+simply won't work in general as far as I can see.  For example
+consider the case of return-by-reference objects, where you can't
+ever make a copy.
+
+> Unfortunately, this doesn't work on a dispatching function call. For that,
+> we'd need another attribute, more magic than this one:
+
+Right, this just get messier.
+
+> More thought appears needed here. Perhaps there is a better way to describe
+> these attributes.
+
+Yes, I think that the idea of describing these as view conversions
+certainly has to be abandoned.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, July 18, 2001 10:17 PM
+
+> The problem is that you need to make a copy of the value in order
+> to insert a new tag (assuming the conventional implementation of
+> tagged objects), and that's just not consistent with the semantics
+> of a view conversion.
+
+No, no, no! View conversions DON'T change the tag of the object. They only
+change the tag of the object used for determining the subprogram to call.
+You have to get the tag used for dispatching from the conversion (in the
+static binding case), without reading the object. This just says to use a
+different tag for (dynamic) dispatching: the object is unchanged (as in any
+view conversion).
+
+Because of tag-indeterminant items, a compiler has to be prepared to get a
+dispatching tag from almost anywhere, so it doesn't seem an implementation
+hardship to add another case.
+
+>  I guess you're thinking in terms of using
+> this funny conversion only in special contexts, specifically on
+> dispatching calls, but presumably these conversions would have
+> to be allowed in other contexts as well (e.g., return statements,
+> as well as noncontrolling parameters), and there has to be
+> well-defined semantics for the conversion, which seems to imply
+> a copy of the object for purposes of substituting the proper tag.
+
+Absolutely not. This is a no-op (discounting checks and resolution issues)
+as is ANY view conversion of a tagged object in a non-dispatching context.
+It has no effect on the object: it just returns the object itself.
+
+> Besides not fitting with the notion of view conversions, that
+> simply won't work in general as far as I can see.  For example
+> consider the case of return-by-reference objects, where you can't
+> ever make a copy.
+
+There is no copy, so this is not a problem. Pascal had suggested a non-view
+conversion, which definitely does not work because you can't copy the object
+in general.
+
+> Yes, I think that the idea of describing these as view conversions
+> certainly has to be abandoned.
+
+No, actually, it is better. There IS a way to use this for controlling
+dispatching functions. You need a two parameter dispatching helper function.
+(One could imagine this also being an attribute of some sort.)
+
+It would have the specification:
+
+    function Identity (Object : in T; Dispatcher : in T) return T;
+
+It would return Object, doing nothing with the second parameter.
+
+Then, a controlling function can be called as follows:
+
+    declare
+	S_Obj : S; -- Not really used.
+    begin
+      return Identity (S'Input (Stream), S'Class'Convert (S_Obj,
+Tag_I_Read);
+    end;
+
+which will cause the result of S'Input dispatched to the type identified by
+"Tag_I_Read" to be returned.
+
+Even if we did define something like 'Give_Tag (because we could get rid of
+the unneeded object here), this would give a viable model to describe its
+behavior.
+
+Anyway, if you don't like the view conversion model, please suggest an
+alternative that doesn't require a complete rewrite of 3.9.2. Or an
+alternative solution.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, July 18, 2001 10:17 PM
+
+BTW, the main reason for describing this attribute as a "view conversion" is
+that the object is untouched by the attribute. If you tried to describe the
+attribute as a function, you would get a copy, and that doesn't work for the
+reasons Gary mentions (and many others as well, such as "Adjust" issues). We
+have to describe it as something else, and "view conversion" seems to be the
+closest existing thing.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, July 19, 2001 3:15 AM
+
+I understand what you are trying to achieve, but the above statement is
+confused.  A view conversion (to a specific subtype) may be used to force
+_static_ binding to a particular subprogram.  The tag is not used in this
+context, since there is no dispatching.  If you ever force redispatching by
+converting to a class-wide subtype, then you call the subprogram designated by
+the tag.
+
+Calling your proposed construct a view conversion is therefore not helpful.  As
+I understand it, the 'Convert attribute means "regardless of the tag found in
+the object, use the tag T for dispatching".  I guess this attribute would have
+to be only usable in subprogram calls.
+
+However, making it an attribute seems to complicate things, because it seems to
+imply that this attribute returns a value, which is not really true (as you
+point out, trying to build a value by copying Obj and inserting tag Tag causes
+endless trouble).
+
+So I think that if we want to pursue this idea we do indeed need special
+syntax. I would propose something like:
+
+    My_Operation (Obj with Tag, ...);
+
+(Yet another use of the reserved word "with"...)
+
+This syntax would only be usable as an actual parameter, and the tag checks
+that you outlined in a previous mail would be performed before the call.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, July 19, 2001 9:38 AM
+
+I agree with Pascal here -- at least this is why the term "view conversion"
+was confusing me.  What we meant by "view" conversion was something which
+changed the compile-time view of an object, and had no effect on its
+run-time representation.  I suppose if you stand on your head, you
+could say this is similar in that it is saying "use this tag for
+dispatching but don't change the run-time representation" but it
+is a bit of a stretch.
+
+> ...
+> However, making it an attribute seems to complicate things, because it
+> seems to imply that this attribute returns a value, which is not really
+> true (as you point out, trying to build a value by copying Obj and
+> inserting tag Tag causes endless trouble).
+
+I think we could still use an attribute, though it clearly would need
+some special semantics.
+
+> So I think that if we want to pursue this idea we do indeed need special
+> syntax. I would propose something like:
+>
+>     My_Operation (Obj with Tag, ...);
+>
+> (Yet another use of the reserved word "with"...)
+
+I think this could also be Obj'With_Controlling_Tag(Tag)
+
+****************************************************************
+
+From: Christoph Grein
+Sent: Friday, July 20, 2001 12:15 AM
+
+I would propose to use the term "use". "with" seems to imply the object has this
+tag, which is misleading - we rather use another tag:
+
+   My_Operation (Obj use Tag, ...);
+
+or
+
+   My_Operation (Obj'Use_Controlling_Tag (Tag), ...);
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Friday, July 20, 2001 3:15 AM
+
+> I think we could still use an attribute, though it clearly would need
+> some special semantics.
+>
+> I think this could also be Obj'With_Controlling_Tag(Tag)
+
+As you know, an attribute is a name.  But here it would not name anything,
+because really there is no such thing as an object Obj having the tag Tag.
+So this would require heavy special casing in the language description as
+well as in compilers (I hate to think of the number of places in my compiler
+where I would have to write "if this is attribute With_Controlling_Tag then
+do something weird").
+
+I hate it when the syntax does not reflect what is really going on behind
+the scenes.  To me, an attribute seems to imply that some object is created
+and used in the dispatching call.  I believe that a new syntax is much
+clearer.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, July 20, 2001 12:31 PM
+
+The attribute seems to have one advantage over the syntax (at least if you
+restrict the syntax only to actual parameters in calls) -- it can be used to
+control a function with a controlling result as well.
+
+For instance, to control S'Input:
+
+    return S'Input'With_Controlling_Tag(Tag_Read_Earlier);
+
+OTOH, if we just made the syntax an expression, which acts like a qualified
+expression with special effects on controlling parameters and results, then
+it too could be used to control functions with controlling results:
+
+    return S'Input with Tag_Read_Earlier;
+
+(An alternative is to revisit my original idea that the syntax is a modifier
+for calls: both function and procedure calls:
+
+    return S'Input with Tag_Read_Earlier;
+
+    return Equal (A, B) with Tag_Read_Earlier;
+
+    My_Operation (Obj, ...) with Obj'Parent_Tag;)
+
+****************************************************************

Questions? Ask the ACAA Technical Agent