Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2015-07

Interface syntax: Is possible don't use specialize in mode objfpc?

54 messages · 11 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Marcos Douglas

Hi,

Is there some way to write this:
type
  generic ICloneable<T> = interface
    function Clone: T;
  end;
...using this sintaxe:
type
  ICloneable<T> = interface
    function Clone: T;
  end;

Because I would like to use:
TFoo = class(ICloneable<TFoo>)

...instead use:
TFoo = class(specialize ICloneable<TFoo>)

But using {$mode objfpc}, ie, if exists some compiler directive to change only this syntax, that is the same in Delphi.

I would like to know why exists this difference, what the advantages for mode objfpc using this syntax.

Thank you very much.

Marcos Douglas

Maciej Izak
to Marcos Douglas

sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc.

2015-07-16 15:34 GMT+02:00 Marcos Douglas:

Hi, Is there some way to write this:

Best regards

Maciej Izak

Michael Van Canneyt
to Maciej Izak
Maciej Izak wrote
sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc.

That seems like a very strange reason to me.

The fact that you must type 1 word in certain places keeps you from using an otherwise useful mode ? This word is there for clarity, It is meant to help you, to make explicit you are in fact specializing a new type.

Michael.

Sven Barth
to Maciej Izak: sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc. 2015-07-16…
"Maciej Izak" wrote
sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc.

Then let me tell you that generic methods will arrive in mode ObjFPC (and thus its syntax) first, because the Delphi syntax is a PITA to parse/handle. (in fact generic methods are already working in mode ObjFPC in my local repo, I just want to get the Delphi ones working a little bit before commiting to trunk)

Regards,
Sven

Marcos Douglas
to Sven Barth
Sven Barth wrote 10 lines
Am 16.07.2015 16:34 schrieb "Maciej Izak" : > > sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc. > Then let me tell you that generic methods will arrive in mode ObjFPC (and thus its syntax) first, because the Delphi syntax is a PITA to parse/handle. (in fact generic methods are already working in mode ObjFPC in my local repo, I just want to get the Delphi ones working a little bit before commiting to trunk)

I didn't understand. This already works... or you talking about "work with the same syntax than Delphi in mode objfpc"?

I will repeat also the last paragraph of the first message: I would like to know why exists this difference, what the advantages for mode objfpc using this syntax.

Regards,

Marcos Douglas

Graeme Geldenhuys
to Marcos Douglas
Marcos Douglas wrote
I would like to know why exists this difference, what the advantages for mode objfpc using this syntax.

Michael already answered that.

"It is meant to help you, to make explicit you are in fact specializing a new type."

The objfpc mode is normally more strict than the delphi mode, and the objfpc is more true to the Object Pascal language - keeping the code more Pascal-like. Delphi (EMBT) is hodge podge of other languages with no regard for Pascal-like syntax.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/
Marcos Douglas
to Michael Van Canneyt: That seems like a very strange reason to me. The fact that you must type 1 word in…
Michael Van Canneyt wrote 13 lines
On Thu, 16 Jul 2015, Maciej Izak wrote: > sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc. That seems like a very strange reason to me. The fact that you must type 1 word in certain places keeps you from using an otherwise useful mode ? This word is there for clarity, It is meant to help you, to make explicit you are in fact specializing a new type.

Yes, but do you think this is more verbose unnecessarily? Because the syntax TFoo<T> (I mean this "") show us that is a generic, don't?

The Lazarus also has some troubles with the code completion using this: TFoo = class(TInterfacedObject, specialize ICloneable<TFoo>)

Sometimes the IDE shows an error in interface declaration, but compiles. So, to not receive these errors I have to create a new type:

TFoo = class; //forward
IFooCloneable = specialize ICloneable<TFoo>;
TFoo = class(TInterfacedObject, IFooCloneable)
//...
end;
...making even more verbose.

Regards,
Marcos Douglas

Graeme Geldenhuys
to Marcos Douglas
Marcos Douglas wrote
Sometimes the IDE shows an error in interface declaration, but compiles. So, to not receive these errors I have to create a new type:

So, that is then a bug in Lazarus's codetools or parser - report it for the Lazarus project.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/
Sven Barth
to Marcos Douglas: On Thu, Jul 16, 2015 at 11:44 AM, Michael Van Canneyt Yes, but do you think this is more…
Marcos Douglas wrote 18 lines
On Thu, Jul 16, 2015 at 11:44 AM, Michael Van Canneyt wrote: > > > On Thu, 16 Jul 2015, Maciej Izak wrote: > >> sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc. > > > That seems like a very strange reason to me. > > The fact that you must type 1 word in certain places keeps you from using an > otherwise useful mode ? > This word is there for clarity, It is meant to help you, to make explicit > you are in fact specializing a new type. Yes, but do you think this is more verbose unnecessarily? Because the syntax TFoo<T> (I mean this "") show us that is a generic, don't?

This might be the case for a human, but for a compiler/parser that is a completely different topic. Take the following example code (with generic methods to highlight the problems I'm facing right now):

=== code begin ===

type
   TTest = class
     function Add: LongInt;
     function Add<T>(aLeft, aRight: T): T;
   end;
var
   t: TTest;
   i: LongInt;
begin
   i := t.Add<LongInt>(2, 4);
end;

=== code end ===

The parser sees the following tokens after the assignment: identifier ('t'), point, identifier ('Add'), less than, identifier ('LongInt'), greater than, left parenthesis, etc.
Our parser only knows the next token, up until the "greater than" (or if there is more than one type parameter the "," for the next parameter) the parser does not know whether it is dealing with a call to generic method Add<X, Y, Z> or a call to a function Add followed by a comparison. This is highly ambigous and a real PITA to implement.

In non-Delphi modes this is much more straight forward:

=== code begin ===

type
   TTest = class
     function Add: LongInt;
     generic function Add<T>(aLeft, aRight: T): T;
   end;
var
   t: TTest;
   i: LongInt;
begin
   i := t.specialize Add<LongInt>(2, 4);
end;

=== code end ===

No sambiguity here. Nice :)

Regards,
Sven

Sven Barth
to Marcos Douglas: On Thu, Jul 16, 2015 at 12:23 PM, Sven Barth I didn't understand. This already works...…
Marcos Douglas wrote 15 lines
On Thu, Jul 16, 2015 at 12:23 PM, Sven Barth wrote: > Am 16.07.2015 16:34 schrieb "Maciej Izak" : >> >> sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc. >> > > Then let me tell you that generic methods will arrive in mode ObjFPC (and > thus its syntax) first, because the Delphi syntax is a PITA to parse/handle. > (in fact generic methods are already working in mode ObjFPC in my local > repo, I just want to get the Delphi ones working a little bit before > commiting to trunk) I didn't understand. This already works... or you talking about "work with the same syntax than Delphi in mode objfpc"?

Generic methods are not yet supported by FPC. Try the following Delphi code in 3.1.1 for example (in mode Delphi):

=== code begin ===

type
   TTest = class
     function Add<T>(aLeft, aRight: T): T;
   end;
function TTest.Add<T>(aLeft, aRight: T): T;
begin
   Result := aLeft + aRight;
end;
var
   t: TTest;
   i: LongInt;
   s: String;
begin
   i := t.Add<LongInt>(2, 4);
   s := t.Add<String>('Hello', 'World');
end.

=== code end ===

This does not compile in FPC currently. In my local repo the above is close to working and the following non-Delphi-mode code definitely works:

=== code begin ===

type
   TTest = class
     generic function Add<T>(aLeft, aRight: T): T;
   end;
generic function TTest.Add<T>(aLeft, aRight: T): T;
begin
   Result := aLeft + aRight;
end;
var
   t: TTest;
   i: LongInt;
   s: String;
begin
   i := t.specialize Add<LongInt>(2, 4);
   s := t.specialize Add<String>('Hello', 'World');
end.

=== code end ===

I will repeat also the last paragraph of the first message: I would like to know why exists this difference, what the advantages for mode objfpc using this syntax.

Less ambiguity for both the user as well as the compiler. In fact if I had already been with a FPC developer back when generics were implemented before 2.2 I had implemented specialization somewhat like the following:

=== code begin ===

begin
   i := t.specialize Add with (LongInt)(2,4);
   i := t.specialize Add with (String)('Hello', 'World');
end.

=== code end ===

This way there would be no ambiguity with the "<" at all... but sadly I wasn't a FPC developer back then. :) (and I would have needed to implement the Delphi compatible one for mode Delphi anyway and just like I do now I would have cursed just as much ^^)

Regards,
Sven

Michael Van Canneyt
to Marcos Douglas: On Thu, Jul 16, 2015 at 11:44 AM, Michael Van Canneyt Yes, but do you think this is more…
Marcos Douglas wrote 21 lines
On Thu, Jul 16, 2015 at 11:44 AM, Michael Van Canneyt wrote: > > > On Thu, 16 Jul 2015, Maciej Izak wrote: > >> sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc. > > > That seems like a very strange reason to me. > > The fact that you must type 1 word in certain places keeps you from using an > otherwise useful mode ? > This word is there for clarity, It is meant to help you, to make explicit > you are in fact specializing a new type. Yes, but do you think this is more verbose unnecessarily? Because the syntax TFoo<T> (I mean this "") show us that is a generic, don't? The Lazarus also has some troubles with the code completion using this: TFoo = class(TInterfacedObject, specialize ICloneable<TFoo>)

Lazarus is not alone, even I have trouble with this :)

Show quoted text 12 lines
Sometimes the IDE shows an error in interface declaration, but compiles. So, to not receive these errors I have to create a new type: TFoo = class; //forward IFooCloneable = specialize ICloneable<TFoo>; TFoo = class(TInterfacedObject, IFooCloneable) //... end; ...making even more verbose.

Pascal is a verbose language. If you want terse, use C++ or something like it.

The whole generics mess that Delphi made goes completely against the Pascal dictum that you must declare something before you can use it.

To me, the above verbose construction makes absolute sense. It has been so since day 1:

PRecord = ^TRecord;
TRecord = record
   a : integer;
   next : PRecord;
end;

Michael.

silvioprog
to Michael Van Canneyt

On Thu, Jul 16, 2015 at 2:21 PM, Michael Van Canneyt <

Show quoted text 64 lines
wrote: On Thu, 16 Jul 2015, Marcos Douglas wrote: > On Thu, Jul 16, 2015 at 11:44 AM, Michael Van Canneyt > wrote: > >> >> >> On Thu, 16 Jul 2015, Maciej Izak wrote: >> >> sadly - no, only in Delphi mode. btw. this thing keep me away from >>> objfpc. >>> >> >> >> That seems like a very strange reason to me. >> >> The fact that you must type 1 word in certain places keeps you from >> using an >> otherwise useful mode ? >> This word is there for clarity, It is meant to help you, to make explicit >> you are in fact specializing a new type. >> > > Yes, but do you think this is more verbose unnecessarily? Because the > syntax TFoo<T> (I mean this "") show us that is a generic, don't? > > The Lazarus also has some troubles with the code completion using this: > TFoo = class(TInterfacedObject, specialize ICloneable<TFoo>) > Lazarus is not alone, even I have trouble with this :) > Sometimes the IDE shows an error in interface declaration, but compiles. > So, to not receive these errors I have to create a new type: > > TFoo = class; //forward > > IFooCloneable = specialize ICloneable<TFoo>; > > TFoo = class(TInterfacedObject, IFooCloneable) > //... > end; > ...making even more verbose. > Pascal is a verbose language. If you want terse, use C++ or something like it. The whole generics mess that Delphi made goes completely against the Pascal dictum that you must declare something before you can use it. To me, the above verbose construction makes absolute sense. It has been so since day 1: PRecord = ^TRecord; TRecord = record a : integer; next : PRecord; end; Michael.

IMHO this could be decided via poll, because several users around the world are using FPC too. For example, in a polling, I would vote in less keywords, e.g: [+1 vote for: "TFoo = class(TInterfacedObject, ICloneable<TFoo>)" / "t.Add<LongInt>(2, 4);"] and [-1 vote for: "TFoo = class(TInterfacedObject, specialize ICloneable<TFoo>)" / "t.specialize Add<LongInt>(2, 4);"].

The more verbose a language becomes, and needs more keywords to do simple things, the more chances it has to be depreciated.

I use other languages too, like Java (Android) and JS (front-end / AngularJS), but here in our company we are testing and thinking about migrating a lot of our online structure to Node.js, because it is very productive and less burocratic. For while we are using a mix of Pascal (XE8/FPC 3) and Node.js via proxy + websocket, but the trend is to use only JS in front-end and back-end.

Silvio Clécio My public projects - github.com/silvioprog
Marcos Douglas
to Sven Barth: This might be the case for a human, but for a compiler/parser that is a completely…
Sven Barth wrote 59 lines
On 16.07.2015 18:02, Marcos Douglas wrote: > > [...] > > Yes, but do you think this is more verbose unnecessarily? Because the > syntax TFoo<T> (I mean this "") show us that is a generic, don't? This might be the case for a human, but for a compiler/parser that is a completely different topic. Take the following example code (with generic methods to highlight the problems I'm facing right now): === code begin === type TTest = class function Add: LongInt; function Add<T>(aLeft, aRight: T): T; end; var t: TTest; i: LongInt; begin i := t.Add<LongInt>(2, 4); end; === code end === The parser sees the following tokens after the assignment: identifier ('t'), point, identifier ('Add'), less than, identifier ('LongInt'), greater than, left parenthesis, etc. Our parser only knows the next token, up until the "greater than" (or if there is more than one type parameter the "," for the next parameter) the parser does not know whether it is dealing with a call to generic method Add<X, Y, Z> or a call to a function Add followed by a comparison. This is highly ambigous and a real PITA to implement. In non-Delphi modes this is much more straight forward: === code begin === type TTest = class function Add: LongInt; generic function Add<T>(aLeft, aRight: T): T; end; var t: TTest; i: LongInt; begin i := t.specialize Add<LongInt>(2, 4); end; === code end === No sambiguity here. Nice :)

I see... More verbose is more easy to compile, making a parser without ambiguity and faster.

Regards,
Marcos Douglas

Michael Van Canneyt
to silvioprog: On Thu, Jul 16, 2015 at 2:21 PM, Michael Van Canneyt < IMHO this could be decided via…
silvioprog wrote 62 lines
On Thu, Jul 16, 2015 at 2:21 PM, Michael Van Canneyt wrote: On Thu, 16 Jul 2015, Marcos Douglas wrote: On Thu, Jul 16, 2015 at 11:44 AM, Michael Van Canneyt wrote: On Thu, 16 Jul 2015, Maciej Izak wrote: sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc. That seems like a very strange reason to me. The fact that you must type 1 word in certain places keeps you from using an otherwise useful mode ? This word is there for clarity, It is meant to help you, to make explicit you are in fact specializing a new type. Yes, but do you think this is more verbose unnecessarily? Because the syntax TFoo<T> (I mean this "") show us that is a generic, don't? The Lazarus also has some troubles with the code completion using this: TFoo = class(TInterfacedObject, specialize ICloneable<TFoo>) Lazarus is not alone, even I have trouble with this :) Sometimes the IDE shows an error in interface declaration, but compiles. So, to not receive these errors I have to create a new type: TFoo = class; //forward IFooCloneable = specialize ICloneable<TFoo>; TFoo = class(TInterfacedObject, IFooCloneable) //... end; ...making even more verbose. Pascal is a verbose language. If you want terse, use C++ or something like it. The whole generics mess that Delphi made goes completely against the Pascal dictum that you must declare something before you can use it. To me, the above verbose construction makes absolute sense. It has been so since day 1: PRecord = ^TRecord; TRecord = record   a : integer;   next : PRecord; end; Michael. IMHO this could be decided via poll, because several users around the world are using FPC too. For example, in a polling, I would vote in less keywords, e.g: [+1 vote for: "TFoo = class(TInterfacedObject, ICloneable<TFoo>)" / "t.Add<LongInt>(2, 4);"] and [-1 vote for: "TFoo = class(TInterfacedObject, specialize ICloneable<TFoo>)" / "t.specialize Add<LongInt>(2, 4);"]. The more verbose a language becomes, and needs more keywords to do simple things, the more chances it has to be depreciated.

You better wake up, pascal is long deprecated.

I use other languages too, like Java (Android) and JS (front-end / AngularJS), but here in our company we are testing and thinking about migrating a lot of our online structure to Node.js, because it is very productive and less burocratic. For while we are using a mix of Pascal (XE8/FPC 3) and Node.js via proxy + websocket, but the trend is to use only JS in front-end and back-end.

And you honestly think that this change will stop this process ?

People that feel that this is a problem can use mode Delphi.

Michael.

Marcos Douglas
to Sven Barth: Generic methods are not yet supported by FPC. Try the following Delphi code in 3.1.1 for…
Sven Barth wrote 83 lines
On 16.07.2015 17:53, Marcos Douglas wrote: > > [...] > > I didn't understand. This already works... or you talking about "work > with the same syntax than Delphi in mode objfpc"? Generic methods are not yet supported by FPC. Try the following Delphi code in 3.1.1 for example (in mode Delphi): === code begin === type TTest = class function Add<T>(aLeft, aRight: T): T; end; function TTest.Add<T>(aLeft, aRight: T): T; begin Result := aLeft + aRight; end; var t: TTest; i: LongInt; s: String; begin i := t.Add<LongInt>(2, 4); s := t.Add<String>('Hello', 'World'); end. === code end === This does not compile in FPC currently. In my local repo the above is close to working and the following non-Delphi-mode code definitely works: === code begin === type TTest = class generic function Add<T>(aLeft, aRight: T): T; end; generic function TTest.Add<T>(aLeft, aRight: T): T; begin Result := aLeft + aRight; end; var t: TTest; i: LongInt; s: String; begin i := t.specialize Add<LongInt>(2, 4); s := t.specialize Add<String>('Hello', 'World'); end. === code end === > > I will repeat also the last paragraph of the first message: > I would like to know why exists this difference, what the advantages > for mode objfpc using this syntax. Less ambiguity for both the user as well as the compiler. In fact if I had already been with a FPC developer back when generics were implemented before 2.2 I had implemented specialization somewhat like the following: === code begin === begin i := t.specialize Add with (LongInt)(2,4); i := t.specialize Add with (String)('Hello', 'World'); end. === code end === This way there would be no ambiguity with the "<" at all... but sadly I wasn't a FPC developer back then. :) (and I would have needed to implement the Delphi compatible one for mode Delphi anyway and just like I do now I would have cursed just as much ^^)

Ok Sven, you and others persuaded me to continue using the mode ObjFPC. Thank you for your explanations.

Regards,
Marcos Douglas

Maciej Izak
to Sven Barth: Then let me tell you that generic methods will arrive in mode ObjFPC (and thus its…

2015-07-16 17:23 GMT+02:00 Sven Barth :

Show quoted text 7 lines
Then let me tell you that generic methods will arrive in mode ObjFPC (and thus its syntax) first, because the Delphi syntax is a PITA to parse/handle. (in fact generic methods are already working in mode ObjFPC in my local repo, I just want to get the Delphi ones working a little bit before commiting to trunk)

@Sven, @Michael

I am using generics all the time for many things.

IMO using "generic/specialize" syntax because it is more simple to implement in compiler is very strange motivation. Using specialize keyword maybe is good in pure theory but is non practical (generic keyword in type declaration is not so bad).

You can torture me (!!!) but I will not use so many unnecessary words for simple things.
By using this complicated syntax you will kill all functional/generic approach.

Advice "if you like shorter syntax then go to other language" is no solution for me. I like some modern versions of Pascal like presented in Oxygen and till Delphi XE2 (! many things after XE2 is pure evil).

I am working on smart pointers/objects (some evolution/for the purposes of Generics.Collections). Syntax with generic/specialize is not "smart" for my branch:

=============== CODE BEGIN ===============
{$MODE SPARTA}
var
  X: strong TDictionary<weak TList<Integer>, string>;

{ sugar syntax for
var
X: SmartObj<TDictionary<WeakObj<TList<Integer>>, string>>; } =============== CODE END ===============

so probably in ObjFPC, code above will become:

=============== CODE BEGIN ===============
{$MODE OBJFPC}
type
  TList_Integer = specialize TList<Integer>;
  WeakObj_TList_Integer = specialize WeakObj<TList_Integer>;
  TDictionary_WeakObj_TList_Integer_String = specialize
TDictionary<WeakObj_TList_Integer, string>;
  SmartObj_TDictionary_WeakObj_TList_Integer_String = specialize
SmartObj<TDictionary_WeakObj_TList_Integer_String>;
var
  X: SmartObj_TDictionary_WeakObj_TList_Integer_String;
===============  CODE END  ===============

Another simple example. Maybe not a good example to follow, but it shows the problems:

===============FPC CODE BEGIN===============
type
  generic ISomeInterface<T> = interface
    function Invoke(AValue: T): Boolean;
  end;
  // arghhhhhh... O____o generics types that are in half generic...
  TList_Integer = specialize TList<Integer>;
  TDictionary_TInteger_List_String = specialize TDictionary<TIntegerList,
string>;
  TArray_TList_Integer = specialize TArray<TListInteger>;
  ISomeInterface_TArray_TList_Integer = specialize
ISomeInterface<TArrayTListInteger>;
  TEqualityComparer_TList_Integer = specialize
TEqualityComparer<TList_Integer>;
  TFunc_TArray_TList_Integer_RESULT_Boolean = specialize TFunc<
TArray_TList_Integer, Boolean>;
  TComparer_TList_Integer = specialize TComparer<TList_Integer>;
var
  d: TDictionary_TInteger_List_String;
  e: TArray_TList_Integer;
  c: ISomeInterface_TArray_TList_Integer;
  l: TInteger_List;
begin
  // you are killing future usage of closures
  d := TDictionary_TInteger_List_String.Create(
      TEqualityComparer_TList_Integer.Construct(
        function(constref ALeft, ARight: TInteger_List): Boolean
        begin
          // ...
        end,
        function(constref AValue: TInteger_List): UInt32
        begin
          // ...
        end
      )
    );
  // another example with closures
  TFunc_TArray_TList_Integer_RESULT_Boolean(c)
    := function(AValue: TArray_TList_Integer): Boolean
       var
         LIndex: Integer;
       begin
         TArray.specialize BinarySearch<TList_Integer>(
           AValue, SomeList, LIndex,
           TComparer_TList_Integer.Construct(
             function(constref Left, Right: TList_Integer): Integer
             begin
               // ...
             end
           )
         )
       end;
  c(l);
  e := d.Keys.ToArray();
  // you are killing simple things
  TArray.specialize Sort<TList_Integer>(e,
TComparer_TList_Integer.Construct(
      function(constref Left, Right: TList_Integer): Integer
      begin
        // ...
      end)
    );
=============== FPC CODE END ===============
===============DELPHI CODE BEGIN===============
type
  ISomeInterface<T> = interface
    function Invoke(AValue: T): Boolean;
  end;
var
  d: TDictionary<TList<Integer>, string>;
  e: TArray<TList<Integer>>;
  c: ISomeInterface<TArray<TList<Integer>>>;
  l: TList<Integer>;
begin
  d := TDictionary<TList<Integer>, string>.Create(
      TEqualityComparer<TList<Integer>>.Construct(
        function(const ALeft, ARight: TList<Integer>): Boolean
        begin
        end,
        function(const AValue: TList<Integer>): Integer
        begin
        end
      )
    );
  TFunc<TArray<TList<Integer>>, Boolean>(c)
    := function(AValue: TArray<TList<Integer>>): Boolean
       var
         LIndex: Integer;
       begin
         TArray.BinarySearch<TList<Integer>>(
           AValue, l, LIndex,
           TComparer<TList<Integer>>.Construct(
             function(const Left, Right: TList<Integer>): Integer
             begin
               //...
             end
           )
         )
       end;
  c(l);
  e := d.Keys.ToArray();
  TArray.Sort<TList<Integer>>(e, TComparer<TList<Integer>>.Construct(
      function(const Left, Right: TList<Integer>): Integer
      begin
        //...
      end)
    );
=============== DELPHI CODE END ===============

Best regards,
Maciej Izak

Sven Barth
to Michael Van Canneyt: Lazarus is not alone, even I have trouble with this :) Pascal is a verbose language. If…
Michael Van Canneyt wrote 11 lines
The whole generics mess that Delphi made goes completely against the Pascal dictum that you must declare something before you can use it. To me, the above verbose construction makes absolute sense. It has been so since day 1: PRecord = ^TRecord; TRecord = record a : integer; next : PRecord; end;

For things like the following you can't use the "declare before use" paradigm however:

=== code begin ===

type
   generic ITest<T> = interface
     function Foo: T;
   end;
   generic TTest<T> = class(TInterfacedObject, specialize ITest<T>)
     function Foo: T;
   end;

=== code end ===

Regards,
Sven

Sven Barth
to Marco van de Voort: In our previous episode, Sven Barth said: https://xkcd.com/927/
Marco van de Voort wrote 8 lines
In our previous episode, Sven Barth said: >> sadly - no, only in Delphi mode. btw. this thing keep me away from objfpc. >> > > Then let me tell you that generic methods will arrive in mode ObjFPC (and > thus its syntax) first, because the Delphi syntax is a PITA to parse/handle. https://xkcd.com/927/

I'm merely building on the syntax FPC already supports.

Regards,
Sven

Sven Barth
to Maciej Izak: 2015-07-16 17:23 GMT+02:00 Sven Barth : @Sven, @Michael I am using generics all the time…
Maciej Izak wrote 38 lines
2015-07-16 17:23 GMT+02:00 Sven Barth < >: Then let me tell you that generic methods will arrive in mode ObjFPC (and thus its syntax) first, because the Delphi syntax is a PITA to parse/handle. (in fact generic methods are already working in mode ObjFPC in my local repo, I just want to get the Delphi ones working a little bit before commiting to trunk) @Sven, @Michael I am using generics all the time for many things. IMO using "generic/specialize" syntax because it is more simple to implement in compiler is very strange motivation. Using specialize keyword maybe is good in pure theory but is non practical (generic keyword in type declaration is not so bad). You can torture me (!!!) but I will not use so many unnecessary words for simple things. By using this complicated syntax you will kill all functional/generic approach. Advice "if you like shorter syntax then go to other language" is no solution for me. I like some modern versions of Pascal like presented in Oxygen and till Delphi XE2 (! many things after XE2 is pure evil). I am working on smart pointers/objects (some evolution/for the purposes of Generics.Collections). Syntax with generic/specialize is not "smart" for my branch: =============== CODE BEGIN =============== {$MODE SPARTA} var X: strong TDictionary<weak TList<Integer>, string>;

Prefixed modifiers are the /worst/ you can do for Pascal.

Show quoted text 20 lines
{ sugar syntax for var X: SmartObj<TDictionary<WeakObj<TList<Integer>>, string>>; } =============== CODE END =============== so probably in ObjFPC, code above will become: =============== CODE BEGIN =============== {$MODE OBJFPC} type TList_Integer = specialize TList<Integer>; WeakObj_TList_Integer = specialize WeakObj<TList_Integer>; TDictionary_WeakObj_TList_Integer_String = specialize TDictionary<WeakObj_TList_Integer, string>; SmartObj_TDictionary_WeakObj_TList_Integer_String = specialize SmartObj<TDictionary_WeakObj_TList_Integer_String>; var X: SmartObj_TDictionary_WeakObj_TList_Integer_String; =============== CODE END =============== Another simple example. Maybe not a good example to follow, but it shows the problems:

The generic and specialize keywords and inline specialization are two completely different topics (plus nested specializations, which are simply not supported yet). While currently mode FPC uses the keywords, but does not allow inline specializations I'm in favor of allowing the latter in mode ObjFPC as well, because with the future addition of generic methods it would simply be strange to not allow it. Also we already allow it for parameters and partially for variable declarations as well, so not allowing it in code is simply inconsistent...

In the end your code above will look like this in mode ObjFPC:

=== code begin ===

var
   X: specialize SmartObj<specialize TDictionary<specialize
WeakObj<specialize TList<Integer> >, string> >;
// the spaces between the "> >" are added, because I don't know yet
whether I'll be able to deal with the fact that the scanner always
converts ">>" to "shr" (and "<<" to "shl")

=== code end ===

Regards,
Sven

Maciej Izak
to Sven Barth

2015-07-16 22:40 GMT+02:00 Sven Barth :

Show quoted text 6 lines
var > X: strong TDictionary<weak TList<Integer>, string>; > Prefixed modifiers are the /worst/ you can do for Pascal.

it is already being done by introducing "specialize" keyword.

I have totally different opinion :) for me it is beautiful:

http://docs.elementscompiler.com/Platforms/Cocoa/StorageModifiers/

Show quoted text 13 lines
In the end your code above will look like this in mode ObjFPC: === code begin === var X: specialize SmartObj<specialize TDictionary<specialize WeakObj<specialize TList<Integer> >, string> >; // the spaces between the "> >" are added, because I don't know yet whether I'll be able to deal with the fact that the scanner always converts ">>" to "shr" (and "<<" to "shl") === code end ===

no difference ;) contrary to the principle of KISS

Best regards,
Maciej Izak

Michael Van Canneyt
to Maciej Izak: 2015-07-16 17:23 GMT+02:00 Sven Barth : @Sven, @Michael I am using generics all the time…
Maciej Izak wrote 16 lines
2015-07-16 17:23 GMT+02:00 Sven Barth : Then let me tell you that generic methods will arrive in mode ObjFPC (and thus its syntax) first, because the Delphi syntax is a PITA to parse/handle. (in fact generic methods are already working in mode ObjFPC in my local repo, I just want to get the Delphi ones working a little bit before commiting to trunk) @Sven, @Michael I am using generics all the time for many things. IMO using "generic/specialize" syntax because it is more simple to implement in compiler is very strange motivation. Using specialize keyword maybe is good in pure theory but is non practical (generic keyword in type declaration is not so bad). You can torture me (!!!) but I will not use so many unnecessary words for simple things. By using this complicated syntax you will kill all functional/generic approach.

No problem. Use mode Delphi then, that's what it is for.

<sarcasm>
Why bother with mode objfpc ? It only makes life more difficult. You need to use @ when there is no need really, you are restricted in your choice of names. Why use it at all ?
</sarcasm/>

And you are discussing with the wrong person. I don't think generics are very useful to begin with. I can see a use case for a simpler declaration of collections, but that's about it.

Silvio mentioned his company is moving to Node.js. That means Javascript. I program Javascript myself.
Javascript is an unbelievably primitive language, yet is is increasingly popular.

To me, that tells me that all these additions to Object Pascal which everyone claims are 'so essential' are in fact pure nonsense. Eye candy to make it look modern.

Michael.

silvioprog
to Michael Van Canneyt

On Thu, Jul 16, 2015 at 6:44 PM, Michael Van Canneyt <

Show quoted text 43 lines
wrote: On Thu, 16 Jul 2015, Maciej Izak wrote: > 2015-07-16 17:23 GMT+02:00 Sven Barth : > > Then let me tell you that generic methods will arrive in mode > ObjFPC (and thus its syntax) first, because the Delphi syntax is a PITA to > parse/handle. > > (in fact generic methods are already working in mode ObjFPC in my > local repo, I just want to get the Delphi ones working a little bit before > commiting to trunk) > > > @Sven, @Michael > > I am using generics all the time for many things. > > IMO using "generic/specialize" syntax because it is more simple to > implement in compiler is very strange motivation. Using specialize keyword > maybe is good in pure theory but is non practical > (generic keyword in type declaration is not so bad). > > You can torture me (!!!) but I will not use so many unnecessary words for > simple things. > By using this complicated syntax you will kill all functional/generic > approach. > No problem. Use mode Delphi then, that's what it is for. <sarcasm> Why bother with mode objfpc ? It only makes life more difficult. You need to use @ when there is no need really, you are restricted in your choice of names. Why use it at all ? </sarcasm/> And you are discussing with the wrong person. I don't think generics are very useful to begin with. I can see a use case for a simpler declaration of collections, but that's about it.

Buddy, with generics you can do other things besides fast creation of lists. =) Please take a look at this little sample below.

Generics are very useful, and one of many possibilities that generics provides is the "compilation time validation", for example, see this small code below:

=== begin code ===

TPersonDao = class(TObject)
public
  procedure Save(APerson: TObject);
end;
TPersonDao.Save(APerson: TObject);
begin
  if not (APerson is TPerson) then
    raise EPersonDaoInvalidType.CreateResFmt(@SInvalidEntityClass,
[APerson.ClassName, TPerson.ClassName]);
  // other codes for TPerson persistance ...
end;

=== end code ===

This code above will check if the instance of my parameter is from a TPerson class, if so, persist it, otherwise raise an exception. It avoids something like this:

=== begin code ===

var
  VProduct: TProduct;
  ...
  VSomePersonDao: TPersonDao;
begin
  ...
  VSomePersonDao.Save(VProduct); // a type, for example (mistakes happen,
we are human =D )

=== end code ===

OK, it will raise an exception "Cannot persist a 'TProduct' using a 'TPersonDao'". Nice, but this error will be showed in production and for my customer, and it is very bad. =/ Using generics you can avoid it:

=== begin code ===

TPersonDao<T> = class(TObject)
public
  procedure Save(APerson: T);
end;
TPersonDao.Save(APerson: T);
begin
  // the codes for TPerson persistance ...
end;

=== end code ===

It does not need EPersonDaoInvalidType, because:

=== begin code ===

var
  VProduct: TProduct;
  ...
  VSomePersonDao: TPersonDao<TPerson>;
begin
  ...
  VSomePersonDao.Save(VProduct);

=== end code ===

The compiler will stop the compilation saying something like "Incompatible specialization type in 'TPersonDao', got 'TProduct', expected 'TPerson'". So one more runtime error will be avoided.

And you can do more:

TSessionDao.Persist<TPeson>(VPerson); // inline specialization

or:

VPersonList := TSessionDao.Load<TPeson>; // inline specialization avoinding
casts

It is only some of many generic possibilities.

Silvio mentioned his company is moving to Node.js. That means Javascript. I

program Javascript myself. Javascript is an unbelievably primitive language, yet is is increasingly popular.

=)

We are using Object Pascal in a desktop ERP written with Delphi 7, and currently we are migrating some our modules to the XE8 (unfortunatelly XE8 is pretty expensive, but ... =/ ). Our ERP has many online features like online registration, SMS/e-mail notifications, reports, charts, and provides several resources for Android/Web via a SSL API written with FCL-Web/Brook, and it is working perfectly, but our productivity is a bit slow for to do new features, because -- and unfortunately -- it is increasingly difficult to find professionals interested in Delphi/Pascal programming. =(

Currently I made a wery fast websocket server[1] using Node.js, and I had some dificult to find an updated WS Pascal client compatible with FPC 3 and XE8, so I found one called Bauglir websocket, after some changes I could compile it in both compilers. But I found some comercial clients, but unfortunatelly it could not compile in FPC because they are using generic classes from the Delphi Generic.Collections. Ironically, there are zillions WS clients written in JS.

To me, that tells me that all these additions to Object Pascal which

everyone claims are 'so essential' are in fact pure nonsense. Eye candy to make it look modern.

Buddy, I don't think so. Pascal is a very nice language, but it could be modernized to be compatible with the current very fast necessity of our customers, allowing us to do core more fast, and this new features (generics, custom attributes etc) could be very helpful. Yes, in mantis there are already many more important issues to be fixed, but we can see some people interested in helping to do these new features, so IMHO I think it would be interesting to hear them a little more. =)

Sure, I can't speak more to avoid being a little off-topic hehe.

[1] - wss://duallsistemas.com.br:8001/ (the public version is just a echo server using the 'echo-protocol' as protocol, you can use a terminal[2] for test it).
[2] -
https://chrome.google.com/webstore/detail/dark-websocket-terminal/dmogdjmcpfaibncngoolgljgocdabhke

Silvio Clécio My public projects - github.com/silvioprog
silvioprog
to silvioprog

On Thu, Jul 16, 2015 at 11:34 PM, silvioprog wrote: [...]

... // a type, for example (mistakes happen, we are human =D )

I meant "a typo, for example". ^^'

Silvio Clécio My public projects - github.com/silvioprog
silvioprog
to Sven Barth: Prefixed modifiers are the /worst/ you can do for Pascal. The generic and specialize…
Sven Barth wrote 91 lines
On 16.07.2015 22:17, Maciej Izak wrote: > 2015-07-16 17:23 GMT+02:00 Sven Barth < > >: > > > Then let me tell you that generic methods will arrive in mode ObjFPC > (and thus its syntax) first, because the Delphi syntax is a PITA to > parse/handle. > > (in fact generic methods are already working in mode ObjFPC in my > local repo, I just want to get the Delphi ones working a little bit > before commiting to trunk) > > > @Sven, @Michael > > I am using generics all the time for many things. > > IMO using "generic/specialize" syntax because it is more simple to > implement in compiler is very strange motivation. Using specialize > keyword maybe is good in pure theory but is non practical (generic > keyword in type declaration is not so bad). > > You can torture me (!!!) but I will not use so many unnecessary words > for simple things. > By using this complicated syntax you will kill all functional/generic > approach. > > Advice "if you like shorter syntax then go to other language" is no > solution for me. I like some modern versions of Pascal like presented in > Oxygen and till Delphi XE2 (! many things after XE2 is pure evil). > > I am working on smart pointers/objects (some evolution/for the purposes > of Generics.Collections). Syntax with generic/specialize is not "smart" > for my branch: > > =============== CODE BEGIN =============== > {$MODE SPARTA} > var > X: strong TDictionary<weak TList<Integer>, string>; > Prefixed modifiers are the /worst/ you can do for Pascal. { sugar syntax for > var > X: SmartObj<TDictionary<WeakObj<TList<Integer>>, string>>; } > =============== CODE END =============== > so probably in ObjFPC, code above will become: > =============== CODE BEGIN =============== > {$MODE OBJFPC} > type > TList_Integer = specialize TList<Integer>; > WeakObj_TList_Integer = specialize WeakObj<TList_Integer>; > TDictionary_WeakObj_TList_Integer_String = specialize > TDictionary<WeakObj_TList_Integer, string>; > SmartObj_TDictionary_WeakObj_TList_Integer_String = specialize > SmartObj<TDictionary_WeakObj_TList_Integer_String>; > var > X: SmartObj_TDictionary_WeakObj_TList_Integer_String; > =============== CODE END =============== > > Another simple example. Maybe not a good example to follow, but it shows > the problems: > The generic and specialize keywords and inline specialization are two completely different topics (plus nested specializations, which are simply not supported yet). While currently mode FPC uses the keywords, but does not allow inline specializations I'm in favor of allowing the latter in mode ObjFPC as well, because with the future addition of generic methods it would simply be strange to not allow it. Also we already allow it for parameters and partially for variable declarations as well, so not allowing it in code is simply inconsistent... In the end your code above will look like this in mode ObjFPC: === code begin === var X: specialize SmartObj<specialize TDictionary<specialize WeakObj<specialize TList<Integer> >, string> >; // the spaces between the "> >" are added, because I don't know yet whether I'll be able to deal with the fact that the scanner always converts ">>" to "shr" (and "<<" to "shl") === code end === Regards, Sven
Hm... and more, the 'i := 1 << 1' isn't a "more Pascal-like" syntax, IMHO.
=)

It compiles in '$mode delphi', but the BCC doesn't allows this sintax, returning an "Expression expected but '<' found". What do you think about doing it (... Integer>>) possible in $mode delphi? =)

Silvio Clécio My public projects - github.com/silvioprog
Graeme Geldenhuys
to silvioprog: On Thu, Jul 16, 2015 at 6:44 PM, Michael Van Canneyt < Buddy, with generics you can do…
silvioprog wrote
TPersonDao = class(TObject) public procedure Save(APerson: TObject); end;

Simply change that to the following:

TPersonDao = class(TObject)
public
  procedure Save(APerson: TPerson);
end;

and you could have compile time validation too. Using TObject as the parameter type is just too generic (excuse the pun). ;-)

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/
Sven Barth
to silvioprog: On Thu, Jul 16, 2015 at 5:40 PM, Sven Barth Hm... and more, the 'i := 1 << 1' isn't a…
"silvioprog" wrote
Hm... and more, the 'i := 1 << 1' isn't a "more Pascal-like" syntax,

IMHO. =)

Definitely. I was surprised when I found out that this works (it had been added sometime in the far past to simplyfy porting of C code) and nowadays it hunts me, because it makes my (FPC programming) life so much more complicated -.-

It compiles in '$mode delphi', but the BCC doesn't allows this sintax,

returning an "Expression expected but '<' found". What do you think about doing it (... Integer>>) possible in $mode delphi? =)

Should be doable, especially since they aren't Delphi compatible anyway. At least it would be simpler to disallow "<<" and ">>" as alternatives for "shl" and "shr" respectively in selected modes than to work around it someway...

Regards,
Sven

Sven Barth
to Graeme Geldenhuys: Simply change that to the following: TPersonDao = class(TObject) public procedure…

Am 17.07.2015 08:06 schrieb "Graeme Geldenhuys" <

Show quoted text 17 lines
: On 2015-07-17 03:34, silvioprog wrote: > TPersonDao = class(TObject) > public > procedure Save(APerson: TObject); > end; Simply change that to the following: TPersonDao = class(TObject) public procedure Save(APerson: TPerson); end; and you could have compile time validation too. Using TObject as the parameter type is just too generic (excuse the pun). ;-)

I agree with Graeme here as I thought the same. But maybe the example was too simplified and didn't show real reasons for the use of generics?

Regards,
Sven

Michael Van Canneyt
to silvioprog: On Thu, Jul 16, 2015 at 6:44 PM, Michael Van Canneyt < Buddy, with generics you can do…
silvioprog wrote
Currently I made a wery fast websocket server[1] using Node.js, and I had some dificult to find an updated WS Pascal client compatible with FPC 3 and XE8, so I found one called Bauglir websocket, after some changes I could compile it in both compilers. But I found some comercial clients, but unfortunatelly it could not compile in FPC because they are using generic classes from the Delphi Generic.Collections. Ironically, there are zillions WS clients written in JS.

This is not ironical; websockets are an interface made specially for the browser. Websockets are useless somewhere else, where everyone uses TCP/IP long before the browser existed. So, since JS is the language for the browser, naturally there will be lots of websocket clients.

And: I repeat, I am not advocating against people using Delphi mode. People that care about Delphi syntax and compatibility should use Delphi mode, period.

Mode objfpc is meant to implement new features in a more pascal like fashion - in the opinion of the FPC devs. If you don't agree: no problem. Use mode delphi.

Show quoted text 7 lines
To me, that tells me that all these additions to Object Pascal which everyone claims are 'so essential' are in fact pure nonsense. Eye candy to make it look modern. Buddy, I don't think so. Pascal is a very nice language, but it could be modernized to be compatible with the current very fast necessity of our customers, allowing us to do core more fast, and this new features (generics, custom attributes etc) could be very helpful. Yes, in mantis there are already many more important issues to be fixed, but we can see some people interested in helping to do these new features, so IMHO I think it would be interesting to hear them a little more. =)

I am not stopping anyone from using generics. I am just not convinced by your arguments. The code you posted - to me - only shows that your design is wrong to begin with. (see the remark by Graeme).

Generics, to me, are just there to circumvent or assuage the strict typing of pascal. This is very un-pascalish. Javascript does not need generics because it has no strict typing to begin with.

JS has no attributes either, in fact, it has none of the features you claim will help you. Yet you will move to Node.js, and so to JS. Why ?
Simple: there is a bigger community, and more ready-to-use code floating on internet. The language itself has absolutely nothing to do with it.

Michael.

Graeme Geldenhuys
to Michael Van Canneyt
Michael Van Canneyt wrote
Simple: there is a bigger community, and more ready-to-use code floating on internet. The language itself has absolutely nothing to do with it.

+1 Well said.

I know this is a huge generalisation (normally not a good thing), but most web (JS) developers I have met, most of their day-to-day JavaScript coding consists of using ready-made frameworks or copying somebody else's code and use it for their own needs. There actual own-written JavaScript coding is very small in the grand scheme of things.

Regards,
- Graeme -

Michael Van Canneyt
to Graeme Geldenhuys
Graeme Geldenhuys wrote 12 lines
On 2015-07-17 07:57, Michael Van Canneyt wrote: > Simple: there is a bigger community, and more ready-to-use code > floating on internet. The language itself has absolutely nothing to > do with it. +1 Well said. I know this is a huge generalisation (normally not a good thing), but most web (JS) developers I have met, most of their day-to-day JavaScript coding consists of using ready-made frameworks or copying somebody else's code and use it for their own needs. There actual own-written JavaScript coding is very small in the grand scheme of things.

And this is why I firmly believe we need more libraries to actually do things, instead of more changes to the language.

Another language feature is not going to automagically supply us with e.g. a websockets library.

Michael.

Graeme Geldenhuys
to Michael Van Canneyt
Michael Van Canneyt wrote
And this is why I firmly believe we need more libraries to actually do things, instead of more changes to the language.

Exactly. And why I love the concept of FCL so much. There are tons of useful stuff in there. I'm not saying all libraries should go in FCL though - that puts to much burden on the FPC devs.

Regarding your 'websockets' example. That is exactly why Indy components are so popular with Delphi (and FPC) developers. All ready-to-use components out of the box. Synapse should really do the same.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/
Nikolay Nikolov
to Sven Barth: I'm merely building on the syntax FPC already supports. Sven
Sven Barth wrote 14 lines
On 16.07.2015 21:04, Marco van de Voort wrote: > In our previous episode, Sven Barth said: >>> sadly - no, only in Delphi mode. btw. this thing keep me away from >>> objfpc. >>> >> >> Then let me tell you that generic methods will arrive in mode ObjFPC >> (and >> thus its syntax) first, because the Delphi syntax is a PITA to >> parse/handle. > > https://xkcd.com/927/ I'm merely building on the syntax FPC already supports.

Btw, just an idea: why not make the generic syntax a {$modeswitch}? This way people will be able to switch on the delphi generics syntax in objfpc mode.

Nikolay

Michael Van Canneyt
to Nikolay Nikolov
Nikolay Nikolov wrote 18 lines
On 07/16/2015 11:29 PM, Sven Barth wrote: > On 16.07.2015 21:04, Marco van de Voort wrote: >> In our previous episode, Sven Barth said: >>>> sadly - no, only in Delphi mode. btw. this thing keep me away from >>>> objfpc. >>>> >>> >>> Then let me tell you that generic methods will arrive in mode ObjFPC (and >>> thus its syntax) first, because the Delphi syntax is a PITA to >>> parse/handle. >> >> https://xkcd.com/927/ > > I'm merely building on the syntax FPC already supports. Btw, just an idea: why not make the generic syntax a {$modeswitch}? This way people will be able to switch on the delphi generics syntax in objfpc mode.

That was my proposal as well.

Michael.

Sven Barth
to Nikolay Nikolov: Btw, just an idea: why not make the generic syntax a {$modeswitch}? This way people will…
"Nikolay Nikolov" wrote 10 lines
On 07/16/2015 11:29 PM, Sven Barth wrote: > > On 16.07.2015 21:04, Marco van de Voort wrote: >> >> In our previous episode, Sven Barth said: >>>> >>>> sadly - no, only in Delphi mode. btw. this thing keep me away from

objfpc.

>>>> >>> >>> Then let me tell you that generic methods will arrive in mode ObjFPC

(and

>>> thus its syntax) first, because the Delphi syntax is a PITA to

parse/handle.

Show quoted text 8 lines
>> >> >> https://xkcd.com/927/ > > > I'm merely building on the syntax FPC already supports. Btw, just an idea: why not make the generic syntax a {$modeswitch}? This

way people will be able to switch on the delphi generics syntax in objfpc mode.

That's on my ToDo list for quite some time already ;)

Regards,
Sven

Marcos Douglas
to Sven Barth
Sven Barth wrote 30 lines
Am 17.07.2015 11:06 schrieb "Nikolay Nikolov" : > > > > On 07/16/2015 11:29 PM, Sven Barth wrote: >> >> On 16.07.2015 21:04, Marco van de Voort wrote: >>> >>> In our previous episode, Sven Barth said: >>>>> >>>>> sadly - no, only in Delphi mode. btw. this thing keep me away from >>>>> objfpc. >>>>> >>>> >>>> Then let me tell you that generic methods will arrive in mode ObjFPC >>>> (and >>>> thus its syntax) first, because the Delphi syntax is a PITA to >>>> parse/handle. >>> >>> >>> https://xkcd.com/927/ >> >> >> I'm merely building on the syntax FPC already supports. > > Btw, just an idea: why not make the generic syntax a {$modeswitch}? This > way people will be able to switch on the delphi generics syntax in objfpc > mode. That's on my ToDo list for quite some time already ;)

Would be great.

Regards,
Marcos Douglas

Jonas Maebe
to Sven Barth: objfpc. (and parse/handle. way people will be able to switch on the delphi generics…
Sven Barth wrote 7 lines
Am 17.07.2015 11:06 schrieb "Nikolay Nikolov" < >: > Btw, just an idea: why not make the generic syntax a {$modeswitch}? > This way people will be able to switch on the delphi generics syntax in > objfpc mode. That's on my ToDo list for quite some time already ;)

I really wouldn't like that. While we already have a lot of modeswitches that allow for a lot of flexibility, at the very basic level every modeswitch is one too many: they make reading code more complex (either because you have to know which modeswitches are active to know what a certain expression means, or because you're simply only familiar with code written with that modeswitch either turned on or off).

modeswitches should only be added because it's simply not possible otherwise without an explosion of syntax modes, or because they're a cross-cutting add-on. But not for syntactic differences...

Jonas

silvioprog
to Sven Barth: Am 17.07.2015 08:06 schrieb "Graeme Geldenhuys" < I agree with Graeme here as I thought…
Sven Barth wrote 25 lines
Am 17.07.2015 08:06 schrieb "Graeme Geldenhuys" < >: > > On 2015-07-17 03:34, silvioprog wrote: > > TPersonDao = class(TObject) > > public > > procedure Save(APerson: TObject); > > end; > > Simply change that to the following: > > TPersonDao = class(TObject) > public > procedure Save(APerson: TPerson); > end; > > and you could have compile time validation too. Using TObject as the > parameter type is just too generic (excuse the pun). ;-) I agree with Graeme here as I thought the same. But maybe the example was too simplified and didn't show real reasons for the use of generics? Regards, Sven

Yes. Could you send a more nice example explaining some useful reasons of generics (freepascal\tests\tbf folder)? I think that it could be very helpful to many programmers. =)

Silvio Clécio My public projects - github.com/silvioprog
silvioprog
to Graeme Geldenhuys: Simply change that to the following: TPersonDao = class(TObject) public procedure…

On Fri, Jul 17, 2015 at 3:06 AM, Graeme Geldenhuys <

Show quoted text 15 lines
wrote: On 2015-07-17 03:34, silvioprog wrote: > TPersonDao = class(TObject) > public > procedure Save(APerson: TObject); > end; Simply change that to the following: TPersonDao = class(TObject) public procedure Save(APerson: TPerson); end;

Yes, it was just a simple and partial demo, but have you seen the following sample in same e-mail that I sent? Using the generics I could do a generic DAO that could be used by any class, avoiding TPersonDAO, TProductDAO, TOtherMyEntityDAO and providing a simple and useful CRUD layer: just specialize it using a model, something like
TSession.Persist/Retrieve/Modify/Purge/Paginate<TMyEntity>.

Generics are very usefeul, the problem is just the way how something it is used in some implementation, e.g, using the FGL AFAIK you cannot know the type of the item from a specializated list class.

and you could have compile time validation too. Using TObject as the

parameter type is just too generic (excuse the pun). ;-)

OK, no problem. =)

BTW I use correct type as parameters, but I believe you understood what I meant. =D

Silvio Clécio My public projects - github.com/silvioprog
Graeme Geldenhuys
to silvioprog
silvioprog wrote
Using the generics I could do a generic DAO that could be used by any class, avoiding TPersonDAO, TProductDAO, TOtherMyEntityDAO and providing a simple and useful CRUD layer: just

I fully appreciate that there could be some uses, but I don't agree it makes the language any better - in the contrary, it makes it much harder to read. Pascal used to pride itself by being an easy to read and understand language [by a human].

As for you DAO example. It comes down to what Michael said - more frameworks need to be created. eg: I use the tiOPF framework for all data persistence and more. I can simply call MyPerson.Save or MyProduct.Save and the framework takes care of everything for me (CRUD, transactions, object ID's etc). I can even switch between database systems, database components or even to a 3-tier system without changing a single line of code in my software. Simply change a compiler define in the Project Settings and recompile my project. All without generics. ;-)

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/
silvioprog
to Graeme Geldenhuys

On Fri, Jul 17, 2015 at 11:24 AM, Graeme Geldenhuys <

Show quoted text 13 lines
wrote: On 2015-07-17 15:08, silvioprog wrote: > Using the generics I could do a generic > DAO that could be used by any class, avoiding TPersonDAO, TProductDAO, > TOtherMyEntityDAO and providing a simple and useful CRUD layer: just I fully appreciate that there could be some uses, but I don't agree it makes the language any better - in the contrary, it makes it much harder to read. Pascal used to pride itself by being an easy to read and understand language [by a human].

I agree with Michael too, but a nice thing to allow other programmers to make new libraries could be adding new features in the language, making it more productive. I'm working in a new lib and I'm having several problems to keep compatibility betten FPC and Delphi, so I'm using a lot of IFDEFs, even using mode delphi.

As for you DAO example. It comes down to what Michael said - more

Show quoted text 7 lines
frameworks need to be created. eg: I use the tiOPF framework for all data persistence and more. I can simply call MyPerson.Save or MyProduct.Save and the framework takes care of everything for me (CRUD, transactions, object ID's etc). I can even switch between database systems, database components or even to a 3-tier system without changing a single line of code in my software. Simply change a compiler define in the Project Settings and recompile my project. All without generics. ;-)

Me too, in any universe (Delphi/ObjFPC, Java, JS, PHP, TypeScript, C# ...) that I'm working currenctly. =)

Silvio Clécio My public projects - github.com/silvioprog
Michael Van Canneyt
to silvioprog
silvioprog wrote 18 lines
On Fri, Jul 17, 2015 at 11:24 AM, Graeme Geldenhuys < > wrote: > On 2015-07-17 15:08, silvioprog wrote: >> Using the generics I could do a generic >> DAO that could be used by any class, avoiding TPersonDAO, TProductDAO, >> TOtherMyEntityDAO and providing a simple and useful CRUD layer: just > > > I fully appreciate that there could be some uses, but I don't agree it > makes the language any better - in the contrary, it makes it much harder > to read. Pascal used to pride itself by being an easy to read and > understand language [by a human]. > I agree with Michael too, but a nice thing to allow other programmers to make new libraries could be adding new features in the language, making it more productive.

Where is the proof that these new features make you more productive ?

I created a code generator that creates boilerplate classes and associated unit test cases. All with in essence D7 style code, ready to go.
I don't think that generics would do anything to improve the situation. I could gain a few lines because I could use a generic list&enumerator, but that's it.

I'm working in a new lib and I'm having several problems to keep compatibility betten FPC and Delphi, so I'm using a lot of IFDEFs, even using mode delphi.

To improve this situation I advocate NOT yet to spend effort on new language modes, but first get the Delphi compatibility to a decent level. I think that this will do more to help productivity than new modes.

After that, we can still see about new modes. I'm not arguing about that.

Michael.

Sven Barth
to Michael Van Canneyt
Michael Van Canneyt wrote 10 lines
> I'm working in a new lib and I'm having several problems > to keep compatibility betten FPC and Delphi, so I'm using a lot of > IFDEFs, > even using mode delphi. To improve this situation I advocate NOT yet to spend effort on new language modes, but first get the Delphi compatibility to a decent level. I think that this will do more to help productivity than new modes. After that, we can still see about new modes. I'm not arguing about that.

I agree with that. We still have quite some things to do there.

Regards,
Sven

Florian Klämpfl
to Sven Barth: Prefixed modifiers are the /worst/ you can do for Pascal. The generic and specialize…
Sven Barth wrote 10 lines
In the end your code above will look like this in mode ObjFPC: === code begin === var X: specialize SmartObj<specialize TDictionary<specialize WeakObj<specialize TList<Integer> >, string> >; // the spaces between the "> >" are added, because I don't know yet whether I'll be able to deal with the fact that the scanner always converts ">>" to "shr" (and "<<" to "shl")

Lucky you that pascal does not allow inline type declarations like:

var
X: specialize SmartObj<specialize TDictionary<specialize WeakObj<specialize TList<-32768..$10000>>
2> >,string> >;
Sven Barth
to Florian Klämpfl
"Florian Klämpfl" wrote 9 lines
Am 16.07.2015 um 22:40 schrieb Sven Barth: > > In the end your code above will look like this in mode ObjFPC: > > === code begin === > > var > X: specialize SmartObj<specialize TDictionary<specialize

WeakObj<specialize TList<Integer> >,

> string> >; > // the spaces between the "> >" are added, because I don't know yet

whether I'll be able to deal

> with the fact that the scanner always converts ">>" to "shr" (and "<<"

to "shl")

Show quoted text 5 lines
Lucky you that pascal does not allow inline type declarations like: var X: specialize SmartObj<specialize TDictionary<specialize

WeakObj<specialize TList<-32768..$10000>>

2> >,string> >;

*shudders* That is a good reason for me not to implement const parameters for generics...

Regards,
Sven

silvioprog
to Michael Van Canneyt: Where is the proof that these new features make you more productive ? I created a code…
Michael Van Canneyt wrote 22 lines
On Fri, 17 Jul 2015, silvioprog wrote: > > On Fri, Jul 17, 2015 at 11:24 AM, Graeme Geldenhuys < > > wrote: > >> On 2015-07-17 15:08, silvioprog wrote: >>> >>> Using the generics I could do a generic >>> DAO that could be used by any class, avoiding TPersonDAO, TProductDAO, >>> TOtherMyEntityDAO and providing a simple and useful CRUD layer: just >> >> >> >> I fully appreciate that there could be some uses, but I don't agree it >> makes the language any better - in the contrary, it makes it much harder >> to read. Pascal used to pride itself by being an easy to read and >> understand language [by a human]. >> > > I agree with Michael too, but a nice thing to allow other programmers to > make new libraries could be adding new features in the language, making

it

> more productive. Where is the proof that these new features make you more productive ?

Buddy, just 'googling' about 'new delphi rtti', 'delphi generics' or 'new delphi custom attributes' you can see many new Delphi XE frameworks available to download, and a lot of them use this new features and are very productive. But OK, I'm not going to insist about it anymore. ;)

I created a code generator that creates boilerplate classes and

associated unit test cases.

All with in essence D7 style code, ready to go. I don't think that generics would do anything to improve the situation. I could gain a few lines because I could use a generic list&enumerator,

but that's it.

Nice job, I need to test it ASAP.

But, making FPC more compatible to XE, we could use more third party components, like Hprose[1]/EntityDAC[2]/TMS Aurelius[3]/DSWScript[4] etc.

> I'm working in a new lib and I'm having several problems > to keep compatibility betten FPC and Delphi, so I'm using a lot of

IFDEFs,

Show quoted text 10 lines
> even using mode delphi. To improve this situation I advocate NOT yet to spend effort on new language modes, but first get the Delphi compatibility to a decent level. I think that this will do more to help productivity than new modes. After that, we can still see about new modes. I'm not arguing about that. Michael.

Are you talking about compatibility to Delphi 5/7?

There are already many new great components available on network, however it uses some basic new Delphi features like I said above, but unfortunatelly FPC doesn't compile them.

In short, it isn't a problem to me and I'm glad to use ObjFPC even with some limitations, but I would be very greatful if the ObjFPC could be improved using at least generics, new RTTI and custom attributes. I know it would be a hard work to be able in FPC, but I can see a bit resistance from the FPC core to accept this new features (or nonsense, as they use to say =D ).

[1] https://github.com/hprose/hprose-delphi
[2] https://www.devart.com/entitydac/
[3] https://www.tmssoftware.com/site/aurelius.asp
[4] https://bitbucket.org/egrange/dwscript

Silvio Clécio My public projects - github.com/silvioprog
Michael Van Canneyt
to silvioprog
silvioprog wrote 10 lines
> > After that, we can still see about new modes. I'm not arguing about that. > > Michael. Are you talking about compatibility to Delphi 5/7? There are already many new great components available on network, however it uses some basic new Delphi features like I said above, but unfortunatelly FPC doesn't compile them.

I am not against improving Delphi compatibility, I have never said that.

But for me, people should use the correct arguments:
- improved productivity is not one of them. I see no proof of this. I do see a lot of marketing.
- The word "Modern" is very subjective.

In short, it isn't a problem to me and I'm glad to use ObjFPC even with some limitations, but I would be very greatful if the ObjFPC could be improved using at least generics, new RTTI and custom attributes.

Attributes and RTTI will come as soon as 3.0 are out of the door.

In the meanwhile, why don't you just use mode Delphi and enjoy the benefits of that mode ?

I know it would be a hard work to be able in FPC, but I can see a bit resistance from the FPC core to accept this new features (or nonsense, as they use to say =D ).

I didn't say features are nonsense. I said arguments are nonsense.

hprose works in lazarus if I understand the sources correctly.

From the entitydac site:

"I originally purchased TMS Aurelius (ORM). I could not get it off the ground after three days."

So be careful what you pick as examples ;)

Additionally:
If you had used tiOPF 10 years ago, you could have done exactly the same as what these products (entitydac and aurelius) do, at NO cost, and without generics. I can say this with confidence, because I already did that, and still do today.

But once more, it's just about arguments. Not about stopping people.

Michael.

silvioprog
to Michael Van Canneyt

On Fri, Jul 24, 2015 at 4:10 AM, Michael Van Canneyt <

Show quoted text 30 lines
wrote: On Fri, 24 Jul 2015, silvioprog wrote: > > After that, we can still see about new modes. I'm not arguing about that. >> >> Michael. >> > > Are you talking about compatibility to Delphi 5/7? > > There are already many new great components available on network, however > it uses some basic new Delphi features like I said above, but > unfortunatelly FPC doesn't compile them. > I am not against improving Delphi compatibility, I have never said that. But for me, people should use the correct arguments: - improved productivity is not one of them. I see no proof of this. I do see a lot of marketing. - The word "Modern" is very subjective. In short, it isn't a problem to me and I'm glad to use ObjFPC even with > some limitations, but I would be very greatful if the ObjFPC could be > improved using at least generics, new RTTI and custom attributes. > Attributes and RTTI will come as soon as 3.0 are out of the door.

Wow, this is a great new! =)

In the meanwhile, why don't you just use mode Delphi and enjoy the benefits of that mode ?

I'm using mode delphi in some units, however just for retro compatibility.

I know it would be a hard work to be able in FPC, but I can see a bit

Show quoted text 14 lines
> resistance from > the FPC core to accept this new features (or nonsense, as they use to say > =D ). > I didn't say features are nonsense. I said arguments are nonsense. [1] https://github.com/hprose/hprose-delphi > [2] https://www.devart.com/entitydac/ > [3] https://www.tmssoftware.com/site/aurelius.asp > hprose works in lazarus if I understand the sources correctly.

It works, but skipping many features using something like {IFNDEF FPC}'many features'{ELSE}'nothing'.

Show quoted text 6 lines
From the entitydac site: "I originally purchased TMS Aurelius (ORM). I could not get it off the ground after three days." So be careful what you pick as examples ;)

At the same page:

"This is "THE ORM FOR DELPHI". Easy to use and powerful. With this tool I have simplified the DB managing in my Delphi application and I can create true cross-db application using EntityDAC and UNIDAC, two great products."

Show quoted text 9 lines
Additionally: If you had used tiOPF 10 years ago, you could have done exactly the same as what these products (entitydac and aurelius) do, at NO cost, and without generics. I can say this with confidence, because I already did that, and still do today. But once more, it's just about arguments. Not about stopping people. Michael.

Yes, I took a look at tiOPF some years ago, it is a nice framework, but it doesn't imply me not to meet new frameworks. =)

Although, this is just my opinion, because I think that this details/features could help the FPC users to use more third party components.

Silvio Clécio
Joao Morais
to Michael Van Canneyt: I am not against improving Delphi compatibility, I have never said that. But for me,…
Michael Van Canneyt wrote
Attributes and RTTI will come as soon as 3.0 are out of the door.

Hello Michael, merging to trunk I presume. Provided that attributes and new rtti are two of the best things since the discover of the fire and the wheel, is there some branch I could see it myself? Another paper beyond http://wiki.freepascal.org/Property_attributes ?

Michael Van Canneyt
to Joao Morais
Joao Morais wrote 8 lines
On 24/07/15 04:10, Michael Van Canneyt wrote: > > Attributes and RTTI will come as soon as 3.0 are out of the door. Hello Michael, merging to trunk I presume. Provided that attributes and new rtti are two of the best things since the discover of the fire and the wheel, is there some branch I could see it myself? Another paper beyond http://wiki.freepascal.org/Property_attributes ?

Attributes:

http://svn.freepascal.org/svn/fpc/branches/joost/classattributes/

New RTTI (I think):
http://svn.freepascal.org/svn/fpc/branches/interfacertti/

Michael.

Maciej Izak
to Michael Van Canneyt

2015-07-31 8:37 GMT+02:00 Michael Van Canneyt :

Show quoted text 5 lines

Looks like "dead branch"...

IIRC this is bugfix for mORMot framework related to broken/lack of implementation of RTTI for interfaces. In Delphi this kind of RTTI is available since Delphi 7 or 6 (I don't remember precisely).

Best regards, Maciej Izak
Michael Van Canneyt
to Maciej Izak
Maciej Izak wrote 8 lines
2015-07-31 8:37 GMT+02:00 Michael Van Canneyt : > Attributes: > > http://svn.freepascal.org/svn/fpc/branches/joost/classattributes/ > > Looks like "dead branch"...

No, it is not.

It looks dead because the support is long finished, but it has not been integrated in trunk because the integration in trunk can only happen after the release of 3.0. So it has been waiting for a long time.

Show quoted text 7 lines
> New RTTI (I think): > http://svn.freepascal.org/svn/fpc/branches/interfacertti/ IIRC this is bugfix for mORMot framework related to broken/lack of implementation of RTTI for interfaces. In Delphi this kind of RTTI is available since Delphi 7 or 6 (I don't remember precisely).

As I hinted: I am not sure where this support is committed. Florian can tell us, I believe he created a branch for this.

Michael.