I have just downloaded 10.3 and after less than 1 minute I already have found an issue. Does this happen to you too?


I have just downloaded 10.3 and after less than 1 minute I already have found an issue. Does this happen to you too?

It seems that code insight does not recognize inline varaibles (but the code compiles)

Comments

  1. Please do not use inline variables. This is a very bad programming practice.

    ReplyDelete
  2. Please do not use comments in that way. This is a very bad programming practice.

    ReplyDelete
  3. Ralf Stocker On the contrary. Inline variables reduce scope, make code more readable and remove a whole range of potential bugs.

    You can make fine mess out of your code with or without inline variables. And if you do it will not be their fault but yours.

    ReplyDelete
  4. Dalija Prasnikar I disagree on making the code more readable - where every historical method in Delphi for the last 20+ years has had variables defined at the top. If you've read/written many lines of Pascal code over that time, then it's opposite of more readable to now come across inline variables. It is certainly 'something new' that we will have to get used to - but at least for the moment, it's definitely not 'more readable' within the context of a Delphi developer. It also has the bad side-effect of assumedly breaking all current parsers of Pascal code (including the IDE's code insight apparently.) Doesn't it also go against every written book/tutorial on fundamental scope principles in Pascal? As far as inline variables being used to reduce scope - wouldn't that be a code smell for refactoring instead via Extract Method? Change is good, but there are some major drawbacks.

    ReplyDelete
  5. Darian Miller So we should never get any new features because existing tutorials will be broken and we will have to learn something new?

    If you are confused by reading code with inline variables more than five minutes after you have learned about existence of that feature, maybe you are in the wrong profession.

    And no, reducing scope is not code smell. You cannot always refactor into another method. Small methods are good, but they must have some logical organization.

    Too much granulation can be equally bad as too less granulation.

    ReplyDelete
  6. Dalija Prasnikar I believe you defend it too much. It always boils down to a cost/benefit decision - does the cost (readability, departure from historical context/documentation, breaking existing tooling, lack of backwards compatability) outweigh the perceived benefits within the current state of the language given the rest of the demands? To me, this feature simply fails that test at this time.

    ReplyDelete
  7. Darian Miller First of all, you don't have to use inline variables if you don't like them. Cost of readability, departure from historical context/documentation, lack of backward compatibility will equal to zero. Even the tooling will not be broken if you don't use it (unless, of course you don't write tools)

    Some benefits, there are too many to write them all:

    1. loop variables - they definitely belong into loop scope, and they do pollute variable declaration block with unnecessary cruft.

    2. Other temporary variables you may need, that also don't belong into main declaration block, like explicit references for better handling and more control over compiler introduced implicit references - those are especially useful for controlling ARC references - and we do have ARC in classic compiler, too.

    3. skip unnecessary automatic initialization/finalization of managed variables in code paths that will not execute - speed optimization.

    4. Preventing errors (for some you have compiler hints, but if you miss the hint...) - some examples

    You cannot forget to initialize variable before use

    procedure Test1;
    begin
    var sl := TStringList.Create;
    try
    finally
    sl.Free;
    end;
    end;

    You cannot use variable that belongs to wrong scope and might be uninitialized - this code will not compile

    procedure Test2;
    begin
    try
    var sl := TStringList.Create;
    finally
    sl.Free;
    end;
    end;

    5. Type inference - repeating type two times, especially with generics makes code harder to read because while you are skipping reading redundant information, you may skip important one.

    This is just the tip of the iceberg. Inline variables are without a doubt extremely valuable feature.

    ReplyDelete
  8. The rule in our shop will be to use it sparingly. Maybe we'll come up with another letter to preface the variable with, like Z (not saying it'll be Z), because we already use L for local variable in the method.

    ReplyDelete
  9. Coding will be a lot simpler as Dalija explained. Here an example using generics:

    TYourType = TDictionary;

    TYourClass = Class
    fSomeDic : TYourType
    public
    procedure DoSomething;
    end;


    implementation

    procedure TYourClass.DoSomething;
    begin
    for var lItem in fSomeDic do
    litem.Value := 10;
    end;

    As you see this is very easy to read. And litem belongs to the for loop. It doesn't exists outside. Any reference to it will raise an error.

    If you need to change your base type to
    TYoutype = TDictionary;

    There's nothing else to change. No need to hunt every tpair declaration.

    You have the tools, use it at you see fit!

    ReplyDelete
  10. Dalija Prasnikar Cost equal to zero is a fallacy and an argument ender. If you don't have the imagination to acknowledge any costs with a major feature change like this (at least the effort allocated to this task versus other pending requirements) then this is a useless conversation.

    ReplyDelete
  11. Darian Miller You are mixing apples and oranges. To what cost you are referring to?

    I explicitly said that cost of using the feature is zero. Not the cost of implementing it. And if you talk about cost of implementing the feature (in terms of how much it costs Embarcadero to do that) half of the things you mentioned don't apply.

    And trust, me it is mere drop in the sea. It is pretty simple and straight forward feature.

    ReplyDelete
  12. Dalija Prasnikar Not sure why I waste the time... but to say cost is zero is just pontification which is sometimes hard to ignore. Say I don't use the new feature myself as I need to stay on an older version... now, say there's a new tool just posted to GitHub and it highly leverages this functionality. I cannot use that tool without some effort. The cost is not zero. Say you are on the latest version, but you rely on tooling that cannot parse this new form of variable definition. Your tooling for code documentation, coverage analysis, static code analysis could be completely broken the second any of this code gets introduced into the project. I simply object to saying there's zero associated cost. That's really not true. There are actual, real-life difficulties introduced with a major change like this. For me, the costs (all of them) are not worth the benefits (which I acknowledge are present.) But this is a really moot because it wasn't my decision to introduce this feature at this time (which I would have vehemently voted against - at this time.) I haven't checked to see if Peganza's tools were upgraded to handle this version. My assumption is they haven't, so this coding style is forbidden in new code until such time as the tooling catches up.

    ReplyDelete

Post a Comment