From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on ip-172-31-65-14.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-3.2 required=3.0 tests=BAYES_00,NICE_REPLY_A, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: project euler 26 Date: Tue, 5 Sep 2023 19:08:59 +0200 Organization: A noiseless patient Spider Message-ID: References: <878r9mudvj.fsf@bsb.me.uk> <87a5u1u1yv.fsf@bsb.me.uk> <8734ztttpc.fsf@bsb.me.uk> <87fs3ssl6v.fsf@bsb.me.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Tue, 5 Sep 2023 17:08:58 -0000 (UTC) Injection-Info: dont-email.me; posting-host="7b327c4b880c05c3511b9a0af588fe44"; logging-data="2177655"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/VpnF3iDumhZngobYBrrjzDdCsedXMV7o=" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.15.0 Cancel-Lock: sha1:eXe1Vab3WptMusDNVqoypT2BZ7g= Content-Language: en-US In-Reply-To: <87fs3ssl6v.fsf@bsb.me.uk> Xref: news.eternal-september.org comp.lang.ada:65598 List-Id: On 2023-09-05 17:18, Ben Bacarisse wrote: > There was > boiler plate code in my program that could be abstracted out into a > generic function (or package?) so that any function can be maximised > over some range or, better yet, any iterable type (if that's how Ada > does things). > Can someone here show me how? You define some classes. Either generic or tagged. E.g. a generic class of functions that uses two generic classes of the argument and the value: generic -- Ordered argument type Argument_Type is private; with function Next (Value : Argument_Type) return Argument_Type is <>; with function "<" (Left, Right : Argument_Type) return Boolean is <>; with function "=" (Left, Right : Argument_Type) return Boolean is <>; -- Comparable value type Value_Type is private; with function "<" (Left, Right : Value_Type ) return Boolean is <>; -- Function type with function Func (Argument : Argument_Type) return Value_Type; function Generic_Maximum_At (Left, Right : Argument_Type) return Value_Type; and the implementation function Generic_Maximum_At (Left, Right : Argument_Type) return Value_Type is Argument : Argument_Type := Left; Max : Value_Type; Value : Value_Type; begin if Right < Left then raise Constraint_Error with "Empty interval"; end if; Max := Func (Argument); while not (Argument = Right) loop Argument := Next (Argument); Value := Func (Argument); if Max < Value then Max := Value; end if; end loop; return Max; end Generic_Maximum_At; or you can choose to pass the function as an argument: generic -- Ordered argument type Argument_Type is private; with function Next (Value : Argument_Type) return Argument_Type is <>; with function "<" (Left, Right : Argument_Type) return Boolean is <>; -- Comparable value type Value_Type is private; with function "<" (Left, Right : Value_Type) return Boolean is <>; function Generic_Maximum_At ( Left, Right : Argument_Type; Func : access function (Argument : Argument_Type) return Value_Type ) return Value_Type; Or you can make it a package which is usually a better choice as one can pack into it several entities sharing the same generic interface: generic -- Ordered argument type Argument_Type is private; with function Next (Value : Argument_Type) return Argument_Type is <>; with function "<" (Left, Right : Argument_Type ) return Boolean is <>; with function "=" (Left, Right : Argument_Type) return Boolean is <>; -- Comparable value type Value_Type is private; with function "<" (Left, Right : Value_Type) return Boolean is <>; package Generic_Discrete_Comparable_Valued is function Maximum_At ( Left, Right : Argument_Type; Func : access function (Argument : Argument_Type) return Value_Type ) return Value_Type; -- Other useless functions end Generic_Discrete_Comparable_Valued; The generic classes of arguments/values can be in turn factored out into reusable generic packages: generic -- Ordered argument type Argument_Type is private; with function Next (Value : Argument_Type) return Argument_Type is <>; with function "<" (Left, Right : Argument_Type) return Boolean is <>; with function "=" (Left, Right : Argument_Type) return Boolean is <>; package Generic_Arguments is end Generic_Arguments; generic -- Comparable value type Value_Type is private; with function "<" (Left, Right : Value_Type ) return Boolean is <>; package Generic_Values is end Generic_Values; generic with package Arguments is new Generic_Arguments (<>); with package Values is new Generic_Values (<>); package Generic_Discrete_Comparable_Valued is use Arguments, Values; function Maximum_At ( Left, Right : Argument_Type; Func : access function (Argument : Argument_Type) return Value_Type ) return Value_Type; -- Other useless functions end Generic_Discrete_Comparable_Valued; -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de