Kryvich 165 Posted October 29, 2018 1 hour ago, Stefan Glienke said: A few closures are not functional programming 🙂 Even less so if they are not pure. Yes, you can borrow a fraction of concepts from FP but you cannot do FP in a non FP language. OK, let's call it functional programming elements in an imperative language. In 10.3 and subsequent releases these elements will be even more. Share this post Link to post
Stefan Glienke 1978 Posted October 29, 2018 Inline variable declaration and type inference has nothing to do with FP at all. Share this post Link to post
Ghostwalker 0 Posted October 30, 2018 When i read Marco's blog post the first time, i just was afraid. It thought, that this will making code more chaotic and it will going into the direction of PHP (using variables without declaration).  In the meanwhile, i read the post a second time and had time to thing about this new language feature.  And came to the conclusion that there are more situations, where this features is usefull, because its clarifiying code. You do not have to jump around, to see where a variable is declared. Also it gives us a new method for using temporary objects.  So, imho its like with all new features. It has its advantages but also its disadvantages. Share this post Link to post
Kryvich 165 Posted October 30, 2018 7 hours ago, Stefan Glienke said: Inline variable declaration and type inference has nothing to do with FP at all. I just noticed that these innovations will make the functional elements in Delphi code more compact and easy to understand.  And if we talk about functional programming, please look at this article by Joel Spolsky ("Can Your Programming Language Do This?"). We can write code in the same style, and after 10.3 we will be able to remove unnecessary syntax elements, while maintaining strong typing of Delphi language. Share this post Link to post
Stregor 0 Posted October 31, 2018 (edited) Marco write: Quote Initializing Inline Variables A significant change compared to the old model, is that the inline declaration and initialization of a variable can be done in a single statement. This makes things more readable and smoother compared to initializing several variables at the beginning of a function. procedure Test; // declaration and initialization in a single statement begin var I: Integer := 22; ShowMessage (I.ToString); end; Why not go one step further and allow initializing local variables?  IMHO will be nice to type: procedure Test; var lLastName: string := 'Type last name here'; begin lLastName := InputLastNameThere(lLastName); end; Of course, this will be a syntactic sugar, because compiler must add lLastName := 'Type last name here'; at the first line after begin Edited October 31, 2018 by Markus Kinzler Changed formatter to Pascal Share this post Link to post
Stefan Glienke 1978 Posted October 31, 2018 2 hours ago, Stregor said: Why not go one step further and allow initializing local variables? Because that would only make initializing with const values possible and not like now initializing with function results. So I guess their reasoning was to not extend existing variable declaration in a very limited way but go the full distance. Share this post Link to post
Markus Kinzler 173 Posted October 31, 2018 http://delphi.org/2018/10/unexpected-benefit-of-inline-variables-compiler-directives/ 1 Share this post Link to post
Attila Kovacs 626 Posted October 31, 2018 {$ENDIF Something}?  Rather:  procedure DoesSomething; var  var1: Integer;  {$IFDEF Something}  {$IFNDEF DXE103UP}  var2: Integer;  {$ENDIF}  {$ENDIF} begin  // use var1  {$IFDEF Something}  {$IFDEF DXE103UP}  var var2: Integer;  {$ENDIF}  // use var1 and var2  {$ENDIF} end;  How many of you can start using the new syntax without paying attention?  2 Share this post Link to post
Stefan Glienke 1978 Posted October 31, 2018 Using that feature in code that also needs to compile in versions before 10.3 makes no sense - however once we migrate to a version that has this feature I will use it in company source code with great joy. 5 Share this post Link to post
Attila Kovacs 626 Posted October 31, 2018 (edited) @Stefan Glienke Even if it breaks your Uses Helper for long time? 😉 (hidden hint :P) Edited October 31, 2018 by Attila Kovacs Share this post Link to post
Stefan Glienke 1978 Posted October 31, 2018 3 hours ago, Attila Kovacs said: Even if it breaks your Uses Helper for long time? It will only break it as long as DelphiAST does not support the new syntax 🙂 Share this post Link to post
Kryvich 165 Posted November 2, 2018 Can't wait for the new release. How about complex structures, is it possible? // Before Delphi 10.3 function TestInlineArray: string; var strArray: array of string; begin strArray := ['Delphi', 'JavaScript', 'Python', 'PHP', 'C']; Result := strArray[Random(5)]; end; // Inlining function TestInlineArray2: string; begin var strArray := ['Delphi', 'JavaScript', 'Python', 'PHP', 'C']; Result := strArray[Random(5)]; end; Who can answer? Simple + or - would be OK. :) Share this post Link to post
Kryvich 165 Posted November 2, 2018 (edited) I found another case where inline variables will be useful - as substitution for a with statement. Yes I know: nowadays no one use them... (Just kidding, I found with statements even in the Delphi 10.2.3 source folder). with ControlRange as IHTMLControlRange do begin select; execCommand('Cut', False, EmptyParam) { do not localize } end; After 10.3 it can be replaced with begin var cr := ControlRange as IHTMLControlRange; cr.select; cr.execCommand('Cut', False, EmptyParam) { do not localize } end; So the with statement can be finally deprecated and excluded from the language. Or maybe we will can write: with var cr := ControlRange as IHTMLControlRange do begin cr.select; cr.execCommand('Cut', False, EmptyParam) { do not localize } end; Â Edited November 2, 2018 by Kryvich Share this post Link to post
Kryvich 165 Posted November 4, 2018 Or even better to enchance the with statement as follows: with const cr := ControlRange as IHTMLControlRange do begin cr.select; cr.execCommand('Cut', False, EmptyParam) { do not localize } end; "const cr" because inside the statement cr is used only to access its members. 1 Share this post Link to post
Davor Slutej 0 Posted November 6, 2018 This is awesome. Thank you. Â Reducing the scope of a variable is very good practice. Â One question, inline constants - can they be assigned by function calls or need to be compile time evaluted? If only the latter then F. Â Â Share this post Link to post
Wosi 8 Posted November 6, 2018 7 minutes ago, Davor Slutej said: One question, inline constants - can they be assigned by function calls or need to be compile time evaluted? If only the latter then F. Marco says in his blog post: Quote Beside variables, you can now also inline a constant value declaration So I think constant value expressions are evaluated at compile time. But I would love to see inline constants initialized with dynamic values just like in TypeScript. Share this post Link to post
Kryvich 165 Posted November 6, 2018 (edited) @dados The right side of assignment can be any statement of a type that has members. Of course it can be the function call that returns an object or a record as well. This extended with statement should prompt the compiler to create a temporary readonly variable cr, without increasing the count of references, for optimization purposes.  Note: it's just my suggestion how to make a with statement more convenient and useful for a programmer and Delphi compiler. I am not participating in Delphi Beta testing, and I don’t know if they made any changes to this statement. Edited November 6, 2018 by Kryvich Share this post Link to post
Jacek Laskowski 57 Posted November 6, 2018 (edited) Next example of use inline variable to improve code clarity: Â Instead of unclear: Â Â fRecipients := TCollections.CreateList<TRecipient>(True); Â we can write: Â fRecipients := TCollections.CreateList<TRecipient>(var OwnsObjects = True); Â Edited November 6, 2018 by Jacek Laskowski Share this post Link to post
Kryvich 165 Posted November 6, 2018 (edited) @Jacek Laskowski To improve clarity it is better to use enumerated types instead of generic types such as Boolean, Byte, Integer. // In library: type TOwnsObjects = (No, Yes); // User code: fRecipients := TCollections.CreateList<TRecipient>(TOwnsObjects.Yes); This will require changes in a framework code, but will not require complicating a syntax of the language. Edited November 6, 2018 by Kryvich Share this post Link to post
Uwe Raabe 2021 Posted November 6, 2018 7 hours ago, Wosi said: Marco says in his blog post: So I think constant value expressions are evaluated at compile time. But I would love to see inline constants initialized with dynamic values just like in TypeScript. Well, this works: begin var I := 20; const J = I-1; Writeln('I=', I); Writeln('J=', J); end; Â 1 Share this post Link to post
Dave Nottage 546 Posted November 6, 2018 On 11/1/2018 at 9:43 AM, Stefan Glienke said: It will only break it as long as DelphiAST does not support the new syntax 🙂 I'm hoping DelphiAST is updated to handle it soon after Rio is released (or beforehand) :-) Share this post Link to post
Wosi 8 Posted November 7, 2018 (edited) 12 hours ago, Uwe Raabe said: Well, this works: begin var I := 20; const J = I-1; Writeln('I=', I); Writeln('J=', J); end;  Great! What's about this: const RESTClient = TRESTClient.Create(Nil); Does it work? 10 hours ago, Dave Nottage said: I'm hoping DelphiAST is updated to handle it soon after Rio is released (or beforehand) :-) I'm having a good feeling about it 😉 https://github.com/RomanYankovsky/DelphiAST/pull/271 Edited November 7, 2018 by Wosi 2 Share this post Link to post
Der schöne Günther 312 Posted November 7, 2018 (edited) 1 hour ago, Wosi said: const RESTClient = TRESTClient.Create(Nil);  Does it work?  Hard to imagine, given that the result of TRestClient.Create(..) is not known at compile-time. This would not be a "const", but a readonly variable. Maybe one day Delphi will also have that? Edited November 7, 2018 by Der schöne Günther Share this post Link to post
Uwe Raabe 2021 Posted November 7, 2018 1 hour ago, Wosi said: Great! What's about this: const RESTClient = TRESTClient.Create(Nil);  Does it work? At least it compiles... 1 Share this post Link to post
Rudy Velthuis 91 Posted November 7, 2018 (edited) On 10/29/2018 at 10:35 AM, Sherlock said: Could someone please explain the benefit of type inference in a programming language that showcases type safety? As soon as the compiler has to guess a type, and my be wrong, this could result in C-like problems later on. I have made my peace with inline variables (yes, I am quick at giving up), but this feature seems a bit too "over the top" bait for non Delphi developers. I mean, this too can be ignored, but with a team big enough, it just find it's way into code nevertheless. The type is still safe. It just doesn't have to be repeated (IOW, you get DRY). So instead of     var      X: TObjectList<MyUsefultype>;   begin      X := TObjectList<MyUsefulType>.Create;  You simply do:     begin      var X := TObjectList<MyUsefulType>.Create;  The compiler does not guess. Type inference is not new either. You already had it for true constants and for certain generic functions (if the compiler could determine the type parameter, you don't have to specifiy it). You also had it when declaring a variable using Refactoring. Now you have it in the compiler. They type is not "guessed", it is determined. Also, if you do:     var i := 17;  then i is not a byte. The compiler chooses a useful type, in this case Integer. If you want something else but the default, you can do:     var i: UInt32 := 17;  so then you don't use type inference.  It makes declaring types a lot simpler and doesn't require repetition, which means there is less chance for errors. I wish we had had it much earlier. These things: inline declaration, inline initialization, block local scope and type inference are all one new feature and belong to each other. Edited November 7, 2018 by Rudy Velthuis 1 Share this post Link to post