Jump to content

Kryvich

Members
  • Content Count

    402
  • Joined

  • Last visited

  • Days Won

    8

Posts posted by Kryvich


  1. Form the Delphi help, "IF directive":

     

    Quote

    You can use the FireMonkeyVersion constant (defined in FMX.Types.pas and equal to 16.1 at the XE2 Update 2 release) in an IF directive. To identify and separate FireMonkey code that is for any version higher than 16.0, surround the code with the following conditional directive:

    
    {$IF Declared(FireMonkeyVersion) and (FireMonkeyVersion > 16.0)}
      ...
    {$IFEND}

     

    This code works fine for me:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    {$IF DECLARED(FireMonkeyVersion)}
      ShowMessage('Here is FireMonkey!');
    {$ELSE}
      ShowMessage('Perhaps it''s VCL');
    {$IFEND}
    end;

     

    • Thanks 1

  2. I like to write code without warnings and hints issued by the compiler. Today I encountered the following warning:

    program TestCaseW1010;
    {$APPTYPE CONSOLE}
    type
      TPerson = class
        Name: string;
        function ToString(Quote: boolean): string; overload;
      end;
    
    function TPerson.ToString(Quote: boolean): string;
    begin
      if Quote then
        Result := '"' + Name + '"'
      else
        Result := Name
    end;
    
    var
      Person: TPerson;
    
    begin
      Person := TPerson.Create;
      Person.Name := 'John';
      Writeln(Person.ToString);         // --> TPerson
      Writeln(Person.ToString(False));  // --> John
      Writeln(Person.ToString(True));   // --> "John"
      Readln;
      Person.Free;
    end.

    The compiler shows W1010 Method 'ToString' hides virtual method of base type 'TObject'. In fact, he does not. Is it a false positive warning, or is it something wrong with my code?


  3. @pyscripter Thank you for the finds! I had some free time, so I adapted Teo's parser for Delphi. Also corrected some bugs in this parser and in the grammar for the Delphi 7.0 language. https://github.com/Kryuski/GOLD-Parsing-System-For-Delphi

     

    @Markus Kinzler Interesting. I will definitely follow this project.

     

    Update: Parse::Easy is written using Perl. Yes, it can generate a lexer and a parser in Delphi laguage, but hey! I do not want to install another IDE and learn a new language when such things may well be written in Delphi. Once they wrote ErrorInsight on J#, and I think it was a bad decision. Maybe later, I or someone else can rewrite Parse::Easy to Delphi. But now it does not make sense, since it is still in the beta stage.

    • Thanks 3

  4. @Uwe Raabe I read a little about this parser, great tool! There is a ready-to-use grammar for Delphi, though without the support of new language features, such as generics, anonymous functions and closures. And there is several GOLD Parser Engines with sources written in Delphi. I took the most recent version and updated it a bit, now it can be compiled in Delphi 10.2.3. Put it on GitHub.

    • Like 1

  5. 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;

     


  6. 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. :)


  7. 1 hour ago, Attila Kovacs said:

    It would be the same if I omit const for input, am I right?

    Not quite. Delphi does not increase the reference count for const parameters. Therefore, this variant will be faster.

    function x(const input: string; var output: string): boolean;
    push ebp
    mov ebp,esp
    add esp,-$10
    mov [ebp-$08],edx
    mov [ebp-$04],eax
    ...
    
    function x(input: string; var output: string): boolean;
    ... same commands ...
    mov eax,[ebp-$04]
    call @UStrAddRef
    ...

     


  8. Documentation says that FireMonkey provide a great deal of customizations without subclassing. I found this:

    1. Prepare PNG for ActiveLink and SourceLink backgrounds.
    2. Right click on the edit.
    3. Edit customs style...
    4. Select EditStyle.Background
    5. Double click ActiveLink
    6. Add your PNG image.
    7. Adjust positions for SourceLink and ActiveLink.

    How to make it easier and more correct - you decide.

    P.S. FMX is multiplatform so you may have to make a style for each platform for which the program is intended.


  9. I think 5 function calls or 5 assigments is not the best code style. Consider these variants:

    SQL.Add('SELECT EntCity, EntStageName' + sLineBreak
      + 'FROM Entertainers' + sLineBreak
      + 'WHERE 1=1' + sLineBreak
      + 'AND TEST=''TEST''' + sLineBreak
      + 'ORDER BY EntCity ASC, EntStageName ASC');
      
    CommandText := 'SELECT EntCity, EntStageName' + sLineBreak
      + 'FROM Entertainers' + sLineBreak
      + 'WHERE 1=1' + sLineBreak
      + 'AND TEST=''TEST''' + sLineBreak
      + 'ORDER BY EntCity ASC, EntStageName ASC';

    Optionally replace line breaks with spaces:

    SQL.Add('SELECT EntCity, EntStageName '
      + 'FROM Entertainers '
      + 'WHERE 1=1 '
      + 'AND TEST=''TEST'' '
      + 'ORDER BY EntCity ASC, EntStageName ASC');

     

    • Like 5

  10. Is it possible to write a language server in Delphi/Pascal, or should it be written in languages such as Java, JavaScript, TypeScript? BTW ErrorInsight was written in J# (correct me if I'm wrong), and it was a bad decision.

     

    Well I see the language server plugins for C/C++ written in C++, D plugin written in D, Dart Language Server written in Dart etc...

    • Like 1

  11. 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. 


  12. 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.


  13. Another observation. From the very beginning, we had this method of declaring procedures and functions:

    procedure procedureName(parameterList);
      localDeclarations;
    begin
      statements
    end;

    The reserved word begin marks the beginning of the procedure body. But starting from 10.3 local variables can be declared directly in the procedure body. Therefore, there is no need to save begin for procedures and functions:

    procedure procedureName(parameterList);
      localDeclarations;
      statements
    end;

     


  14. I think inline vars and type inference will be especially usefull in functional programming with Delphi.

    Now we write like this:

    program TestClosure;
    {$APPTYPE CONSOLE}
    uses
      SysUtils;
    var
      Proc: TProc;
    begin
      Proc := (function: TProc
        var
          n: Integer;
        begin
          n := 0;
          Result := procedure begin
            Write(n);
            Inc(n);
          end;
        end)();
      Proc;
      Proc;
      Proc;
      Proc;
      Readln
    end.

    In the new Delphi 10.3 Rio, this can probably be reduced to

    program TestClosure10_3;
    {$APPTYPE CONSOLE}
    uses
      SysUtils;
    begin
      var Proc := (function: TProc begin
        var n := 0;
        Exit(procedure begin
          Write(n);
          Inc(n);
        end);
      end)();
      Proc;
      Proc;
      Proc;
      Proc;
      Readln
    end.

    BTW can you say what this code will display?

    Similar JavaScript code for comparison:

    var func=(function(){
      var n = 0;
      return function(){
        console.log(n);
        n++;
      }
    })();
    func();
    func();
    func();
    func();

     

×