[fpc-pascal] Constants in generics

Ryan Joseph ryan at thealchemistguild.com
Wed Nov 7 02:59:26 CET 2018



> On Nov 6, 2018, at 11:19 PM, Sven Barth via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
> 
> Complex inline specializations containing, for example a multiplication with specializations on the left and the right side are currently not possible in mode Delphi. In addition to that Delphi allows overloads of generic types with variables and constants, so when the parser encounters "Bla<N" and has not yet encountered the ">" it does not know whether it needs to start a specialization or an expression. This is already annoying enough to solve with merely types, but if the right side of the "<" can also take constants for generics that gets downright proplematic. 

Can you show full a code example? If it really is so problematic because of something Delphi does then maybe it’s best left to objfpc mode until it can be resolved.

> Specialization is an expensive operation. When the compiler can already decide that "Something<SomeType, SomeOtherType>" can never be valid, because it's declared as "Something<T, const N>", then this is preferable. Otherwise the user might get some cryptic error message during the specialization, because "SomeOtherType" is used where only a constant can be used. 
> Pascal is considered a type safe language and without forcing users to decorate such parameters as "const" you essentially allow users to mix types and constants. 
> Not to mention that parsing the generic can already be done more correctly then it could be if the parameter is a typesym (which it would be right now). 
> You can't do e.g. "const SomeOtherConst = ConstParam * Pi" that way as it would mean to ease up the compiler's restrictions for type checking even more. 

I guess if you include const it could save some compile time if you tried to specialize with the wrong type? It’s a pretty minor savings but that’s ok.

type
	generic TList<T,const U> = record
		list: array[0..U-1] of T;
		function capacity: integer;
	end;

Btw I only implemented this with integers (no strings or floats) because afaik this feature is only useful for arrays. I guess you could use non-ints for default parameters but this is probably a stupid idea because of how much compile time you’ll add to specialize a large amount of types.

Is there any reason to support strings and floats?

type
	generic TCaller<T,const U> = record
		procedure Say(message:T = U);
	end;

var
	caller: specialize TCaller<string,’hello’>;
begin
	caller.Say;

Regards,
	Ryan Joseph




More information about the fpc-pascal mailing list