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,63a41ccea0fc803a X-Google-Attributes: gid103376,public From: Matthew Heaney Subject: Re: Naming of Tagged Types and Associated Packages Date: 1998/07/30 Message-ID: #1/1 X-Deja-AN: 376281474 Sender: matt@mheaney.ni.net References: <6pdhfo$1br$1@platane.wanadoo.fr> <6pi0pf$df8$1@nnrp1.dejanews.com> <6pirk1$iar$1@nnrp1.dejanews.com> <6pknai$qst$1@nnrp1.dejanews.com> <6pl5rh$elr$1@nnrp1.dejanews.com> <35BF50B4.6FDCDDA0@west.raytheon.com> NNTP-Posting-Date: Thu, 30 Jul 1998 02:17:47 PDT Newsgroups: comp.lang.ada Date: 1998-07-30T00:00:00+00:00 List-Id: Chris Brand writes: > Matthew Heaney wrote: > > > > The types in the RM > > aren't named using _Type, so why do it that way in your code? > > Except, of course, Ada.Text_IO.File_Type. Good point. The reason (I think - the DRs will correct me if I'm wrong) for the the _Type convention for files has to do with "static polymorphism." "Static polymorphism" you say? Hmmm? How can polymorphism - usually associated with dynamic behavior - be static? Suppose we named type Direct_IO.File_Type "Direct_File", and suppose we named Sequential_IO.File_Type "Sequential_File". I've argued for this kind of thing in the past, but here's why it's a bad idea. I need a sequential file type, so I instantiate generic package Sequential_IO on my type, and then declare a bunch of instances: package T_IO is new Sequential_IO (T); use T_IO; procedure Op1 is File : Sequential_File; begin ... procedure Op2 is File : Sequential_File; begin ... procedure Op3 is File : Sequential_File; begin ... You get the idea. Everywhere where I declare a file instance, the type is named Sequential_File. Now, suppose that as a build the software, or a requirement changes (not unlikely), I realize that I need direct file access, not just sequential access. The means I have to do a new instantiation, and everywhere where there's a Sequential_File, there's now needs to be a Direct_File. If I'm lucky, the change might be in a single package body, and I can use a search & replace to do the change. But I might not be so lucky, and I might accidently change other file instances that shouldn't be changed. If I'm really unlucky, then the name might be spread across packages, and I have to change a bunch of code that causes a massive recompile on the entire system. You get the idea. The best approach is the not have to do any editing at all, and only change which file package is being instantiated. So let's use a neutral name like "File_Type", so that that all I have to do is make a single change - to change the instantiation from Sequential_IO to Direct_IO. All the file objects have the same type name. All the operations have the same signiture too, so no code needs changed. If I need to know the characteristics of a file instance (to determine whether it's sequential or direct), then I don't need to be reminded of this every time I declare an object. All I need to do is state that information once, at the point of instantiation of the generic file package. That is why the interfaces for Sequential_IO and Direct_IO are identical. It's sorta like deriving each file type from an abstract root type. Instead of refering to a class-wide type called Root_File'Class and doing dynamic dispatching on primitive operations, you refer to a "root type" called File_Type, and invoke primitive operations statically. I've written a data structures library that does this kind of thing. No, I did not create a type hierarchy rooted at Root_Stack, with different stacks deriving from Root_Stack. No (public) tagged types or inheritance were needed thank you very much. I simply have different kinds of stacks that are NOT part of a type hierarchy, but do have identical interfaces. Just like Sequential_IO and Direct_IO. Because I want a client to be able to easily change the code if he changes his mind about what kind of stack he needs (say, to go from a bounded stack to a dynamic stack with a statically allocated heap), I just named all the stack types Stack_Type. (Brian Rogoff must be smiling right now...) Just like File_Type. This does not mean, however, that you should name every type using the _Type convention. This is a big mistake, because then the convention would loose its value as an indicator of static polymorphism. For example, the active iterator for the Stack_Type is called Stack_Iterator. It's not just any Iterator_Type, it's an iterator for stacks, so call it that. This is exactly like file mode, which is not called Mode_Type. It's call File_Mode. Because it's not just any mode type, it's a file mode, so call they called it that. All the conventions you need are right there in the RM. You don't need to do anything different from the RM, because the DRs already figured it out. So take their advice about how to program in Ada, and do as the RM does. So I'll say it again: naming types "Instance" is a bad idea, for no other reason than that is not a convention that appears in the RM. (There are other reasons it's not a good idea, but those have been debated in other posts.)