[fpc-pascal] generics class hierarchy

Honza befelemepeseveze at gmail.com
Sun Dec 19 13:03:19 CET 2010


2010/12/19 Sven Barth <pascaldragon at googlemail.com>:
>> "There is a single placeholder _T. It will be substituted by a type
>> identifier when the generic class is specialized. The identifier _T
>> *may not be used for anything else than a placehoder*. "
>>
>
> According to the documentation I'd say that it should succeed, because in
> "class(BaseClass)" "BaseClass" is a type identifier. But of course that has
> its own set of problems... see the second last paragraph of this mail.
The type parameter in the inheritance part clause, i.e. class(T) part
of the generic class declaration has nothing to do with the
placeholder formal parameter. The placeholder formal arg list are
given inside the sharp brackets <> as a kind of macro parameters. And
the docs explicitly states that a placeholder identifier may not be
used elsewhere in the generic declaration except for identifying the
place where the "macro" expansion should substitute the
instantiation/specialization parameter. So using it in the inheritance
clause is invalid. IMO the docs are clear on this and my experiments
seems to confirm this behaviour. I have excersised generics a lot to
get heLib compiled and working. Still the latest changes in the
compiler broke the published code as I realized very recently and not
yet uploaded the remedy which sits on my local disk.

>> The bold part is IMO violated by the declaration. Anyway, it could be
>> perhaps (not tested) written as:
>>
>> type
>>   TBoxProxy = class(_t_point);
>>   generic gt_box<_t_point, _num>  = class(TBoxProxy)
>>     f_width, f_height : _num;
>>   end;
>>
>
> No, this won't work, because "_t_point" won't be defined when "TBoxProxy" is
> parsed.

Yes it's not defined and that was my 3rd note, you can't base a
generic declaration on a not yet specialized ancestor.


>> Another strange point is, that the declaration of gt_box doesn't use
>> the formal specialization paramater `_t_point` at all (in the posted
>> code), so the same the other way around should also work:

> It IS used, because David wants to influence the class the generic class
> gt_box inherits from when specializing the class.

It is not used *anywhere except* in the invalid place of the ancestor type.

> type
>  TIntPoint = class
>    x, y: Integer;
>  end;
>
>  TFloatPoint = class
>    x, y: Single;
>  end;
>
>  generic gt_box<_t_point, _num> = class(_t_point)
>    width, height: _num;
>  end;
>
>  TFloatBox = specialize gt_box<TFloatPoint, Single>;
>  TIntBox = specialize gt_box<TIntPoint, Integer>;
>
>> type
>>   generic gt_box<_num>  = class<_t_point>
>>     f_width, f_height : _num;
>>   end;
>>
>
> This won't compile because of the "<...>" around "_t_point". Also it's not
> what Daniel intends.

Yes, that's just a typo, round parenthesis are what I've meant and
should wrote there.

>> A 3rd note is that your code can't compile as _t_point is not declared
>> when gt_box is declared, but the declaration wants to inherit from
>> _t_point, so IMO also for this the code is rightfully rejected the
>> compiler.
>
> The question is whether this should be rejected if "_t_point" is a template
> parameter... on the other hand this would violate compile time checks of the
> generic class...
>
> I'm still thinking how David's idea could be achieved in another way which
> is supported by the compiler...

I've not yet got time to look at his goal at all, so I don't know. I
just spotted the invalid constructs presented.

-- 
bflm
freepascal-bits.blogspot.com



More information about the fpc-pascal mailing list