Hi, all I'm making a plea for supporting a feature that's been debated already, but I feel is sorely missing, and hampering FreePascal in both short and long term, as it's getting established now: inline variable declaration with type inference.
Key scenarios where it is a major improvement vs legacy Pascal.
1. Loop variables"For" loop variables are a perfect fit, as declaring loop variables leads to ambiguity. The loop variable being undefined after the loop being a documented code smell (
https://wiki.freepascal.org/For#Loop_Completion).
But local loop variables also don't make sens to be visible outside the loop: they only open up opportunities for errors and readability complexity, I'm referring to things like "item" in the legacy form of
for var i := 0 to someList.Count-1 do begin
var item := someList[i];
...
end;
where inline and scoped declaration makes everything easy to understand and debug, as it's all local.
2. Simplifying long expression and function callsBeing able to introduce easily a tight-scoped variable can be a massive boost on readability AND debuggability
begin
var x := ...some longish expression that computes x...;
var y := ...some expression with side effects that computes y...;
MyFunction(x, y);
end;
Even with just two variables, the above code allows to spread parameter evaluations cleanly, and it becomes trivial to breakpoint the code after a particular argument is computed and eval the value.
It also brings to the table the ability to name the argument, which can be a significant boost to code readability for functions with many parameters, or functions you're unfamiliar with the order of parameters.
3. Record initializationRather than the legacy variable + fillchar dance, with risk for error and need to read multiple lines of the code, you can just do
var myDescriptor := Default(TSomeDescriptor);
myDescriptor.Field:= 123;
...
I took the descriptor structure exemple, as it's common in APIs. The inline declaration makes everything local and obvious to whoever will read the code.
4. Elimination of the "catalog of variables" anti-patternEvery function implementation where you have many variables (like in the above points) quickly becomes a massive catalog of variables declaration, followed by implementation. This declarations are not visible without scrolling, and since you have many of them, they're not always readable.
When faced with unfamiliar code, the catalog anti-pattern can also make it non-obvious what a symbol is when reading code: is it a local variable ? an argument ? a property ? something else ?
This can be alleviated by prefixing symbol names, but there will still remain a degree of ambiguity about variable type and scope (esp with nested functions, anonymous procs, where the prefixing is not enough).
Bringing the declaration close to usage just cleans everything up, and makes local portion of code readable and understandable in isolation, which is a huge boon.
5. Avoiding uninitialized variablesI'm placing this last because the compiler can help here, so it's not always fatal. Though there will still be a degree of ambiguity when a variable is passed by reference, or when a variable goes out of logic scope, since it can't get out of compiler scope.
Using nested functions is the only mitigation with legacy Pascal, but it's like using a hammer to swipe a mosquito, and it can be detrimental to readability, as it will break the flow of code.
Final wordYes, inline variables place an extra burden on IDE and debug tools, but they also lift burdens from the shoulders of developers, especially when reading and debugging code.
For full disclosure, I've been using inline variables declarations in Pascal for 15 years, since I introduced them in DWScript. It took a long time for Delphi to catch, but that was years ago.
Hoping for FreePascal to make its move!