I think it's desirable some kind of lightweight class without all the bloat like a
TVoidClass and TObject should derive from the TVoidClass.
There is no desire to change or extend the object model. If you need something lightweight use object.
It's not the same and you know it. Object won't be developed further. It has not the sugar candy syntax. It's stacked, not in heap.. Same you said that it's a bad idea being with objects because their limitations can't be offered as a similar solution. It's not the same and it hasn't the same priority. And are useless in Delphi (embarcadero deprecated them).
And it's a bad idea two types of coding (for objects) and for TObjects. Duality for same things is allways bad idea. Telling that use object instead of making a voidheap one is a straw man argument.
https://en.wikipedia.org/wiki/Straw_manThis argument will be acceptable if object would hace exactly the same functionality, nor less as a heap object and being sugar-sintax in heap and fully mainteinance. Object its even an antecesor of record with methods. It's an ancient way of doing things and not a supported one. Would you advise to ANY who is starting with fpc to use objects or classes? You will answer: go for classes. So no room for : Go for objects as an advice.
TObject is half bloated, half hacky and full oversized for nearly 99.9% of uses.
First: if smartlinking is enabled (default on Windows) any non virtual methods of TObject are removed.
Second: nothing there is hacky, it's simply a type that makes use of the low level information generated by the compiler, that's why it's a core type of the RTL.
Third: It's not oversized for 99.9% of uses, because the LCL makes use of nearly all the functionality provided by TObject to provide all the functionality we know and love and LCL usage is clearly more than 0.1%.
First, smartlinking only removes interface ones (below). The other are class functions that could viewed as compiler constructs and being out of class scope or in the class scope (but this is taste) -> This is RTL not a part of a class. And should be the class designer if use it or other compiler info. Give TObject as is, and let a void one to be generated as object with the same funcionality as object and fully maintained. And it's how an academic OOP should be. Why is this change problematic?. It's making the actual model to an universal, fully academic supported and fully compatible with existing code. This can have many views. One can have (by sugar sintax) define that class-RTL methods could be in all classes (like in a void class)-> example
(MyAscendant:=TFooClass.ClassParent) or as (MyAscendant:=ClassParent (TFooClass); And i could argue the later can have advantages too. could you do this with an object. NO.
But the main question is
why is difficult or not viewed as neccesary a Void object which should be the academic root to start working and gives tools to do other things and not Lazarus-delphi ones? I think it's a autoimposed limitation.
Second, better not doing a smartlinking job when you don't need to smart link if better defined.
Not too much gain...
TObject = class
public
{ please don't change the order of virtual methods, because
their vmt offsets are used by some assembler code which uses
hard coded addresses (FK) }
constructor Create;
{ the virtual procedures must be in THAT order }
destructor Destroy;virtual;
class function newinstance : tobject;virtual;
procedure FreeInstance;virtual;
function SafeCallException(exceptobject : tobject;
exceptaddr : codepointer) : HResult;virtual;
procedure DefaultHandler(var message);virtual;
procedure Free; class function InitInstance(instance : pointer) : tobject; {$ifdef SYSTEMINLINE} inline; {$endif}
procedure CleanupInstance;
class function ClassType : tclass;{$ifdef SYSTEMINLINE}inline;{$endif}
class function ClassInfo : pointer;
class function ClassName : shortstring;
class function ClassNameIs(const name : string) : boolean;
class function ClassParent : tclass;{$ifdef SYSTEMINLINE}inline;{$endif}
class function InstanceSize : SizeInt;{$ifdef SYSTEMINLINE}inline;{$endif}
class function InheritsFrom(aclass : tclass) : boolean;
class function StringMessageTable : pstringmessagetable;
class function MethodAddress(const name : shortstring) : codepointer;
class function MethodName(address : codepointer) : shortstring;
function FieldAddress(const name : shortstring) : pointer; { new since Delphi 4 }
procedure AfterConstruction;virtual;
procedure BeforeDestruction;virtual;
{ new for gtk, default handler for text based messages }
procedure DefaultHandlerStr(var message);virtual;
{ message handling routines }
procedure Dispatch(var message);virtual;
procedure DispatchStr(var message);virtual;
{ interface functions }
function GetInterface(const iid : tguid; out obj) : boolean;
function GetInterface(const iidstr : shortstring;out obj) : boolean;
function GetInterfaceByStr(const iidstr : shortstring; out obj) : boolean;
function GetInterfaceWeak(const iid : tguid; out obj) : boolean; // equal to GetInterface but the interface returned is not referenced
class function GetInterfaceEntry(const iid : tguid) : pinterfaceentry;
class function GetInterfaceEntryByStr(const iidstr : shortstring) : pinterfaceentry;
class function GetInterfaceTable : pinterfacetable; { new since Delphi 2009 }
class function UnitName : {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};
class function QualifiedClassName: {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};
function Equals(Obj: TObject) : boolean;virtual;
function GetHashCode: PtrInt;virtual;
function ToString: {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}ansistring{$else FPC_HAS_FEATURE_ANSISTRINGS}shortstring{$endif FPC_HAS_FEATURE_ANSISTRINGS};virtual;
end;
end;