PDA

View Full Version : Difference between FPC Generics and Delphi Generics?



chronozphere
04-01-2011, 10:01 AM
Hi,

I would like to use generics, yet keep my code compatible with both Delphi and FPC?

Would that be possible? If so, how to d it?

Thanks :)

Murmandamus
04-01-2011, 06:20 PM
I don't think the implementations differ significantly. At least, I am unable to find any documentation of discrepancies. Generics are pretty straightforward to implement in Object Pascal.

If anything, I would say that the FPC generics are, at worst, a subset of Delphi generics, so anything you do with the FPC ones should port to Delphi without further modification.

chronozphere
04-01-2011, 06:34 PM
I think you're wrong. I've been looking into it a bit more and I noticed that FPC uses "generic" and "specialize" keywords, while delphi does not. It makes me think that these two flavours are syntactically quite different.

Has anyone worked with both of them?

JSoftware
04-01-2011, 08:45 PM
FPC generics are much stricter than Delphi's implementation. I wouldn't bother with making them compatible. To make them compatible you would need to specialize every generic class



type
{$ifdef FPC}
generic TGenericType<T> = class
{$else}
TGenericType<T> = class
{$endif}
function Test(AArg: T): T;
end;

TSomeGeneric = {$ifdef FPC}specialize {$endif}TGenericType<longint>;

implementation

function TGenericType.Test(AArg: T): T;
begin
result := T*2;
end;

Murmandamus
04-01-2011, 09:52 PM
Ahh, yeah, looks like the syntax is slightly different because of the reserved words. However, the actual functionality does appear to be a subset.

I haven't used Delphi generics (since I don't have a later copy of Delphi with them), but from what I have discovered in terms of differences so far:

1) Generics in FPC are defined using the "generic" keyword preceding the name of the generic in the declaration, and are "specialized" using the "specialize" keyword. In Delphi, the keywords are not used, but the rest of the syntax appears to be the same (analyzed using several comparative examples in both). This appears to be a decision made by the FPC developers due to a potential conflict with other syntactical elements which use the angle bracket syntax "<>".
2) Generics in Delphi may be specialized in VAR and TYPE declarations. In FPC, they may only be specialized in TYPE declarations. (caveat: it appears you can specialize in a VAR declaration, but there's no way to instantiate the resulting variable, because the constructor expression doesn't understand the "specialized" keyword, or the use of the angle bracket notation).
3) Generics in FPC may not be specialized in local scope; in Delphi, Generics can be specialized in local scope (ie, in a procedure/function/method's local type declaration).

That's what I have found so far; there could be some more caveats to those items, as well as more items; it's not meant to be an exhaustive list, just something to get you started, since the documentation is damn sparse on the subject.

chronozphere
04-01-2011, 10:17 PM
Wow.. thanks. Both of you. :)



I wouldn't bother with making them compatible.


Hmmm.. yes, I was thinking about that. It would be great to have delphi-style generics in FPC (even if it were only in DELPHI mode). It would definitely be a cool feature. But I now understand that it would make no sense to change the FPC implementation to match delphi's. Besides, FPC was WAY earlier with generics support. :)

Nice trick to use conditional defines. I will probably use that. :) I'll probably do it this way:



type
{$ifdef FPC}generic{$endif} TGenericType<T> = class
function Test(AArg: T): T;
end;

TSomeGeneric = {$ifdef FPC}specialize{$endif} TGenericType<longint>;

implementation

function TGenericType.Test(AArg: T): T;
begin
result := T*2;
end;


Just saves a couple of lines. ;)

Thanks Murmandamus, for the whole list of differences. Delphi's generics seem a bit more powerfull to me, but I'm not sure how often I will use the extra functionality you mentioned. I think FPC's implementation will do just fine. :)

JSoftware
04-01-2011, 11:11 PM
Generics are overrated anyway :P

You might save a slight bit of time, but I think it'll only end in tears

Murmandamus
04-01-2011, 11:51 PM
Well, they solve some rather sticky problems at the design paradigm level. For example, ages ago, back before classes, I had a number of different internal linked list methods that I created with Objects (think TP 5.5-5.0). If I wanted singly-linked, doubly-linked, circularly-linked, etc options, I had a different object for each combination of options (well, some of them were actually options in the list). When we got classes, it made it easier to manipulate them syntactically, but I still had a number of classes that I had to support so that I could maintain distinctive functionality. Generics solves the last of the problems I had, so I can actually use just one generic TLinkedList class now, but the fact that it is little more than a glorified high-level macro-like extension still doesn't feel like the optimal solution. I think there is still yet more enhancement and integration to be had in the concept, and it will finally be the sweetest syntactic sugar to solve those sticky kinds of problems.

It is definitely nice for some things, but you're right; it's not useful or appropriate to use for many things, even though programmers sometimes go overboard trying to do so. :)

VilleK
05-01-2011, 09:20 AM
In Delphi 2009 and above the new Generics.Collections unit is highly useful.

You can declare containers like this:

X : TObjectList<TMyClass>;

It will hold and own the items.

Then iterate like this:

Item : TMyClass;
...
for Item in X do
...

I like this style of generic containers as it saves time typing and removes the need of casting. There is also a hashtable called TDictionary<K,V>.
But I agree that more advanced use of generics can indeed lead to trouble ;)

chronozphere
05-01-2011, 09:49 AM
I will probably only use them for list-like datastructures. It's really handy if you don't have to copy the same code for integers, floats, 2d, 3d and 4d vectors. :)

Btw, is it possible to use Type Parameter bounds, like java has? It means that you can enforce that your type-parameter T must be a derivative of a specific class, like this:



public class SomeGenericClass <T extends OtherClass> {
//....
}

Brainer
05-01-2011, 12:46 PM
Btw, is it possible to use Type Parameter bounds, like java has? It means that you can enforce that your type-parameter T must be a derivative of a specific class, like this:

A text worth mentioning: http://sjrd.ftp-developpez.com/tutoriels/delphi-generics/delphi-generics.pdf.

Answering your question: yes, it is. :) As you will see in the article, there is few methods to do so. A little extract from the article, which I put below, provides you with an answer:


type
TStreamGenericType<T: TStream> = class
end;

chronozphere
05-01-2011, 01:49 PM
Ah thanks. I'll read that! :)

And how about FPC? Does it have this feature too?

JSoftware
05-01-2011, 05:34 PM
Looks like Paul Ishenin is updating Delphi mode generics in FPC heavily those days, so it might be safe to just use the Delphi generics style for now

chronozphere
06-01-2011, 09:17 AM
Thanks for the heads up mate! That makes my life a whole lot easier. :)

wagenheimer
13-01-2011, 09:08 PM
I'm having some trouble converting my Delphi generics to FPC.

FManaButtons: {$ifdef FPC}specialize{$endif} TObjectList<TManaButton>;

Error: Specialization is only supported for generic types

This not works in FPC?

wagenheimer
13-01-2011, 09:24 PM
Records Types with Procedures also does not works? =(

JSoftware
13-01-2011, 09:26 PM
I'm having some trouble converting my Delphi generics to FPC.

FManaButtons: {$ifdef FPC}specialize{$endif} TObjectList<TManaButton>;

Error: Specialization is only supported for generic types

This not works in FPC?
The TObjectList in fpc isn't generic

JSoftware
13-01-2011, 09:29 PM
Records Types with Procedures also does not works? =(
Upgrade to FPC in trunk and use Delphi mode. It's partially supported there. It just got implemented less than a month ago, and I'm not sure it's stable, but I haven't had any problems with it during my quick tests

The same goes for Delphi style generics. The current trunk version in delphi mode can do inline specialization just like delphi. But again, this is very, very new stuff

chronozphere
14-01-2011, 01:15 PM
The same goes for Delphi style generics. The current trunk version in delphi mode can do inline specialization just like delphi. But again, this is very, very new stuff


Awesome Awesome!! :) Hope these new features will become "stable" soon.

chronozphere
03-02-2011, 12:16 PM
Ok, seems like they implemented it:

http://wiki.lazarus.freepascal.org/FPC_New_Features_Trunk

I'd like to test it, but I don't know what to download. Is this only available through the development trunk? Are there any automatic builds (FPC + Laz) containing these changes?

Thanks :)

Edit: I have downloaded and installed the latest version, which I found at this page:
http://www.hu.freepascal.org/lazarus/
But it doesn't work yet. ??? Do these packages also contain the latest FPC builds?

Murmandamus
04-02-2011, 07:49 AM
I don't think there are any snapshots of Lazarus builds with the FPC development trunk, which is 2.5.x.

Yet, anyway.

You can download a development snapshot build of FPC, of course, but you'll have to compile from command line.

http://www.freepascal.org/develop.var