New language additions in Free Pascal

These are many new improvements of Object Pascal programming language in Free Pascal compiler. I don’t know how much new are they, but at least they are new since Delphi 7 language. I haven’t used any of these features before (until now) because I wasn’t know about them.

1. For .. in loop:

This can be used to loop in string characters:


procedure ForInLoop(aStr: string);
var
  ch: Char;
begin
  for ch in aStr do
    WriteLn(ch);
end;

or through set items:


procedure ForInSetLoop;
var
  s: set of 1 .. 100;
  i: Integer;
begin
  s:= [1, 3, 7];
  for i in s do
    Writeln(i);
end;

2. += operator

This new operator can be used to concatenate strings and add values to numbers:


var
  aName: string;
begin
  aName:= 'Free';
  aName += ' Pascal';
  Writeln(aName); // Free Pascal
end;

For numbers:


x:= 10;
x+= 15;
Writeln(x); // 25

3. Properties without OOP

Now you can define a property in a structured code:


var
  x: Integer;

procedure SetX(aX: Integer);
begin
  x:= ax;
end;

function GetX: Integer;
begin
  Result:= x;
end;

property MyX: Integer read GetX write SetX;

// Main program
begin
  MyX:= 170;
  Writeln(MyX);

end.

4. Bit packed record

You can define a record of bits, and display it as byte:

type
  tbit = 0..1;

  tBitsByte = bitpacked record
    bit0   : tbit;
    bit1   : tbit;
    bit2   : tbit;
    bit3   : tbit;
    bit4   : tbit;
    bit5   : tbit;
    bit6   : tbit;
    bit7   : tbit;
  end;

var
  aByte: tBitsByte;
begin
  aByte.bit0:= 1;
  aByte.bit1:= 0;
  aByte.bit2:= 1;
  Writeln(Byte(aByte)); // 5

5. Sealed class

You can prevent inheriting from a class by adding the keyword sealed:

TMyClass = class sealed
  private
    fValue: Integer;
  public
    constructor Create(aValue: Integer);
    destructor destroy; override;
    function GetValue: Integer;
end;

I couldn’t find a good example right now to explain why we need to do this, but in the future I may get one.

6. Class methods and variables

You can declare methods and variables that can be used by class name before object instantiation the same like Java static methods as in this example:


TMyClass = class sealed
  private
    class var fValue: Integer;
  public
    constructor Create(aValue: Integer);
    class function GetValue: Integer;
    class procedure SetValue(aValue: Integer);
end;

constructor TMyClass.Create(aValue: Integer);
begin
  inherited Create;
  fValue:= aValue;
end;

class function TMyClass.GetValue: Integer;
begin
  Result:= fValue;
end;

class procedure TMyClass.SetValue(aValue: Integer);
begin
  fValue:= aValue;
end;

// Main code

begin
  TMyClass.SetValue(900);
  Writeln(TMyClass.GetValue);
end.

7. case of String


case aName of
'Free Pascal': Writeln('Lazarus IDE');
'C++': Writeln('CodeBlocks IDE');
end;

 

If you know any new useful additions please let me now to write it here.

References:

http://lazarus.freepascal.org/index.php/topic,19107.0.html

http://www.freepascal.org/docs-html/ref/refse24.html#x56-630004.6

http://edn.embarcadero.com/article/34324

26 thoughts on “New language additions in Free Pascal

  1. May be the case variable is put in a processor register while comparison (I’m not sure), so that it should be an ordinal value, such as Integer, Byte, Characters, and Boolean. Non-ordinal values couldn’t be put into register such as Strings.
    Float types are also can’t be used either in Delphi or Free pascal.
    This is an example of compile-time error if you try to use Case with Double:

    unit1.pas(28,10) Error: Ordinal or string expression expected

  2. about case of String (FPC vs Delphi)

    in Delphi you have some workarounds this limitiation:

    http://www.phidels.com/php/forum/forum.php3?forumtable=postsbdd&mode=showpost&postid=9024

    http://www.developpez.net/forums/d620347/environnements-developpement/delphi/langage/case-string/

    but it’s true that a native implementation in FPC is great. Basically “case of only” works with Ordinal values (from the CPU point of view just imagine how case of is compile: a jump table).
    I believe that FPC natively performs a test on the string reference rather than on the string content itself (which would be slow and globally inefficient).

  3. Well, I just don’t see why Case has to be translated into a jump table. I just want an easy way to test for several values.

    This should be possible, imo:

    case {any value} of
            {any value}:  begin  {any code}  continue;  end;    // continues with the next value's code (default in C/C++)
            {any value}:  {any code};
            else          {any code};
    end;
    

    “{any value}” wouldn’t have to be a constant.

  4. Only until a difference is found, which shouldn’t take long for most strings. Often the first character is already different.

    Besides, in most cases I don’t care if the code can be translated into a jump table. When I have to test for lots of string cases, I would prefer a syntax that reduces the amount of source code I have to type.

  5. Yes, that’s right. Code readability and ease of writing it is a very important issue. The compiler should be smart enough to optimize this code for the best possible performance.

  6. “case of” generates jump tables in Delphi, and not nested cmp/jxx. If a “case of ” would generate, in asm, some complicated cmp/jxx then it’s fair that delphi doesn’t implement it, maybe it woulds give a wrong feeling about how the source code would be compiled.

    Now I don’t know how FPC handle this, but it’s probably not by an efficient comparison (for example in the RTL you have some good explanation on how strings are compared: begin with last char and then try to compare the content, etc).
    So it’s probably usefull (case of for string) but it’s probably faster not to use this but the efficients string comparison methods of the RTL…

  7. There is no problem in RTL, it is the same, for example my name:

    Name:= ‘معتز’;
    My first letter is Name[1], second is Name[2], etc. There is no difference between RTL and LTR in strings

  8. With FPC, you can directly retrieve the value of public variables belonging to a dll :
    MyVar: integer; external ‘MyDll.dll’ name ‘MyVar’;
    With Delphi, you can, but not in an immediate way :
    MyLib: = GetModuleHandle (‘MyDll.dll’);
    MyVar: = PInteger (GetProcAddress (MyLib, ‘MyVar’));

  9. For those who want to know FPC implementation, case of construct is translated to if-else if-else construct using AnsiCompareText as compare function on AnsiString type. probably it will be translated to unicode variant of the compare function in case of WideString, UTF8String or UnicodeString. It should be faster if the compiler could generate embedded prefix tree (with code size tradeoff) but currently this is not the case.

  10. ok, what about ordinal case .. of, is processor registered used, and does cross platform feature of FPC reduces the usage of processors registers in for loop, case, function calling?

  11. As far as I know such case statements does use some form of register and table to “goto” the piece of code in that ordinal’s portion of the program. This was even so in the Pascal days (i.e. late 80’s).

    But then it would only work for ordinals (and only ordinals which fit into registers). For anything else, the case (and case-like) statements would have to follow some if->elseif->elseif principle. I.e. it would work in a similar way as Lisp’s cond statement – which is exactly like a list of ifs in a row (just more elegant / simplistic to write).

    However, it does not mean a case/switch on a non-ordinal type can’t be done more optimally than a set of ifs or a cond. E.g. the values may be converted to a specific string type (say something like WideChar or UTF32 or even for the compiler to decide by checking the most complex string type from the code), then an ordinal hash value can be used. The variable string then simply needs to be converted to the same string type and a hash calculated on it. Thereafter the normal ordinal case implementation can be used. Perhaps an even more optimal way would be to force some specific (customizable) string type in this case – then no conversion would be needed, only hashing.

  12. On second thought, hashing might not be more optimal in all cases. So this might need a bit of investigation.

    But if a consistent string type / encoding can be used, then the comparison itself might be optimized by simply using some bitwise comparison.

  13. the King is ded long live the King…

    I have learned Pascal, it had been very important in my education, but that was like 20 years ago….
    Sorry, but I can not take those statements serious, I learned Delphy to…

    But when somebody is ded livit be, and that is mu oppinion os this subjece….

  14. If you don’t like it, don’t use it.

    In some cases the ‘case of String’ comes truly handy, and I think it is useful. Sometimes, e.g. when parsing user input, trading speed for ease of use is not a penalty. Of course one should think twice before using such a feature in a loop executed millions of times.

  15. @jonDo711
    It’s not “ded”. Pascal still has decent capabilities (even compared to other “new” languages). It’s main benefit is due to stuff like Lazarus allowing much easier portable UI design without loosing performance like you get through Java or even Qt.

    Most executables compiled through it would be similar to a C++ executable’s performance, but without the hoops to jump through to get it working properly on Window & linux, and, and, and. It’s definitely much more efficient than Python’s executables. And with most other “new” languages you need to use some extra libs (at best) or a VM (at worst) to have it portable. E.g. with C++ you’d need something like wxWidgets / Qt to design once and run many times – else you need the JVM (or similar).

    So it’s (Lazarus) one of the few languages you can use to write efficient portable code very easily. And that (IMO) is why it’s not dead.

    If you state that it should be “left to die” and not waste time on updating it, then you could just as well state that none of the updates to C++ should have happened (i.e. functional / lambda / ec.). Actually you should then also have been able to state that the C++ extensions onto C (in order to give C some OOP in the 80’s) should have been left off in preference to something like Simula / Lisp which already had OOP far in excess of what C++ even has now.

  16. I worked on a port of the Pascal P-Code compiler in the late 1970s. The case statement in those days was effectively a selector for sets and sets could only take up to 64 members, so the case statement was implemented as a 64 offsets branch table (the team that I was on optimised it to use a smaller table if there were less than 64 members). The new syntax cannot work with a simple offset branch list and must be done by effectively if-the-else chains or hashing; it is, therefore, a different construct behind the scenes with the same syntax.

    Also, converting bits to bytes used to be automatic – the ‘packed’ keyword did that.

    Apologies for any spelling errors – the required fields text boxes overlay the comments box in my browser, so I am typing blind.

  17. You have worked on Pascal P-Code compiler! you should be one of the famous developers, did you work for Borland and what is your name if you don’t mind
    Thanks

    Motaz Abdel Azeem

  18. Most probably all these “new” features are only new in Pascal (and its derivatives). E.g. the Foreach is very similar to the map function in Lisp which already worked on any sequence (Array / Linked List / Set / String) since at least the 70’s. The x += y; is an old shortcut of writing x = x + y; from C++ … it “might” allow for some optimized assembly code though – seeing as one of the operands is also the variable to receive the result.

    It’s not “new” programming features, it’s new features for Pascal, so yes sealed is most probably similar to java’s final. I’ve yet to see anything truly “new” in any language for the past 30 to 50 years.

  19. @jonDo711

    This is the future of FPC and Lazarus, it seems not to be dead at all:

    http://www.pilotlogic.com/sitejoom/index.php/codetyphon

    CodeTyphon is the FREE “Pascal Visual Programming Studio”,
    for Cross-Platform Native Development,
    with Multi-OS, Multi-CPU and Cross-Build abilities.
    Has Lazarus+FreePascal+Tools+Free Components packages+Free Libraries
    and all these with full source and samples.

    Build capabilities:
    http://www.pilotlogic.com/sitejoom/index.php/wiki/88-wiki/codetyphon-studio/technical/185-freepascal-build-capabilities
    http://www.pilotlogic.com/sitejoom/index.php/wiki/88-wiki/codetyphon-studio/technical/186-lazarus-ide-build-capabilities

    😉

Leave a comment