Michael Van Canneyt wrote 15 lines
Well, in
Var
A : Integer;
The 'Var' is strictly speaking also redundant, as the : is used only in
variable declarations. But the 'var' makes it easier to read, and Pascal is
a verbose language. Additionally, the parsing is easier to do, as you know
what to expect next. By that rationale, the 'generic' keyword was deemed
appropriate when FPC made it's implementation.
We'll resolve the incompatibility - remaining backwards compatible to FPC
itself - when someone finds the time and desire to do so.
Or when someone from our beloved users sends us a patch to this effect.
Michael,
Actually, you are pretty far off. I've written a few parsers for Delphi and before generics it has ALWAYS gone like this:
// comments are considered transparent
After: {unit|program|library} ident ; [interface] [uses section]
Next must be either: {block|function/procedure|section}
A block always starts with one the following keywords: {var|const|type|resourcestring}
A section can be one of the followings:
[implementation|initialization|finalization]
When block is detected {var|threadvar|const|resourcestring|type} it always goes like this:
block
ident {:|=} body [end];
{repeat above flow|{block|function/procedure|section}}
A block example:
const
// okay, starting a new block {const}
// next parsed token must be an ident
// repeat *NEXT TOKEN MUST BE* an ident
WM_SOMETHING
// okay, got ident
// in {const} block next token must now be =
=
// next tokens must a constant expression
WM_USER + $FF
// okay we read a constant express
;
// okay, terminated
// now expecting {ident|[block|function/procedure|section]}
WM_OTHERTHING = WM_SOMETHING + 1;
WM_LASTTHING = OTHERTHING + 1;
var
// okay, starting a new block {var}
// next parsed token must be an ident
...
So this has always been the case. When the parser encounters {var|const|type|resourcestring} in the context of creating a new block, the next token is always, ALWAYS an identifier.
type
// okay, starting new block {type}
// next token must be an identifier
TTime
// okay, got ident
// in {type} block next token must now be =
=
// next token must be one of the following
// {ident|array|class|record|set|(|type}
Double
// read ident, verify value refers to an already typed ident
// next token must be ;
;
// okay, terminated
// now expecting {ident|{block|function/procedure|section}}
TPoint = record X: Integer; Y: Integer; end;
Go it? So whenever you have {var|threadvar|const|type|resourcestring} in the context of creating a block, the next token will always be an ident, or the code is invalid.
You've always had the case where
program A;
type
// the next thing read must be an ident
That's how it's always been. Delphi has always been about {block|function/procedure|section}.
Block has ALWAYS been like this:
block
ident {:|=} body [end];
{repeat above flow|{block|function/procedure|section}}
Putting the word "generic" infront of the ident breaks the long established trend.
type generic TList<T> = class end;
See, we started a block {type} and introduced a keyword {generic} before the identifier {TList}. This unnecessarily breaks the pattern and is inconsistent.