If freepascal implemented inline vars, it would not force them (I hope!); that is the key.
Everything that is added, is always forced on everyone.
I may not have to type it myself. But I can not shut the world out, so I will have to read it, because someone else used it in their code.
Regarding duck typing, the IDE Ctrl+Shift+C *does* duck typing, and even the CONST sections of a pascal program **is** duck typing. It cannot be so bad, if used when useful and avoided when it is ambiguous.
Both are different.
Codetools is a once off. And hopefully checked once by the user. It does not follow
and break the compiled app, if something else changes in type. (see example before)
"for" loops are one of the biggest examples for inline vars (including those with duck typing) => And the example shows how vulnerable it makes the resulting code.
Sure, if the "cnt" function was cardinal to start with, codetools would create a loop counter of type cardinal => but at least that would be declared on the variable. I get a chance to notice it. If the function was in another unit, I would never notice it, until I spent good time to debug the app because it doesn't work (if I noticed, before I shipped to the end user).
And if, that feature is added, then every bit of 3rd party code that I ever used becomes less reliable, because the author may have used that feature, and it may have introduced bugs, that you couldn't have before. (And that is for all the examples I gave, not just inline+duck, but also inline on its own)
"const" declarations are indeed duck typed (though they can be declared with type too / as real non-writeable constant / but that is not the point).
It be possible to start a discussion on how or if they differ (due to what input they can take).....
But, lets assume the worst (i.e. they don't differ) => would that be a reason to extend the problem, and make the problem even bigger?
Compare Java and Python. The former is very verbose and distracting with all those type declarations and casts. I believe it has too little duck typing. In Python, you never know what a variable contains: only in an assignment you have a real clue about the type of the variable.
Yes, python (as a lot of script languages) doesn't have much of "type"s.
But then, I wouldn't use it for the same purposes that I would use a languages with type system for.
I know there are huge apps (server side apps) in JS. But then someone invented typescript. (though looking at how much its used, lots of people prefer the uncertainty of JS).
I always am glad, that when I refactor or update code, the compiler will give me errors if I screw up. So much easier than to test and debug everything. (and search usually returns to many locations, and skips some too).
Of course its not a 100%. Hardcoded typecasts can still screw me. But then again, just because it isn't perfect, doesn't give a reason to intentionally make it worse.
About inlining variables, a big advantage exist, which is the contrary of what Martin said. If I decide to change type of a function, or a variable, I search then the whole project for every occurence of that function or variable (everyone does so, right?).
Change func(), search and find this:
// classic VAR section:
theindex := func; // theindex is declared elsewhere, how was it declared?
// inlined var:
var theindex: integer = func; // case 1: I comfortably see *now* the type of the variable
var theindex := func; // case 2: even better. It cannot be wrong (in this case) thanks to duck typing
You have actually seen and understood the example I gave?
Yes, if I change the return type of a function (or property, or...) then I must update my code by hand. And, yes that means I have to go a few steps to find the places where I have to do so. But at least, I get to see, if such an update will screw me over.
If it is duck typed, then I just get screwed.
Btw, your example is flawed
[quote]theindex := func; // theindex is declared elsewhere, how was it declared?[/quote]
Even if "theindex" was declared with duck typing, since it is immutable, that could easily have been at some earlier point inside that function code body. It may then just be assigned a new value from that function.
So if we take that example of yours (and ignore my other warnings), then...
- in some case you will now find "func" and save the very little time of going to the "var" declaration block.
- but, in other case, you will find it, and the inline-var (plus duck typing) will be somewhere else in the function body
So the first save a few seconds, the second looses them again, because now finding the random pos where that var is declared, that takes more time than finding the "var" block.
But even worse.
procedure bar;
begin
{...}
var foo := xyz();
{...}
foo := func();
{...}
Now when you change the type of "func" (and assuming you somehow realize it breaks the above code / which may take some time to debug...), but assuming you find the "foo := func()" line in the same time as you would do by a search.
Then
- you must find the "var foo" line, hidden somewhere in a block of code
- you must look up the type of "xyz"
How is that an improvement?
Of course a grain of salt has to be used: inline variables when useful, choose long and descriptive names when useful, use duck typing when it is not ambiguous, perform a final review of a newly written function before trying, et cetera.
Good naming is key in any case....
How to you know that it neither is, nor will in future ever be ambiguous?
Again, I refer to my earlier "for i := 0 to cnt()" loop example => would you have though that this is ambiguous?
And then what is not ambiguous?
And when you refactor code, how much time to you spent to re-check
every duck typed declaration?
duck typing is borrowing time, at an extremely high interest rate. You may be lucky (or not) and pay day may not arrive for a long time. But eventually it will (even if after years), and when you get that bug that makes it pay day, you can easily loose way more that the few seconds you saved by not specifying the type to start with.
(well, python made something toward optional static typing, don't know the current status).
See my above typescript comment. Apparently more and more people who started on type-less or duck typed code, are getting bitten and start wanting the protection of types. (even if there are masses remaining who don't know yet).
Why should we want to reduce that protection in Pascal?
And again, there is no "you don't have to use it".
From time to time I browse the internet to see comparison of languages, and what other think about pascal or C or whatever. Pascal is hated by a lot of people, and a motivation is its verbosity. Are people too lazy to type begin and end, and procedure etc? Maybe. I love pascal exactly for that:
And having proper manually typed vars, is very much a most important part of this verbosity. (and also way more/better than just verbosity)
Programmers have other things to do, than to keep the compiler happy. The code is written once, then read many times and modified many times. A good language should help this process, and good features like inlining, and good editors, can help if used in the right manner.
Proper typing (not duck typing) has nothing to do with keeping the compiler happy. (That may have been one of many considerations several decades ago, but that is ancient history)
All the reasons I gave against inline-vars (with and without duck typing) are to help the programmer with exactly the tasks you mention.
Sure, having to declare a variable Pascal style, costs a tiny bit of time. But that is an investment towards better code. It pays out in the end.
As for the
not duck-typing (regardless of inline or up front declaration), that is so helpful that even (some) JS users want it and have typescript now. (And according to you, Python users too).
If even those languages move away from duck typing (even if they can't for compatibility abandon it), then that is really telling a story.