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.7 required=5.0 tests=BAYES_00,INVALID_MSGID, PDS_OTHER_BAD_TLD autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,f66d11aeda114c52 X-Google-Attributes: gid103376,public From: mheaney@ni.net (Matthew Heaney) Subject: Re: Building blocks (Was: Design By Contract) Date: 1997/10/02 Message-ID: #1/1 X-Deja-AN: 277597728 References: Organization: Estormza Software Newsgroups: comp.lang.ada Date: 1997-10-02T00:00:00+00:00 List-Id: In article , stt@houdini.camb.inmet.com (Tucker Taft) wrote: >Robert A Duff (bobduff@world.std.com) wrote: > >: ... >: By the way, speaking of negative logic, what do people think about >: negative logic in "if" statements? I tend to try to reduce the number >: of "not"s in the code. But other people tend to use some other >: heuristic, such as "do the normal case first" or "do unusual case >: first". > >FWIW, one of my heuristics is if one case is much shorter than the other, >do the shorter case first, as it is easier to see what is happening. >When you see something like: > > ... 200 lines > else > Do_Something; > end if; That about sums it up for me too. I like to handle the special cases right up in front. That often means checking preconditions that aren't expressable in Ada syntax (hint, hint). I would have implemented Tuck's example as if not P then Do_Something; return; end if; ...200 lines One of the benefits of this approach is that it removes a level of nesting. A simple example of a precondition check is a stack pop. Instead of procedure Pop (Stack : in out Bounded_Stack) is begin if Stack.Top /= 0 then Stack.Top := Stack.Top - 1; else raise Stack_Empty; end if; end; I would do this as procedure Pop (Stack : in out Bounded_Stack) is begin if Stack.Top = 0 then raise Stack_Empty; end if; Stack.Top := Stack.Top - 1; end; This is what I meant by "check preconditions at top of subprogram." Get the special cases out of the way. Of course, you can also let Ada do the check for you. If the Top component is of type Natural, then procedure Pop (Stack : in out Bounded_Stack) is begin Stack.Top := Stack.Top - 1; exception when Constraint_Error => raise Stack_Empty; end; You have to be careful with this style, though; do too much in the exception handler and you can get burned by RM 11.6 subtleties. Of course, it would be really cool if I could declare Pop as procedure Pop (Stack : in out Root_Stack) precondition Not_Empty: Length (Stack) > 0; end Pop; and then Ada could check the precondition for me. David Luckham wrote a paper (and a whole annotation language) describing exception annotations, something like: procedure Pop (Stack : in out Root_Stack) exception when Length (Stack) = 0 => raise Stack_Empty; end Pop; Maybe we can look into this for the next language update, hmmmm? -------------------------------------------------------------------- Matthew Heaney Software Development Consultant (818) 985-1271