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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,47def5aa7b3182bd X-Google-Attributes: gid103376,public From: Samuel Mize Subject: Re: (long) programming by extension Date: 1999/02/24 Message-ID: <7b22f5$1mrg@news1.newsguy.com>#1/1 X-Deja-AN: 448112800 References: <79fct8$9k3$1@murdoch.acc.Virginia.EDU> <1103_918264881@DZOG-CHEN> <36cdb012.580716@news.pacbell.net> <7av52o$62g@news3.newsguy.com> <7avc0i$cnb$1@its.hooked.net> <7b1kdb$13k6@news3.newsguy.com> Organization: ImagiNet Communications, Ltd. User-Agent: tin/pre-1.4-981002 ("Phobia") (UNIX) (AIX/3-2) Newsgroups: comp.lang.ada Date: 1999-02-24T00:00:00+00:00 List-Id: The example I used to describe programming by extension is also used to describe object-oriented programming. So it was a poor choice to show the difference. However, there IS a difference. I'll try again. Suppose you are coding a message handler which will get messages in one format from many interfaces, some of which are not yet known, and perform some complex computation. You can define each interface to have a "get" procedure, and use a tagged type to pick the right "get." package No_Interface is type Use_None is tagged null record; type Interface_Selector is access all Use_Nothing'Class; -- this will raise an exception if called, -- or maybe return a default value procedure Get (Interface: Use_Nothing; Message: Data_Format -- defined elsewhere ); end No_Interface; - - - - - - - - - - - - - - - - - - - - - with No_Interface; package Disk_Interface is type Use_Disk is new No_Interface.Use_None with null record; procedure Get (Interface: Use_Disk; Message: Data_Format); end package; - - - - - - - - - - - - - - - - - - - - - with No_Interface; package Serial_Interface is type Use_Serial is new No_Interface.Use_None with null record; procedure Get (Interface: Use_Serial; Message: Data_Format); end package; - - - - - - - - - - - - - - - - - - - - - with No_Interface; use No_Interface; procedure Message_Handler (Current: Interface_Selector) is D: Data_Format; begin -- some complex computation involving several records for I in whatever_range loop Get (Current.all, D); ... if D.Continued then Get (Current.all, D); ... end loop; end Message_Handler; In no case will the type Use_[whatever] contain any data. You can add interfaces as you need to, and never have to recode -- or even re-compile -- Message_Handler. I would certainly NOT call this object-oriented programming. It's sort of an "infinite case statement." But it does take advantage of the Ada 95 facilities for programming by extension. In a real-world application, something as significant as a major device interface probably WOULD be coded as an "object," if you're using object-oriented technology. This is a contrived example. I HAVE used tagged types to generate such an "infinite case statement," but it was buried in an obscure and proprietary system, so it would be neither clear nor legal for me to reproduce the code. Best, Sam Mize -- Samuel Mize -- smize@imagin.net (home email) -- Team Ada Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam