Search code examples
delphirecordanonymous-types

Language question: record field with an anonymous record(?) as type...?


I'm still learning Delphi/OP and stumbled upon the below (simplified) code that's part of an exercise in an old Delphi book.

type
  TMyRec = record
    FField1: Integer;
    FField2: String;

    FAnonRec: record
      FAnonField: Integer;
    end;

    FField3: Boolean;
  end;

My main question is:
1. What would FAnonRec - or rather, it's type - be called, in language terms? How do I refer to it? Something like record field of anonymous record type...? Just constructed type...? - I googled my question for some time but kept getting results about ancient Greek history... The closest I found was this error explanation.

Further questions:
2. In general, what is this type of construction called ("creating the type" right then and there instead of using a pre-declared named type)? - regardless of whether it's used as in the example or in a var block or even if no record is used.
3. The "Structure" tool in Delphi only shows FField1 and FField2:
delphi structure
- yet the "Class Explorer" tool shows the entire record:
Image
- anybody know why?
4. Point 3 and the fact that this is from an old book and the fact that I have a hard time finding any more info about it make me wonder whether that kind of construction is maybe outdated/discouraged?


Solution

  • I would call it a "nested record type definition". It exists since the beginning of Turbo Pascal IIRC, and has nothing to do with "anonymous methods", introduced recently (at least in this century), which is a much more complex beast, since it grabs some execution context with it.

    I don't see any reason why it may be seen as outdated or discouraged. It is a perfect valid structure, which makes sense, from the code point of view, since it gather some fields in a logical parent field. Of course, if you expect to access it independently, a dedicated type definition is worth it. Performance will be the same, it would be just more convenient if YAGNI (less typing, whole record seen at a glance).

    So you can start by writing such nested records, then define a dedicated type when needed - e.g. if adding some methods could make your code more readable and maintainable. In practice, using nested records in type definitions could reduce eventual code change in your code base, since adding an explicit type definition later on won't break the way to access its members from existing code.

    Note that there is RTTI for it, as a stand-alone record, named after the "main" record (something like '__TMyRec_FAnonRec'). So from the RTTI point of view, it is not anonymous. ;)