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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,bd40601768eaf8fd X-Google-Attributes: gid103376,public From: Brian Rogoff Subject: Re: Array of Variant Records Question... Date: 1999/09/09 Message-ID: X-Deja-AN: 523213060 References: <7r5vh3$imu1@svlss.lmms.lmco.com> <37d6a45c@news1.prserv.net> <37d6ccb6@news1.prserv.net> <7r77i8$i08$1@nnrp1.deja.com> <37d7c116@news1.prserv.net> <7r8t21$ov5$1@nnrp1.deja.com> Content-Type: TEXT/PLAIN; charset=US-ASCII X-Trace: nntp1.ba.best.com 936930020 224 bpr@206.184.139.136 MIME-Version: 1.0 Newsgroups: comp.lang.ada Date: 1999-09-09T00:00:00+00:00 List-Id: On Thu, 9 Sep 1999, Robert Dewar wrote: > In article <37d7c116@news1.prserv.net>, > "Matthew Heaney" wrote: > > 1) access constant params > > no comment, not exciting ...> That's new, only exciting features may be proposed! > > 4) implicit conversion of an access param to a named access > type > > > > 5) implicit conversion of a specific access type to an access > type that > > designates an ancestor that is class-wide Matt, can you give examples where you find that explicit conversions are painful, or damage readability? > > 7) downward closures > > discussed to death already, not worth discussing further ... Well, if we want to be precise, we should call them "downward funargs", since Ada already supports a restricted form of downward closure via generics. To violate Robert's sentiments even further, I'll append a little GNAT program which (1) Uses downward funargs (2) Has a fair bit of subprogram nesting (3) Solves the N Queen problem so that even if downward funargs aren't dicussable I hit two other threads :-) Happy 9/9/99 -- Brian -- N Queens Problem -- -- see L.Allison. Continuations implement generators and streams. -- Computer Journal 33(5) 460-465 1990 -- -- Cont = State -> Answer where State=List, Answer=Std_output -- Generator = Cont -> State -> Answer = Cont -> Cont with Ada.Text_IO; use Ada.Text_IO; procedure Generate is package Int_IO is new Ada.Text_IO.Integer_IO(Integer); type Node_Type; type List_Type is access Node_Type; type Node_Type is record Head : Integer; Tail : List_Type; end record; type Cont_Proc_Type is access procedure (L : in List_Type); type Gen_Proc_Type is access procedure (Cont : Cont_Proc_Type; L : in List_Type); type Pred_Func_Type is access function (L : in List_Type) return Boolean; N : Integer; function Cons(I : Integer; L : List_Type) return List_Type is P:List_Type; begin P := new Node_Type; P.Head := I; P.Tail := L; return P; end Cons; -- generator "library" -- success : Cont procedure Success(L : List_Type) is procedure Print(L : List_Type) is begin if L /= null then Int_IO.Put(L.Head); Print(L.Tail); end if; end Print; begin if L /= null then New_Line; Put(" :"); Print(L); end if; end Success; -- Choose :Int -> Cont -> Cont = Int -> Generator procedure Choose(N : Integer; Cont : Cont_Proc_Type; L : List_Type) is begin for I in 1..n loop Cont( Cons(I, L) ); end loop; -- for each i continue with i++L end Choose; -- Filter : (State -> boolean) -> Generator procedure Filter(P : Pred_Func_Type; Cont : Cont_Proc_Type; L : List_Type) is begin if P(L) then Cont(L); end if; -- else fail -- if L ok then continue with L else do nothing end Filter; -- doo = gen**n :Int -> Generator -> Generator procedure Doo(N : Integer; Gen : Gen_Proc_Type; Cont : Cont_Proc_Type; L : List_Type ) is procedure Gen_Cont(L : List_Type) is begin Gen(Cont,L); -- gen and then cont, to L end Gen_Cont; begin if N = 0 then Cont(L); else Doo(N-1, Gen, Gen_Cont'Unrestricted_Access, L); end if; -- do (n-1) gen and then [gen and then cont], to L end Doo; -- n queens proper procedure Queen(N : Integer) is function Valid(L : List_Type) return Boolean is function V(Col : Integer; L2 : List_Type) return Boolean is begin if L2 = null then return True; -- safe elsif (L.Head = L2.Head) or -- check rows (L2.Head+Col = L.Head) or -- & diagonals (L2.Head-Col = L.Head) -- other diags then return False; -- threat else return V(col+1, L2.Tail); end if; end V; begin if L = null then return True; else return V(1, L.Tail); end if; end Valid; -- choosevalid :Generator procedure Choose_Valid(Cont : Cont_Proc_Type; L : List_Type) is procedure Valid_Cont (L : List_Type) is begin Filter(Valid'Unrestricted_Access, Cont, L); -- check valid and if so continue, with L end Valid_Cont; begin Choose(N, Valid_Cont'Unrestricted_Access, L); -- choose row and then [check valid and if so continue], with L end Choose_Valid; begin Doo(N, Choose_Valid'Unrestricted_Access, Success'Unrestricted_Access, Null); -- [do n times: choose a valid row] and if so succeed end Queen; begin Put_Line("Enter a number and hit return"); Int_IO.Get(N); Queen(N); New_Line; Put_Line("and that's it!"); end;