In defense of declaring variables at the top
In defense of declaring variables at the top
Reasons I like it:
1) It obliges you to reason beforehand about what goes in the algorithm
2) If you have to add a new variable, everything is there for you to read
3) Minimizes mistakes
A
Reasons I like it:
1) It obliges you to reason beforehand about what goes in the algorithm
2) If you have to add a new variable, everything is there for you to read
3) Minimizes mistakes
A
Declaring variables beforehand is not making code any safer or cleaner - its just adding ceremony. Keeping methods short, using good names and having a compiler that is smart enough to infer the type of a variable from its first assignment is doing so.
ReplyDeleteAgree with Stefan Glienke , except the last one; i still like writing types everywhere just to keep it clear and safe
ReplyDeleteAgustin Ortu I am really amazed that people think that writing types everywhere makes anything safer. Not writing a type but letting the compiler figure it out by its first assignment is not any less safe. It does not suddenly turn into Java Script that does weird type conversions that go out of control. If I could write var i := 42 the compiler knows ok, i is an Integer (lets leave aside the fact that Delphi has Byte and SmallInt and all that) and I cannot then in the next line assign 'Hello World' to it. The language would still be strongly typed.
ReplyDeleteCan't agree... how do you assign a pointer with no type declarations? or classes/child classes?
ReplyDeleteHeinz Toskano Where did I say that I want to prevent that? I said there is no need to force them. All languages that support type inference (that I know) allow specifying the type but in fact in the majority of cases they are simply not needed because the compiler can infer them from the right side expression of the assignment.
ReplyDeleteStefan Glienke Correct. Look at TypeScript or even the latest iteration of C#. TypeScript is strongly typed even if you don't see very many types in the declarations. Even when returning anonymous types from a function, they are no less type safe.
ReplyDeleteHeck even C++ has "auto" these days.Though in C++ it makes a lot more sense than in Delphi, due to templates.
ReplyDeleteThat said, I still like being explicit with my types. I feel it documents my intentions when writing the code.
ReplyDeleteMind if I point to PHP's type inference and the hell that created?
ReplyDeleteAllen Bauer no need to invoke C-languages :) several Pascal dialects support type inference.
ReplyDeleteI think type inference is only part of the equation and, honestly, not even the most important one in my view.
ReplyDeleteFor a start, let's agree on the meaning of "safe": what I mean by "safe" is that it is more difficult to write incorrect code.
Imagine a situation such as this:
var MyInterface := MyOtherInterface.NewSubOject; // <-- What ACTUAL interface is this if TSubObject implements multiple interfaces? What if it returns the TSubObject instance? What if it returns the WRONG implementation because MyOtherInterface for some reason was typed incorrectly through the inference? What if the developer doing that does not even KNOW that TSubObject implements multiple interfaces?
Also, documentation is part of writing "safe" code. The fact we have to be explicit means that we may catch incorrect or clunky designs more easily. Removing types means we have less visibility.
Personally, if this is ever done, I'd like to see several compiler directives:
1) To make it a compilation error if the type is ambiguous
2) Emit warnings when you are in an inference chain that is some levels deep (with the number configurable at the module level) and ANY of the types implements multiple compatible interfaces.
3) Turn it off entirely at the module level
And I would also like to see a new keyword or class attribute to stop developers from doing inference on particular types.
A
> var MyInterface := MyOtherInterface.NewSubOject; // <-- What ACTUAL interface is this if TSubObject implements multiple interfaces?
ReplyDeleteIn your case MyInterface would be a TSubObject, not an interface.
> What if the developer doing that does not even KNOW that TSubObject implements multiple interfaces?
In the grand scheme of things, the developer should always assume every object can implements every interface, because even if TSubObject does not implement ISomeInterface at the time the code is written, it could implement it a few days (or months, or years) later, and the code will still compile without errors or warning when that happens.
Also on a side note, while interfaces in Delphi are often used just as an ersatz for automatic memory management, they are much more than that.
Andrea Raimondi Feel free to declare your variables where you like. I don't think anybody would propose removing that choice from a programmer.
ReplyDeleteWhat I don't like about Delphi is that I cannot impose a lifetime smaller than a function.
David Heffernan Then make your functions smaller ;)
ReplyDeleteSpecific rejoinders to your points.
ReplyDeletePoint 1. Declaring variables in one place or another does not oblige more or less thought and design.
Point 3. That's quite a big claim. Minimize is a very precise word that means "find the smallest possible value". I think you rather mean to say "reduces mistakes". In which case you need to say what you are comparing with. Presumably C++ style declarations which can appear in the body of a function. Even that is a very serious claim. Does you have any evidence? I can't think of any reason why errors would be reduced by forcing all local variables to be listed in one block.
Willo van der Merwe That's fine. But you cannot apply that rule indefinitely. There comes a point where splitting a method up into smaller and smaller pieces becomes counter productive. At some point, if you go too far, then you have too much indirection and the logic becomes harder to comprehend.
ReplyDeleteIMO, PHP doesn't really have type inference - more like ducktype inference :P
ReplyDeleteI like declaring types for the same reasons as Asbjørn i.e. code readability - but there are clearly places where type inference can work. One such place is "index" variables in for loops. Automatically declared type inferenced loop variables would eliminate things like "index not valid after loop" and remove the ceremonial declaration. Another is argument / result type declarations in inline anonymous method implementations.
I do love Generics, but miss being able to limit T to f.x. an enumerated value to able to use Set of T / Ord(T) - as well as a "math" type limit to be able to do arithmetics - provided that T supports the necessary basic operators (+-*/, assignment and comparators, etc)
What I most often miss is the ability to reference an object property as exactly that - a reference - i.e. the ability to pass a property as an argument - not it's value - but as a method which can be accessed later from where the reference is kept (both for read and for write). That would greatly reduce the need for string constant + RTTI trickery.
Yes, it is a stretch - since an attribute is per class - but there is only one type - and it's structure is fixed - even though it may have several instances - so conceptually this should work - given enough compiler intelligence.
It is impossible to claim that declaring variables at the top reduces error, because there are two cases where it allows errors that tighter scoping can prevent:
ReplyDeleteA) using a variable before it has been initialized (but without compiler error because the variable has a default initialization, such as for interfaces)
B) reusing the same variables for different purposes in different portions of a function, without proper re-initialization or cleaning up in between
With tighter scoping and "declaration just before use", those tow errors are minimized.
And there are no errors that tighter scoping opens up.
Ability to declare variables anywhere in the code would be fine with me. But I don't miss that functionality much.
ReplyDeleteAs far as type inference is concerned my take is road to hell is paved with good intentions. It seems like a good idea and then before you know it you are swamped with tons of unreadable code where you have to jump back and forth trying to understand with what type are you exactly dealing with.
Type inference is fine only in small number of use cases where type is plain obvious, like for loops variables, unwrapping optionals (nullables) like in Swift with if let constructions...
var obj: TSomeObject = TSomeObject.Create construction also looks like place where type can be inferred without reducing code readability, but that is the place where I would draw the line. Constructors - can do, but anything else not.
Type inference based on function results is just horrible when it comes to code readability and maintenance. Thanks but no thanks.
Willo van der Merwe PHP is not a strongly typed language.
ReplyDeleteDalija Prasnikar Adding a feature to a language does not force you to use it at all times to the exclusion of other features.
ReplyDeleteIf type inference of expressions for inline variable declarations was added, you would be free not to use it.
David Heffernan I don't have to use it, but others will. And more often than not you have to deal with other people's code.
ReplyDeleteMarkus Müller Exactly. That's why the type extensions were added.
ReplyDeleteDalija Prasnikar The correct way to deal with that is not to cripple the language, but to use procedure and education and supervision and code review to enforce coding standards within your team. You have to do that anyway.
ReplyDeleteDavid Heffernan It goes beyond your team. For start, if nothing else, you have to deal with core Delphi libraries. Going through code of that complexity is hard enough as-is. Additional obscuring is not something I would welcome.
ReplyDeleteWhile you do have to educate and impose certain coding standards, the less you have to do in that department, the better. You don't have to spend time on education and reviewing for parts where compiler does the job for you.
Dalija Prasnikar That argument leads to a language of the lowest common denominator. I'm not keen on that. I don't want to go back to Delphi 7.
ReplyDeleteDavid Heffernan I am not arguing that we have to go back to Delphi 7. But full spread type inference does not bring enough to justify all unreadable code you can write with it.
ReplyDeleteDalija Prasnikar That's not my point. My point is that arguing that others might write code that you do not like is an invalid argument.
ReplyDeleteDavid Heffernan I agree with your point to a point ;-) And any feature can be abused, that is for sure.
ReplyDeleteMy point is that introducing type inference everywhere compiler can infer type is bad. It is not as bad as 'with', but nevertheless bad.
I have mentioned few cases where type inference can be used safely without diminishing code readability.
In case of type inference that is basically keystrokes saving syntax sugar, you don't have other arguments besides people can and will write unreadable code using it. And that someday one will have to deal with such code.
Dalija Prasnikar - How can a working type inference be bad, as long as it actually works?
ReplyDeleteDalija Prasnikar So you say that people write unreadable code in C# because of this? Especially when dealing with collections or arrays how is writing IEnumerable myBlablas = GetBlablas() instead of var MyBlablas = GetBlablas() any more readable?
ReplyDeleteLars Fosdal Because compiler can infer types in way more places than human can. That makes your code less readable.
ReplyDeleteFor instance, inferring type based on function result.
function ReturnSomething: string;
...
var x = ReturnSomething;
Compiler can easily know what type should be used, but person reading code would have to go to ReturnSomething declaration to know what is actual x type.
Stefan Glienke Yes, I have no idea what GetBlablas() returns and I want to have that information in place and not lying somewhere else.
ReplyDeleteStefan Glienke BTW, I think you meant other way around.
ReplyDeleteTo make it clear, the way I see it
IEnumerable myBlablas = GetBlablas() - good
var MyBlablas = GetBlablas() - bad
Dalija Prasnikar That is why you name your variables and methods properly.
ReplyDeletevar Item = ReturnItem;
var txt = ReturnText;
There is also the context in which the variable is used which adds further understanding.
Some examples where type inferring does not have negative impact on code readability (IMO):
ReplyDeleteinferring in for loops
for item in Some Collection do
for i := 0 to Count - 1 do
for enum in TEnum do
inferring in optional unwrapping - the Swift way
if let x = SomeOptional
inferring in generics
var list: TList
list := Tlist<>.Create
calling constructor
var x = TSomeObject.Create
Dalija Prasnikar in Delphi with top-level variable declaration it's not so clear-cut
ReplyDeletevar
myBlablas : IEnumerable;
... some
other
variables ...
begin
... some
lines
of
code ...
myBlablas := GetBlablas();
...
end;
So unless the code is trivially short, the type declaration is not obvious, only the naming as Lars Fosdal pointed is important.
And if the code is trivially short, the explicit typing is just ceremony and does not matter much (and neither does the naming tbh).
Lars Fosdal That's not Pascal. Looks more like BASIC. ((shiver))
ReplyDeleteLars Fosdal I understand what you mean. I just don't agree that is enough.
ReplyDeleteDalija Prasnikar Again, that a feature can be used poorly does not mean that it cannot be used well. We are all free to write whatever code we like. The argument that because a feature can be badly used is not a valid argument.
ReplyDeleteThe only reasonable argument to make has to relate to the merits, or otherwise, of using the feature properly.
To illustrate. A huge amount of terrible abuse of inheritance can be found in many code bases. I know my code base has plenty, and I'm sure yours does too. That's due to a failure on the parts of the developers and not evidence to support removing inheritance from the language.
It's easy to think of many more examples. Almost every language feature will serve up its own potential for abuse. If you reject all features that can be abused, you will have nothing left.
Eric Grange I said I have no objections with inline variables. And top-level declarations are still more local to the code in question, than some distant function from who knows where.
ReplyDeleteDavid Heffernan I already said that in principle I agree. Any feature can be abused. But I also think there is huge difference between features that bring something substantial like inheritance, and mere syntax sugar like type inference.
ReplyDeleteAnd again, I don't have issues with declaring variables inside code, nor limited type inference.
I would like to declare my variable anywhere in the code. I found this really practical !
ReplyDeleteWillo van der Merwe I was merely reusing the same syntax as Stefan and Dalija.
ReplyDeleteI would prefer
var Variable := Source;
and even allow
var Variable: TExplicitType := Source;
for inline declarations.
For inline variables that are not bound to a loop - I think their scope should be limited to the current block.
I.e.
if Condition
then begin
var Ref := Source;
end
else begin
// no Ref here
end;
// no Ref here
Dalija Prasnikar In context of Generics, type inference is waaay more than syntactic sugar, IMO.
ReplyDeleteDalija Prasnikar So your argument should be about the merits or otherwise, and not about the fact that any tool can be abused in the hands of the right (wrong?) person
ReplyDeleteLars Fosdal I agree with that.
ReplyDeleteI said I accept limited (as in where type can be inferred without compromising code readability) type inference.
Lars Fosdal Willo van der Merwe
ReplyDeleteI am currently living in Java and Swift more than in Delphi, so I have maybe used non pascalish syntax in some places more by mistake than intention.
David Heffernan Not in general, but in this case yes.
ReplyDeleteBecause it is kind of feature that will be misused at large. Even by good developers. You will write code, and few years later you will find yourself having hard time understanding it. And as far as merits are concerned it is really insignificant feature except in few cases I have mentioned earlier - maybe there are more such exceptions, but I cannot think of any at the moment.
Dalija Prasnikar I think I'd like to be the judge of whether or not I will write good code if it's alright by you.
ReplyDeleteDavid Heffernan Yes, it is alright with me.
ReplyDeleteI am not saying that anyone (or everyone) should agree with me, but I also want to be able to state my opinion. In this case it is not likely I will change my POV.
Dalija Prasnikar Clearly everyone has their own opinions. And of course they differ. But the argument that you used against inference is just as applicable to other features such as inheritance. But you won't apply it there.
ReplyDeleteIt's fine to argue on the basis of how much benefit a feature might have, but specious to argue on the basis that a feature might be misused.
David Heffernan I think I stated why it is not applicable to other features. You are missing my point completely. I am not sure if I can explain properly.
ReplyDeleteYou mentioned writing bad code, this is not about writing bad code and even not about misusing feature. You will be writing good code but that code will lose readability comparing to code without type inference.
And it is almost impossible not to use type inference if it would be available. Because it is so damn convenient.
Maybe another example will help you understand what I mean. Swift forces you to write parameter names when calling functions like sum(x: 10, y: 20). If you ask me it is nuisance. If Delphi would have such thing, we would all be cheering now to get rid of that. But no matter how I dislike it, it does make code more readable.
Basically, I know why people would like to have type inference and I would like to have it in some places. But I have enough experience (also with using type inference myself) to see that in the long run having it everywhere would not be so good at all.
I think that is a feature one should be very careful with.
Dalija Prasnikar In general I'm agreeing with you. I too am weary of the type inference addition. I understand what David Heffernan and friends have to say, but do you guys realise what you're sacrificing because you're too lazy to add a type definition?
ReplyDeleteWillo van der Merwe Do you use Generics extensively?
ReplyDelete+Willo Feel free to continue declaring your variables the way you please
ReplyDeleteLars Fosdal Not extensively, no. How extensively do you use it?
ReplyDeleteDavid Heffernan It's not that simple. No developer operates on an island. Pascal has certain restrictions imposed to assist a developer. Like Swift's parameter naming and Python's forced indentation, these are features intended to assist the developer. Declaring variables upfront were designed to assist the developer to think and plan about what they're about to do, and forms part of what makes pascal, pascal. Remove that and you start to venture down the Modula-2 road.
ReplyDelete+Willo I really don't understand that. I don't use goto. Even though it exists in the language. I understand that there are very rare scenarios where goto is effective and think the language is better for its existence even though my code never uses it.
ReplyDeleteI never use single statement, always compound statement. The entire codebase that I work on, alongside a team of developers, adheres to this standard.
I don't use the new extended exit function that sets Result and then exits. I personally regard it as confusing to have two quite different ways to set Result. That's a choice that my team makes.
It is perfectly possible to choose what features you use. I don't believe that you are incapable of exercising choice. Why do you feel that you won't be able to do that?
Aside: Modula-2 variable declaration is identical to Pascal.
+Willo Declaring variables upfront were designed to assist the developer to think and plan about what they're about to do
ReplyDeleteDo you have evidence to back that statement? Personally I suspect that the original motivation was to help make it easy for the compiler author to work out how large the function's stack frame was. An awful lot of language features were motivated like that in the old days. But, like you, I'm just speculating.
David Heffernan
ReplyDeleteWhy do you feel that you won't be able to do that?
Sure, I'll be able to control it my own code base, but, that's not really the point. The point is that you're sacrificing readability and stability for something an IDE can assist you with quite easily.
_Aside: Modula-2 variable declaration is identical to Pascal. _
I know that, I was trying to show how drastically a language can change, since Modula-2 was based on Pascal.
Do you have evidence to back that statement?
No hard evidence, but that's the way it's been punted to me for years (Since Turbo Pascal vs C wars). The fact that it allowed for single pass compilation was a happy side-effect. :)
> The point is that you're sacrificing readability and stability for something an IDE can assist you with quite easily.
ReplyDeleteActually you are not really sacrificing readability, just ceremony, for trivial cases, variable declaration does not bring anything, and for complex cases, you just end up with a long list of loosely related variable declarations (the RTL & VCL have many "good" examples demonstrating how this is actually detrimental to readability).
Stability is also not enhanced by declaring variables on top for simple reasons: it allows use of variable before initialization, and it encourages same-variable reuse for different purposes. Both these reasons ARE detrimental to stability. Late, in-place and tightly scoped declaration can on the other hand be leveraged to minimize those issues.
> The fact that it allowed for single pass compilation was a happy side-effect. :)
Type inference does not prevent single-pass compilation, provided you do not go for a "backtracking" type inference (but that one usually comes with more downsides than upsides)
Willo van der Merwe We have a generics based class hierarchy with some 230 different classes - and numerous other support classes that uses generics heavily.
ReplyDeleteIt cut down our source #LOC by 15-20% when we introduced it - and a lot of code has since been written. I guess you can say it is relatively extensive use - and sometimes abuse, according to Stefan G :P
Willo van der Merwe For Generics - type inference can in some cases simplify the use of the fairly verbose generics syntax - and makes the code easier to read and to maintain.
ReplyDeleteFor me the prime benefit of inline declarations is that the variable scope can be limited more narrowly. I don't understand why so many people are arguing in favour of wider scope. I thought that debate was resolved long ago.
ReplyDeleteLars Fosdal Not abuse but overuse that can lead to more use (seen and done that myself) ;) And I did not make it a fact I just guessed you might. Especially when the generic type parameter is restricted to classes you can easily forget about the good old class of in Delphi.
ReplyDeleteJust short reminder, we are discussing two separate things here. Declaring variables upfront is one and type inference is another.
ReplyDeleteTo sum up my position:
ReplyDeleteYES to inline declarations with limited scope
YES to type inference where possible.
YES to inline declaration with type inference
My position summary:
ReplyDeleteYES to inline variables
YES to type inference in few cases like: for loops, generics, constructors var item := TSomeObject.Create; instead of var item: TSomeObject := TSomeObject.Create;
NO to type inference everywhere compiler can deduce the type, especially NO to type inference based on function result
+Dalija difficult to know what you mean by type inference for generics
ReplyDeleteDavid Heffernan for instance:
ReplyDeletevar list: TList := TList<>.Create
This is kind of generic type inference Java has. It can most likely be expanded to some other use cases, but I don't have time to invent them at the moment.
Dalija Prasnikar IMO, your suggestion to disallow type inference for function results is strange. You need this for functions in factories, f.x.
ReplyDeletevar Structure := Factory.Build;
Lars Fosdal While it may be fine for well defined factories, type inference in function results is what makes your code harder to read and understand later on.
ReplyDeleteI am talking from experience here. I have my own 6 months old Swift code where I have hard time reading it. It is not bad code and it is quite simple, but if it takes me 3 minutes longer to understand what code does because I don't see variable type, then it is 3 minutes too much.
And problem is while you can say that you are not going to use it in some places, you will. It is almost impossible not to use it while you are writing code. Also while you are writing code everything is so obvious, but when you return to that code after a while you will find yourself jumping back and forth trying to deduct types. And imagine reading someone else's code.
That is primary reason why I am against it. It seems like good idea, but actually it is not.
Lars Fosdal In your example if inference can be done other way around the I am for it
ReplyDeletevar Structure: TStructure := Factory.Build<>;
Would you like
ReplyDeletevar Instance: TClass = Create;
as well?
Lars Fosdal Yep, that is fine. There is no need to repeat information twice, problem is when you miss information completely.
ReplyDeleteThe variable may be an abstract base type - and what you want to create is a different type. IMO, the right side of the assignment should be the one to decide the type.
ReplyDeleteLars Fosdal I wonder why you come up with syntax that is far from what we currently have. Why suddenly make changes to the way we call a constructor?
ReplyDeleteStefan Glienke To point out why it needs to be the right side of the assignment which controls the actual type - inferred or explicitly.
ReplyDeleteLars Fosdal In that case you would have to use var Instance := TClass.Create;
ReplyDeleteBTW, Swift has type inference all the way, but now when I think of it does not allow construction (cannot check right now)
var Instance: TClass = Create;
I am currently in the middle of release cycle so I am not thinking clearly. Just FYI, if I say something stupid ;-)
or
ReplyDeletevar Instance := Factory.Build;
Lars Fosdal You don't know that Factory is Factory (it is just a function) and you don't know what type it will return. When you call constructor you have actual type written right there.
ReplyDeletevar list: TList := TList<>.Create;
ReplyDeletelooks pretty lame to me. Not at all keen on the rhs depending on the lhs. To me
var list := TList.Create;
makes far more sense.
I honestly cannot see what's wrong with allowing inference everywhere. If you don't want to use it, don't.
When I code in C# I use var infrequently. Typically in statements like this:
var arr = new double[666];
But naturally I prefer
FooBar x = obj.getThing();
to
var x = obj.getThing();
It's just seems pretty obvious when inferring variable type is a good thing to do, and when it is not.
As I've said many times, if all language features that could be misused were reject for that reason, we'd have nothing.
Dalija Prasnikar In the IDE, when at the code, you see the base type returned by the function (should it not be obvious by the factory/function name) by hovering the cursor over the function - as well as any xml doc present. In the debugger, you can see the actual type returned by hovering over instance.
ReplyDeleteDavid Heffernan Java has it like this, I am fine with either way as long as you have the type there.
ReplyDeleteAnd I will repeat again this is not kind of feature you can easily ignore if you have it available.
var or no var is irrelevant here. Java does not have var, Swift forces you to use var or let, but both is fine with me.
Lars Fosdal and when IDE goes berserk on you, or you read code outside the IDE... I don't like to depend on IDE too much while reading code.
ReplyDeleteDalija Prasnikar I have no problem choosing when to use var when I code in C#. I don't think I'm particularly special. I think any competent coder will be able to make good judgement calls. I bet you would be able to get this right.
ReplyDeleteLars Fosdal As a general rule, in my view, if code is only readable when you have support from an IDE, then such code should not be written in that way.
ReplyDeleteDavid Heffernan I am a bit lost right now, so maybe I misunderstood what you mean by var, what I want to say is that I am against
ReplyDeletevar x = obj.getThing();
because it has no explicit type.
Dalija Prasnikar Now you are clutching at straws. I search/browse code outside the IDE as well, but when I am really digging into a piece of code - I am always in the IDE to be able Ctrl-Click jump, get hover hints, etc.
ReplyDeleteDavid Heffernan Well, obviously I am not able to do this right ;-)
ReplyDeleteDavid Heffernan In general, I can agree - but if that is the case, the code is not well written. Proper naming is important.
ReplyDelete(edit: which is why foo:bar examples annoy the heck out of me)
Lars Fosdal _which is why foo:bar examples annoy the heck out of me_
ReplyDeleteIt's interesting you say that given that you habitually offer up example code that is not valid.....
property ThisCodeIsNotValid;
At least it is readable :)
ReplyDeleteDalija Prasnikar My point is that I don't give a dang what type x is. Its the thing that I got from obj.getThing. You are too focused on knowing what type everything is.
ReplyDeleteDalija Prasnikar In C#, since 3.0, the var keyword is used to declare variables whose types are inferred by the rhs of the initialization statement. So,
ReplyDeletevar foo = 42;
is equivalent to
int foo = 42;
This is obviously a very simple example. My point is that any half competent developer is perfectly capable of understanding that
var arr = new double[666];
is just as clear as
double[] arr = new double[666];
and avoids the repetition. And that half competent developer is just as capable of understanding that
var x = obj.getThing();
is unclear.
Where var comes into its own is with complex expression whose types are actually hard to express. The use case that pushed the C# designers into this route was LINQ which has a tendency to produce exceedingly verbose types that nobody ever wants to name explicitly.
I'm a 100% confident that you are capable of known when to use such a feature, and when to shun it.
Stefan Glienke I think the point is that sometimes you want to know the type when you read the code, and sometimes you don't want to know the type. It's not an either or. I'm sure that there are plenty of times when you do want to be able to know what type a variable is.
ReplyDeleteStefan Glienke exactly.
ReplyDeleteIn GC'ed environments, there is also a trend to not only not having to care what the type is, but also not caring about the memory management implications. In Delphi you still have to care whether it's an instance or an interface, and if you're going to keep a reference to it, if it might not create a circular reference.
David Heffernan What are we exactly arguing about? From what I can see, examples of code that you want to write are exactly in line with kind of code I want to write. IMO compiler is perfectly capable in distinguishing between that kind of code and the code you said it is unclear. All I want is that compiler prevents me from writing unclear code.
ReplyDeleteWhy? Because, I have too many times caught myself writing unclear code with type inference. I can tell the difference between good and bad code, but somehow I have hard time writing proper code when compiler does not forces me to. Maybe it is just matter of getting used to it, and with time I will get better. I don't know.
Dalija Prasnikar My opinion differs. I think if you don't allow language features that can be abused then you won't allow anything. I don't believe that the compiler can stop us writing bad code. That's our job to do right.
ReplyDeleteDavid Heffernan And I generally agree with you. Compiler cannot stop us from writing bad code, but it can be helpful. And I like that help. If my views in this matter would prevent someone from writing code they really, really want to write, then let it be type inference everywhere. But I still think it is a not a good thing to have.
ReplyDeleteStefan Glienke can you create a New Feature request entry at Quality Portal? I think your explanation would be very appreciated :D
ReplyDelete