...answering from the future.
FreePascal has support for generic functions and procedures outside of classes.
Here's code that shows how you could implement Thrice as a special case of Times to also illustrate your ask about "FourTimes, FiveTimes, etc.".
The code includes a couple of examples using different types (integer, string, record):
{$mode objfpc}
program Thrice;
uses sysutils;
type
TPerson = record
First: String;
Age: Integer;
end;
generic TArray<T> = array of T;
var
aNumber: integer;
aWord: String;
thePerson: TPerson;
aPerson: TPerson;
generic function TimesFn<T, RT>(thing: T; times: Integer): RT;
var i: integer;
begin
setLength(Result, times);
for i:= 0 to times-1 do
Result[i] := thing;
end;
generic function ThriceFn<T, RT>(thing: T): RT;
begin
Result := specialize TimesFn<T, RT>(thing, 3);
end;
begin
{ Thrice examples }
for aNumber in specialize ThriceFn<Integer, specialize TArray<Integer>>(45) do
writeln(aNumber);
for aWord in specialize ThriceFn<String, specialize TArray<String>>('a word') do
writeln(aWord);
thePerson.First := 'Adam';
thePerson.Age := 23;
for aPerson in specialize ThriceFn<TPerson, specialize TArray<TPerson>>(thePerson) do
writeln(format('First: %s; Age: %d', [aPerson.First, aPerson.Age]));
{ Times example }
for aNumber in specialize TimesFn<Integer, specialize TArray<Integer>>(24, 10) do
writeln(aNumber);
end.