AdaCore / ada-spark-rfcs

Platform to submit RFCs for the Ada & SPARK languages
62 stars 28 forks source link

[RFC] Final modifier #95

Open raph-amiard opened 1 year ago

raph-amiard commented 1 year ago

Link to text: https://github.com/AdaCore/ada-spark-rfcs/blob/topic/final/considered/final_modifier.md

Glacia commented 1 year ago

The whole idea of having "final" tagged type seems wrong to me. Doesn't the word tagged implies it has a runtime tag? So with final keyword you're kinda trying to untag tagged type. Here is an idea: How about allowing regular record types to be derived within a package? Kinda like this:

package Game is
   Type Player_Base is 
      record
         Health : Positive := 100;
      end record;
   type Player_Mage is new Player_Base with -- Player_Mage has Health too!
      record
         Magic_Points :  Positive := 100;
      end record;
end Game;

Combined with https://github.com/AdaCore/ada-spark-rfcs/blob/master/considered/rfc-prefixed-untagged.rst you'll get pretty much the same thing as tagged final, no? Am i wrong?

raph-amiard commented 1 year ago

@Glacia Sealing tagged types doesn't imply they don't have RTTI anymore, just that it cannot be extended from outside the package. You still have access to the tag, via dispatching primitives, or introspection.

You could see it as very similar to a discriminated record, where the discriminant is the tag. Actually the two are isomorphic. However, there are various reasons the second can be useful rather than the first:

  1. If you provide an API to outside users via a library, you might want internal developpers of your library to be able to derive from a base class and create new cases, potentially in different packages, but never allow outside users to derive from any of your classes. In that case, you can "seal" all the leafs of your derivation tree

  2. You might want to derive from an interface provided by a library, or even a base class. That doesn't mean that you want people to be able to derive from your implementation. In that case, you can seal it.

  3. For various reasons, today in Ada, tagged types might be a better fir for your API than a discriminated record (Libadalang is an example of that). You still don't want people to be able to derive from your hierarchy.

That's it :) Tell me if you need more info/examples, I'll be glad to add them