The main point of generics is to avoid copy and paste.
I don’t think they are close to macros at all. C macros are horrid. Aside from a differing parameter format which takes some getting used to. Generics read just like standard Ada code. “Production scale” doesn’t make any sense to me. You should use them in the best ways at any scale. If readability suffers then don’t use generics. Repeating yourself can be the best way. I don’t have much experience with Generics but personally I would use them sparingly in any case.
Booch 83 components are perfectly readable standalone and re-usable. Actually the nested procedures that he sometimes used are more of a readability issue than generics atleast to someone who has learnt Adas generics syntax.
Correct, that is idea of all pre-processors. C, PL/1, Ada generics, C++ templates etc.
That is the point. Generics are harmful in software engineering.
Because it is a set of insulated packages, just like the standard Ada library or Simple Components. Generics are nice there, but these libraries simply do not represent the case of software decomposition.
The first cases for OO were operating systems, I remember RSX-11M kernel code written in Assembly in a highly OO manner (call vectors etc) though nobody would called it so that time.
The morale is, how deep you fall, even in Assembly OO decomposition is the way one you face a real software engineering problem.
You do not understand. There is simply no other way. When you, say, load a driver, it is same as overriding primitive operations of a tagged type. Be it in Assembly or in an OOPL. You have some vector of entry points to fill logically equivalent to a dispatching table. No way you could do that with puny subprograms.
It is relevant to choice between Assembly/C and an OOPL. It is much more readable to do OO in an OOPL. E.g. GTK’s GObject re-implements OO in C, not much fun to see or use.
But the point was that you cannot decompose OS drivers or GUI widgets into procedures. Yes, it is all Turing-complete, but a design identifying abstractions like driver or widget is not possible with procedures.
arrives to the specific driver? How the OS user is supposed to know which procedure Write from which driver package to call given the file? The file number I should say since we want to keep it nicely procedural…
Hint: The user does not know or care, it is called dynamic dispatch.
You surely prefer to change whole program when writing COM1 instead of COM2 and having separate terminal console for each COM port, each USB device, each possible IP address for each network adapter each PCI slot…
How much disk space you would need to have that. Wait, you prefer a copy of everything for each combination drive x SATA port.
It takes two seconds to do a search and replace and the code is more readable. Tagged records affect the size and don’t work well with drivers anyway. It would be nice if Ada had a form of generics that would also catch differences between peripheral records such as Timers potentially being very different at compile time such as when the chip in use changes with different Timer_2 registers (e.g. a list of certain types with some matching record components accepted as a parameter instead of static predicates with some code duplication). Without variants that are incompatible with Spark on volatile record overlays.
Go has interfaces without inheritance but I’m not a huge fan of those either.
My code is application specific but I wouldn’t use inheritance with the Linux kernel either. I’m sure it would be rejected anyway. I wonder if Rust was accepted partly because it doesn’t.