From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,61e9062c1f23b9d5 X-Google-Attributes: gid103376,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!feeder3.cambrium.nl!feeder4.cambrium.nl!feeder1.cambrium.nl!feed.tweaknews.nl!news2.euro.net!news.mixmin.net!news2.arglkargh.de!noris.net!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Reconsidering assignment Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <1181165630.012508.55290@i38g2000prf.googlegroups.com> Date: Thu, 7 Jun 2007 11:27:18 +0200 Message-ID: <19fxsxv1god43$.1pqq8vgfu2itn$.dlg@40tude.net> NNTP-Posting-Date: 07 Jun 2007 11:24:48 CEST NNTP-Posting-Host: 3de0aa1c.newsspool4.arcor-online.net X-Trace: DXC=0flM5OjU0a4i6K;>iZ]7634IUKkg2E[=5IGbS4J: X-Complaints-To: usenet-abuse@arcor.de Xref: g2news1.google.com comp.lang.ada:16088 Date: 2007-06-07T11:24:48+02:00 List-Id: On Wed, 06 Jun 2007 14:33:50 -0700, Maciej Sobczak wrote: [...] > Some important foundations. > A type can be unconstrained/constrained. It can be also a subtype of > another type, adding some more constraints. New subtypes can also be obtained through generalization, i.e. by lifting constraints. For example, an enumeration type could be extended, or an integer type could be promoted to a real. > Consider: > > procedure P1(X : in Integer); > procedure P2(X : out Positive); > procedure Swap(X, Y : in out Integer); > > declare > X : Integer := -1; > Y : Positive := 1; > begin > P1(X); -- (1) OK (matching) > P1(Y); -- (1) OK (actual is stricter) > P2(Y); -- (2) OK (matching) > P2(X); -- (2) OK (actual is wider) > Swap(X, Y); -- (3) compile-time error on second parameter > end; > > The call at (3) should banned. For types that have equivalent value- > and constraint- spaces, the rules for parameter passing are as > follows: > 1. "in" formal parameters can get actual parameters that have > constraints matching or stricter > 2. "out" formal parameters can get actual parameters that have > constraints matching or wider > 3. "in out" formal parameters can only get actual parameters that have > matching constraints. > > Any violation of these rules leads to potential constraint error that > cannot be prevented at compile-time. This does not work because most of the base type operations will be lost. function "+" (Left, Right : Integer) return Integer; This cannot be inherited by Positive according to your rules because the result is out. Thus the programmer will have to delegate it: function "+" (Left, Right : Positive) return Positive is begin return Positive (Integer (Left) + Integer (Right)); end "+"; which were ambiguous: X : Integer := 1 + 1; is it Positive'(1)+Positive'(1) or Integer'(1)+Integer'(1)? You will need complex preference rules to resolve this mess. > procedure Safe_Swap(X, Y : in out String) with X'Length = Y'Length; This does not change anything, because the constraint is not static. The summary of your program is to map constraint [more generally, substitutability] violations onto types. You do this by disallowing operations, and disallowing is static relatively to the type of the operation. Hence to make it work, all constraints have to be static in the type scope. But the string length is not such a constraint. > declare > S1 : String := "abc"; > S2 : String := "xyz"; > S3 : String := "klmnop"; S4 : String := Read_From_File; > begin > Safe_Swap(S1, S2); -- OK > Safe_Swap(S1, S3); -- compile-time error > Safe_Swap(S1, S3(1..3)); -- OK Safe_Swap(S1, S4); -- ? Note that Ada addresses this issue. If you wanted the above you should simply do the following: type Three_Character_String is new String (1..3); type Six_Character_String is new String (1..6); Done. If you use String instead, then there must be a reason for. [...] > Now - what am I missing? :-) That Constraint_Error is a valid outcome. The problem is not that "-" of Integer is inherited by Positive. It shall be. It is also not, that the Positive's "-" is a composition of the Integer's "-" with two conversion functions Integer->Positive and Positive->Integer (where the former cannot be implemented without Constraint_Error). Whether you compose it this way or choose to override it, it would be impossible to implement without Constraint_Error. This is not the actual problem. I would like to see contracted exceptions. Consider your examples in the light of: procedure Foo is X : Integer := -1; Y : Positive := 1; begin Swap (X, Y); --Illegal end Foo; The contract of Foo does not have Constraint_Error, but Swap has it. Let Swap have no Constraint_Error in the contract, then it cannot be inherited by Positive, because the inheritance will compose it with Integer->Positive, which has Constraint_Error in its contract. So, you'll be forced to either override it or drop inheritance... or redesign Foo: procedure Foo is X : Integer := -1; Y : Positive := 1; begin Swap (X, Y); exception when Constraint_Error => -- Aha! ... end Foo; -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de