Since ~Delphi 2010, we have had generics, attributes, iterators, and some other compiler niceties. While many of the features we would like are difficult to implement, I believe that a few simple language features are long overdue.
There are dozens of more things I'd like to see in Delphi, but here I will cover the ones that are easy to implement, yet provide large gains.
Block Level Variable Declarations
Most compilers just declare block level variables internally as normal locals, i.e., it's just syntactic (but very useful!) sugar. It could even be done with a pre-processor but that would be hacky and affect the debugger.
The easiest way is scan for block vars. They internally treat them as locals. But add a prefix of suffix of otherwise unusable characters and give each block an ID.
So for example, give each block a number, 1, 2, 3, 4... then for each block var, internally just make it name$1
or something. Very easy to implement with very little impact to the compiler.
procedure Test();
begin
for var c:string in List do begin
...
end;
var d:TStrings = TStringList.Create;
var x:integer = 7;
for var f:integer := 1 to 10 do begin
var x:integer = 5;
...
end;
end;
Type Inference
function Foo(): integer;
var
x = 1;
xList = TStringList.Create;
begin
...
for var x in xList do begin
...
end;
end;
Using Statement
A try with an implicit finally free block.
Let me show you how this would alter existing code:
class function TMyWriter.ToString(aSrc: TRoot): string;
var
xStream: TStringStream;
xWriter: TWriter;
begin
xWriter := TWriter.Create(aSrc); try
xStream := TStringStream.Create; try
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
finally xStream.Free; end;
finally xWriter.Free; end;
end;
With using:
class function TMyWriter.ToString(aSrc: TRoot): string;
var
xStream: TStringStream;
xWriter: TWriter;
begin
using var xWriter := TWriter.Create(aSrc) do begin
using var xStream := TStringStream.Create do begin
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
end;
end;
end;
Auto Free
This, of course, applies to the Windows compiler, not the ARC based ones. Someday, the ARC compiler will reach Windows as well, but until it does, this solution is simple and helpful.
There are possible alternate syntaxes as well, but the main desire is for the functionality. The exact name of the keyword isn't that important either. Auto is simply shorter to type thatn autofree, dynamic, finalized, etc.
procedure Test2();
var
x: integer;
y: TStrings = TStringList.Create; auto;
begin
...
auto z = TStringList.Create;
...
end;
Let me show you how this would alter existing code:
class function TMyWriter.ToString(aSrc: TRoot): string;
var
xStream: TStringStream;
xWriter: TWriter;
begin
xWriter := TWriter.Create(aSrc); try
xStream := TStringStream.Create; try
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
finally xStream.Free; end;
finally xWriter.Free; end;
end;
With auto:
class function TMyWriter.ToString(aSrc: TRoot): string;
var
xStream: TStringStream; auto;
xWriter: TWriter; auto;
begin
xWriter := TWriter.Create(aSrc);
xStream := TStringStream.Create;
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
end;
Or when combined wtih block declared variables:
class function TMyWriter.ToString(aSrc: TRoot): string;
begin
auto xWriter := TWriter.Create(aSrc);
auto xStream := TStringStream.Create;
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
end;
Ternary Operator
It is quite hard to believe Delphi is over 20 years old and we still do not have a ternary operator. Syntax can vary, but the long used one among other langauges can be easily adapted to Delphi:
xValue := xCondition ? 'one' : 'two';
A commenter also suggested looking to Scala for a more Delphi like syntax that I liked as well:
xValue := if xCondition then 'one' else 'two';
Conclusion
With these simple additions, Delphi would be far easier to write code in without losing any functionality.