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,56131a5c3acc678e X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-11-26 18:10:25 PST From: "Ekkehard Morgenstern" Newsgroups: comp.lang.ada Subject: Re: Question about OO programming in Ada Date: Thu, 27 Nov 2003 03:10:28 +0100 Organization: 1&1 Internet AG Message-ID: References: NNTP-Posting-Host: p508c12e5.dip0.t-ipconnect.de X-Trace: online.de 1069899024 4398 80.140.18.229 (27 Nov 2003 02:10:24 GMT) X-Complaints-To: abuse@einsundeins.com NNTP-Posting-Date: Thu, 27 Nov 2003 02:10:24 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 Path: archiver1.google.com!news2.google.com!fu-berlin.de!news.belwue.de!news.uni-ulm.de!rz.uni-karlsruhe.de!feed.news.schlund.de!schlund.de!news.online.de!not-for-mail Xref: archiver1.google.com comp.lang.ada:2975 Date: 2003-11-27T03:10:28+01:00 List-Id: First of all, thank you very much for that elaborate reply! :-) I had to print it out and read it twice to understand it, but it was very much worth it! :-) Today I rewrote all my packages to be generic and not use a single access type! Of course, I had to do away with linked lists. Instead I defined a parameterized Vector (array) class. Not only has the source become thrillingly short, but also very easy to handle and inherit from. :-) This will be sufficient as a foundation to build upon, until I receive the book "Programming in Ada 95" that I ordered a couple of days ago. :-) I will try to follow the advice you've given and hide the use of access types, if I really them, inside the private part of the packages affected. But I have a few more questions, so it'd be great if you could answer them. :-) "Robert I. Eachus" schrieb im Newsbeitrag news:GpednY19wYJAdFmiRVn-gg@comcast.com... > That is complex enough to deserve an example. Thanks for the example, it gave me a good insight into the matter. :-) > abstract function Register(Owner: in out Person'Class; > The_Vehicle: in out Vehicle) > return Registration'Class; > > Perhaps when you finish, you will end up returning a Registration_Ref, > but so far it isn't necessary to make that type public. (Notice that > you can always write Register(Someone, Car)'Access, if you really need > to get an access value to assign to a Registration_Ref, or in some cases > Register(Someone, Car)'Unchecked_Access.) Thanks. That's good to know. What does "Unchecked_Access" do? > Later you will write (child) packages to deal with cars, trucks, buses, Why child packages? Does the package hierarchy matter for derived classes? > ride motorcycles. This can be determined by nested dispatching, or more > usually by "if Owner in Motorcycle_Driver'Class then..." This is really a great feature! So I can practically test if any object is a member of a particular class, or set of classes? I read in the OO part of the Rationale that a classwide type is actually represented internally with a set of key/value pairs, right? What kinds of other applications does that have? > But the second instance, the use of a classwide result type is more > interesting. This is not to cause dispatching, but to actually return > an object whose class is not known at compile time. A typical usage is: > > procedure Something (...) is > The_Registration: Registration'Class > := Register(The_Owner, The_Vehicle); > begin > -- further operations on The_Registration, which may involve > -- dispatching calls. > end Something; I still wonder if The_Registration is actually a reference, or is it the object returned by Register()? I.e. if I wanted only a reference to the object, would I have to use an access to Registration'Class? I wonder about this stuff because I'd like implement a linked list package, which provides one set of subprograms for all types of derived linked lists and list nodes. Now, if I had a function like this: function Next( N : in out Node'Class ) return Node'Class; (btw, is it ok to use "in out" in this case with a function?) Can I return an object of type Node'Class, or do I have to return an access to it? And the Node implementation, can it look like this: type Node is tagged limited record Succ : Node'Class; Pred : Node'Class; end record; I gather from previous discussions that Node'Class represents an actual object, not a reference to it, so I'd have to use access types in this case, which would give type Node_Ref is access Node'Class; type Node is tagged limited record Succ : Node_Ref; Pred : Node_Ref; end record; Or do I err? If I use the latter version, and keep the function Next() as defined above, would the object be copied when it is returned? Or is that precluded by the fact that it's a limited type? But if I modify Next() to be something like function Next( N : Node_Ref ) return Node_Ref; how can I avoid casting N and the return value from a derived class? What's the optimal way in Ada to do this? > > First of all, how do I accomplish returning a reference in Ada? > > Whether an object is passed by value, value-return, or reference depends > on the object's class, not on whether the parameter is in, in out, or > out. In parameters can be referenced but not changed, in out parameters > can be referenced and changed, and for out parameters the attributes are > defined at the point of the call, but there may not be an initial value. But what about return values from functions? Or does the return value in a function correspond to an "out" parameter in a procedure? > > i.e. the difference between > > > > procedure Proc( Param : in out Type'Class ); > > > > and > > > > type Type_Class_Access is access Type'Class; > > procedure Proc( Param : in Type_Class_Access ); > > Not much. Or rather, using the second form unnecessarily is a sign that > you are new to Ada. Yes, I am, but I'm trying to get things right! :-) > There are cases where the access parameter won't > cause any additional difficulties, and other cases where it will mean > that you need to explicitly free the storage to avoid memory leaks. Yeah, I know that problem can be addressed by creating an instance of the Unchecked_Deallocation procedure. BTW, how do I use the Finalization package? I'd like to use things like constructors and destructors sometimes to be able to initialize / cleanup objects when they're created or destroyed. > If you pass objects instead of pointers, you eliminate the potential > memory leaks. That's true and a grand feature of Ada because it does away with bookkeeping on the programmer's part in general. For now, I'm using arrays where possible instead of lists, which can be parameterized in generic packages. Then I only need to create an instance of that package for the application in question, and multiple instances if necessary. :-) I'm really surprised how short my source code has become. It's just the way programming's meant to be that I can concentrate on the key tasks at hand. :-) Generic packages remind me a bit of C++ templates, but generics are much more powerful. :-) What I also find very useful is the renaming of packages / procedures etc. Does that have any impact on dispatching or inheritance (in the case of renaming procedures)? BTW, can I instantiate a generic package in a procedure body (initialized with a value passed as a parameter)? (I didn't try yet) > This doesn't mean you shouldn't use pointers (access > types) where appropriate. But in Ada a good rule is that you only use > explicit access types to create data structures. And since you normally > use abstract data types to implement these structures, the notation is > limited to the private parts and bodies of a few packages. I will have to try that with my doubly-linked list problem. Does it really change much if I use abstract Nodes and Lists in the example I gave above? The problem with arrays is that they need to be preallocated to a particular size, which can consume a lot of memory. Lists and Nodes occupy only the memory that they actually use. And which method is faster? > (And you > probably chose those packages from a library instead of "rolling your > own.") What kind of library would you recommend to me? I'd need some linked lists, queues, containers and so on, but I'd like to have versions that are completely generic. I could write them myself, and I probably have to, because I need to limit the amount of third-party software that I use. I plan to use Ada for a major software project in which I might even have to implement an Ada compiler for a virtual machine that I've designed myself, and which I might also implement in Ada. That's why it's very important to me to do my packages right, right from the start, because I perhaps cannot change the design after building up on it. > But sometimes you need to create your own interlinked data > structures, as in the example of Persons, Vehicles, and Registrations. > In those cases, you can use different data structure packages, written > as generics to implement some of the data structures you need. Indeed, generics seem to be a very powerful feature in Ada that can be used in a lot of ways. > Incidently, this is my problem with a set of data structure packages as > a part of Ada. There are several ways to implement these structures in > Ada, and which one you want to use depends on intimate details of the > problem you are trying to solve. So a limited set of official solutions > IMHO would be worse than the current situation. (A core set of data > structure packages in the standard, plus an indication that compiler > vendors and others are encouraged to extend the set is a different story.) That's ok. It isn't really all that much code to write such things like lists, queues, stacks, etc., but of course it would be neat to have them in the Ada package, because they're constructs frequently used. > Don't cheat yourself. It is possible to subset Ada's support for > object-oriented programming to match what you currently know about the > subject from C++ or some other OO languages. But the Ada model is much, > much richer than that. A lot of this richness involves information > hiding. Yeah I agree. Like in any language, getting a grasp of the language features might take some time, but it's worth it, of course! :-) > In Ada you constantly find yourself asking two questions: > > What is the minimum required information to use this subprogram, > data-type, abstraction, and so on? Yeah, I already noticed this today when I rewrote my classes to use generics. They're only a fraction of the code size they were before. :-) > > and: > > Is there a different way to express this which allows more > information hiding? > > Why this emphasis on information hiding? The converse of information > hiding is coupling. The more coupling you have, the more bugs you have, > the bugs are harder to find, and fixing bugs is more likely to create > additional bugs. So maximizing information hiding is the easy way to > bug free programming. Yeah, that's true, the more you encapsulate and abstractify classes and packages as black boxes, the more universally useful they get. :-) > Yes. Ada is trying to tell you something. In Ada the intent is that > cleaner means better. If you are converting back and forth all over the > place, it means that your programming model is not well thought out. How do I avoid casting access types between derived classes? > Quicker is possible, but tough. We used to say that learning Ada was 5% > learning syntax and 95% learning software engineering. It's true that learning Ada simple, especially for people who already know other programming languages. I can't believe how much I learned in only a couple of days. Software design is not my problem, it's what I've been doing most of my life, so it's a piece of cake now that I have Ada. :-) (Ada can really save a LOT of typing! Just because it has such powerful constructs. I don't mind at all typing away at packages and stuff knowing I'd need 10 times the source with C++ or more even with C) > Then along came > Ada 95. It cleaned up a lot of special cases to make learning how to > program in Ada easier, and added support for several powerful new > programming paradigms. My guess is that Ada 95 made learning the > language somewhat easier, but tripled the amount of software engineering > you need to know to use the whole language. You can see that above, > with delegation of dispatching, multiple dispatch, and returning > classwide objects. Those are just from the object-oriented extensions > in Ada 95. Yes, but you don't really need to know about all these things to program in Ada, and that's really a good thing. You can get along well with basic constructs, and the more intricate details of the language can be postponed to be used later when necessary. > I could probably teach a one semester course on how to use child > packages in Ada, and then follow it with a semester on generic package > parameters in Ada, or a semester on real-time programming in Ada, or a > semester on high integrity programming, oops make that at least two > semesters! I could also probably create a year long course on how to > use access discriminants in Ada, but IMHO, maybe 30 people world-wide > need to know all the tricks of using them. (Maybe a course on when it > looks like you need to use access discriminants, but don't?) You can put me on that list for some later point in time. ;-) I hope I can get back to you with my questions when I have to write an Ada compiler and run-time system. Perhaps my understanding of the language will be real good by then, but I might still need detailed information about how things are supposed to be. > > English is a foreign language to me, and I'd rather not > > read umpteen pages of Ada language theory when I can avoid it! ;-) ) > > Hmmm. There should be some good Ada reference material auf Deutch, but > I don't know what offhand. (And at this point I'm not going to go back > and rewrite the above. ;-) Yeah, that'd be a lot of work! ;-) I haven't looked yet for some German-language Ada resources, but I don't really need them right now. It's a shame, I found no Ada books in German for beginners on Amazon. But I prefer reading the English language versions to German translations anyway. :-) > 100% Ada, no bugs--the only way to create software. That sounds promising! :-) I hope I'll be able to write all my future software, at least in my private projects, in Ada. It has a lot of features I always wanted in a programming language. And it's a great programming language concept anyway, mature and tested! (I came up with similar designs on my own and found Ada by curiousity, recalling a hint that someone gave to me over ten years ago.) Ada is indeed the best programming language I've ever seen and it seems to be relatively easy to write a compiler for (like, compared with C++), because of the logical and well-defined structure. And it has many features that I haven't found in any other language yet, like value range checking and arbitrary numerical types, and parameterizable packages. All of Ada's features are very promising for the development of well-designed bug-free software. :-) (because, you know, I'm not worried about myself there, because I can write bug-free software in any programming language, but if I write a development environment with its own language, I want to choose a language that enforces or at least encourages bug-free programming for those less experienced than people like me, also, and Ada seems to be the ideal choice! Even if I support other languages -- if my VM is designed for Ada, and Ada is the prime language for it, then all other languages can benefit from it as well.)