First off, what would happen if "for var i := 0 to SomeCount - 1 do" always inferred i as Integer? It's possible I've never once used another type for an iterator. Not having to declare i over and over again would be nice too.
If start is qword($8f00 0000 0000 0001) and end is qword($8f00 0000 0000 0007), then that would not work with integer. Imagine something looping from a start-address to an end-address. (in virtual address space, otherwise those addresses don't really come up / but I have seen kernel addresses in the range $7ffff .................... .
As for "statements after list.free", sure that's a perennial problem is accessing freed memory which you still have but the scope nonetheless restricted even further to the problem area. Seems like a win to me.
Well, to me only if the scope was unreasonable big before. And then that problem also happens a lot outside of loops, where it is often much harder (or impossible) to limit the scope. So the "gain" (if any) is really only limited to a very specific subset of code.
Where as one could argue that in general the declare statements add code into the body, increasing its complexity (to the reader). So there even can be seen a loss.
I only brought up type inferring because it's another benefit of inline vars. Untyped vars in the declaration section wouldn't make sense to me because then what is their size? You could assign anything to them at a later time so I don't see how that works.
The inferring would happen when they are used/assigned the first time. It would then stick for the rest of the code. That is pretty much the same as what your example does. Only that the "reservation of the name" happens in a diff place. (and the scope changes / but that is unrelated to the inferring of the type)
Technically at least they do the same. Subjective there may be preferences.
Also don't forget Pascal infers types for constants so it's not that unnatural of an idea. Sure it's not exactly the same because they are converted upon assignment so if you want a specific type you can supply that.
I can't find the documentation....
But I think I read somewhere: numbers (123) have a type. That is hardcoded. So yes its converted when assigned to a variable. And I think (and that can be seen as questionable) that type may depend on representation (hex is unsigned, or isn't it ... really need to find the doc for it).
and the "const MYFOO = 1". well it isn't an assignment. ":=". it makes MYFOO a placeholder for "1". So then that has the same rules for its type.
But as I said, couldn't find the docs now. I may be wrong on this. Long way down memory lane.
I would never advocate for JavaScript syntax with no types at all. Just in obvious situations where you know the type and you don't want to change it like "var list := TList.Create". You know it's TList
But do you? I don't. It could be TObject for some reason. (I gave one earlier).
Of course, if it needed to be, it could be specified then and only then. But talk about making things simpler, if that means you get a complex rule set when you can have the type inferred and when not...
Another example: maybe that list should be an COM interface type? So lifetime is managed? So then when a class implement an interface (com interface) should the compiler always infer that interface type? Because that saves code down the line, doesn't it.
Also if you infer from factory methods, or from "type TFooClass = class of something" => then the type can change. And I know your reply will probably be, that inferring is perfect for that? Because it will follow that change....
Only if that new type does break the code.... And I don't mean in the sense of break compilation, that is easy to fix.
But it changes the functionality. Maybe something down the line called an overloaded function, or relied on a type helper? The new inferred type still finds something that it can be compiled, but it does something completely different....
Well again, happy bug hunting.