Hi,
Ryan Joseph wroteI want to do a pivot away from the macro stuff to ask another question.
Since I’ve wanted to contribute to the compiler for so long and I
finally have a little understanding I’d like to know if there’s anything
minor I could do, that isn’t offensive to the compiler team.
<rant>It's not about the compiler team. It's about the integrity of a programming language, which doesn't matter these days a lot, when all languages turned into a feature race to provide the same broken concepts, but with slightly different syntax. Nevermind. I sometimes do not even understand how people did stuff for 50 years without TObjectClassAdvancedTemplateGenericRecordRTTI...</rant>
What comes to mind first as being minor (or not, I don’t know) and
important are default record fields. Is there are reason this never
existed in Pascal? It’s in C++, C#, Swift etc…. and I use it often.
Because C# and Shift are managed languages, and C++ just includes everything for no good reason. And this is actually major, with far fetching implications. C++ is an utter mess for this, with the default initializer sometimes called and sometimes not, when you declare a variable of this type. Because if you pull the way computers work into the equation, it complicates things a lot. It matters where you define a variable of this type. On the heap, on the stack or on the global variable list, you have to compile different code for this, and you are probably won't be able to cover all corner cases. (Eg. what if you allocate this type with GetMem(sizeof(type))?)
Show quoted text 7 lines
The compiler added advanced records but making a static class method
which is hidden down in the implementation is annoying boiler plate I’m
sick of doing (plus calling it, or forgetting to). The new initialize
operator is the best alternative but again it’s boiler plate and adds
methods in the implementation.
Is there any reason we can’t do that? Is it a design choice?
It's a design choice.
In general, could you stop trying turning Pascal into C/C++? What C++ provides is mostly what is provided by advanced records (the useful subset). Except C++ allows writing the default initializer into the type declaration which then may or may not get executed, because C++ is a godforsaken mess.
What you can also do is, to declare the type, then declare a set of defaults with "const", which you can also write into the interface section. Then if you need a certain initialization for that type, just do it with an assignment.
var
myvar: mytype;
const
myvardefault: mytype = <initializer>;
begin
myvar:=myvardefault;
end;
In this case the compiler will even warn you, if you A., forgot to initialize the variable B., forgot to initialize a field in the initializer. I'm using similar pattern in my 3D engine, where I have various set of default vertices and matrices defined as consts, which are still the same type, and i can initialize them this way to whichever default I need..
If you need huge amounts of this construct, I would advise you to generate it as Michael said, which is what you would do with extended preprocessing or similar syntax sugar, like this one. It's just implicit code generation.
Charlie