[fpc-devel] Packages, Generics

Willibald Krenn Willibald.Krenn at gmx.at
Sun Sep 12 03:59:17 CEST 2010


Hi!

Today I was thinking about fpc packages (whenever I am using this word, 
I mean Delphi-style-DLL-packages) and what difficulties might arise when 
implementing them. In my opinion, doing packages for D6-like Pascal 
should not be conceptually hard. It'll be more of a technical challenge 
to fiddle with the compiler internals.

However, since FPC supports more then the "simple" D6 language, I had a 
look at generics in particular. First, let me say that I am really glad 
to see this feature in FPC. However, I have to say that generics are NOT 
equivalent to C++ templates and should not be. (I strongly dislike the 
specialize keyword, btw., even though it makes the process of 
'instantiating' the 'template' more apparent.) So, generics are _not_ 
pre-processor style macros - generic types are proper types. Let me explain.

Normally, a generic type can be statically checked by the compiler on 
it's own. You do not need to specialize it. The reason is simple: for 
most of the time, you could think of a generic type parameter as a 
variable with the type 'class of X' (which Pascal already supports). 
With the content of this variable you can do everything that is 
described in the public interface of its type. Nothing more, nothing 
less. For generic classes, this means that the compiler is able to check 
the correctness of the use of a value with a generic type without the 
need for specialization. Here is a catch: Pascal has quite a lot of 
types that are not classes. And this makes things a bit uncomfortable.

I would say that it is (almost) impossible to do packages in a sane way 
if we allow all sorts of operations on 'generically typed' values: If 
someone defines such a generic class, the compiler will need to 
pre-generate all possible type specializations of that class for the 
package file. Thereby 'all possible instantiations' means one for each 
non-oo type and at least one for all the object types (and possible 
combinations). Still worse, this would even break the 
'one-implementation for all classes thing', because different classes 
could provide a method with the same name... (which would end up at 
different places in memory).

I don't know how Delphi solves these issues (w. regards to packages) but 
I think the one way to deal with this is to restrict the operations that 
can be done with values of generic types so that these operations match 
the type-information of the generic type parameters (e.g., generic A = 
class <T1 :Ordinal...> ...).

As said, all the class/interface types are no problem - they probably 
just need one specialization. Primitive types are basically grouped in 
Ordinals, Reals, Characters, Structures, Pointers, Functions. Each group 
comes with a set of operations that is valid and quite a lot of them end 
up being passed around as pointers. Refcounting aside, a common
operation allowed on all types would be the assignment. This is enough 
for simple generic containers. Hence, if no other operation is needed, 
one common specialization could do. (Refcounting issue would still need 
to be solved, though.) If the developer needs more advanced operations, 
he/she has to narrow down the type that is allowed for specialization: 
Oridnal, or Real, or some TMyClass... . You get the basic idea. The more 
one restricts the generic parameter, the more one is allowed to do with 
values of that type.  Which is the big difference to C++ templates, and 
the way generics should work.

So I am of the opinion that 'real' generics would make packages 
possible: Yes, generated code might be less efficient (int64 
implementation for all signed ordinals), or there might be code 
duplication (for each ordinal type one implementation), but things would 
work. With the current implementation of generics packages are a no-go, 
I am afraid.


Cheers,
  Willi





More information about the fpc-devel mailing list