Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-10

How can I implement "thrice" in Free Pascal?

38 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Andrew Pennebaker

Haskell lets you define functions like thrice, which accepts an element of type a and returns a list of the element repeated three times, for any data type a.

thrice :: a -> [a]
thrice x = [x, x, x]

I know the answer involves generics, but the docs don't offer examples using Free Pascal's built-in generic types.

Cheers,

Andrew Pennebaker
www.yellosoft.us

Marco van de Voort
to Andrew Pennebaker

In our previous episode, Andrew Pennebaker said:

Show quoted text 5 lines
thrice :: a -> [a] thrice x = [x, x, x] I know the answer involves generics, but the docs don't offer examples using Free Pascal's built-in generic types.

There is no built in list type, generic or not, and no way to define new operators. All list and collection types are library. I see no way this could work.

Andrew Pennebaker
to Marco van de Voort

Can this be done with arrays? I didn't mean to be too specific; I'd be happy with any generic collection that could do this.

Cheers,

Andrew Pennebaker
www.yellosoft.us

Marco van de Voort wrote 16 lines
In our previous episode, Andrew Pennebaker said: > thrice :: a -> [a] > thrice x = [x, x, x] > > I know the answer involves generics, but the docs don't offer examples using > Free Pascal's built-in generic types. There is no built in list type, generic or not, and no way to define new operators. All list and collection types are library. I see no way this could work. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Vladimir Zhirov
to Andrew Pennebaker
Andrew Pennebaker wrote
thrice :: a -> [a] thrice x = [x, x, x] I know the answer involves generics, but the docs don't offer examples using Free Pascal's built-in generic types.

The solution would require generic functions, these are implemented in FPC trunk only. In the latest release (2.4.4) the result you want can be achieved with overloading and some copy-paste (that can be avoided using include files). See attached code for an example.

However note that it does not work properly for class instances. Since they are basically pointers the output would be three pointers to the same class instance. AFAIK there is no way in FPC (and Delphi) to deep-copy arbitrary class instance because TObject does not force us to define copy constructors.

--------------------------------------------------------
program project1;
uses
  Classes;
{$mode delphi}
type
  TIntegerArray = array of Integer;
  TStringArray = array of String;
function Thrice(AValue: Integer): TIntegerArray; overload;
var
  I: Integer;
begin
  SetLength(Result, 3);
  for I := 0 to 2 do
    Result[I] := AValue;
end;
function Thrice(const AValue: String): TStringArray; overload;
var
  I: Integer;
begin
  SetLength(Result, 3);
  for I := 0 to 2 do
    Result[I] := AValue;
end;
var
  I: Integer;
  Thrice5: TIntegerArray;
  ThriceHello: TStringArray;
  ThriceWorld: TStringList;
begin
  Thrice5 := Thrice(5);
  for I := 0 to High(Thrice5) do
    Write(Thrice5[I], ' ');
  WriteLn();
  ThriceHello := Thrice('hello');
  for I := 0 to High(ThriceHello) do
    Write(ThriceHello[I], ' ');
end.
Sven Barth
to Vladimir Zhirov
Vladimir Zhirov wrote
The solution would require generic functions, these are implemented in FPC trunk only.

Generic functions are NOT implemented in trunk (at least as far as I know...).

Regards,
Sven

Vladimir Zhirov
to Sven Barth
Sven Barth wrote
Generic functions are NOT implemented in trunk (at least as far as I know...).

Ouch, sorry. I read about "generic procedural types" at "New features trunk" wiki page and thought it was what OP need. Andrew, I apologize for misinformation and thanks Sven for correcting me.

Andrew Pennebaker
to Vladimir Zhirov

Thrice is designed to work for *any* array type, e.g. arrays of arrays of arrays of bytes. Even if I hardcoded several thousand possible types, Thrice wouldn't work for custom user types.

If you do find a way to make this work, please let me know.

Cheers,

Andrew Pennebaker
www.yellosoft.us

Vladimir Zhirov wrote 12 lines
Sven Barth wrote: > Generic functions are NOT implemented in trunk (at least as > far as I know...). Ouch, sorry. I read about "generic procedural types" at "New features trunk" wiki page and thought it was what OP need. Andrew, I apologize for misinformation and thanks Sven for correcting me. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Andrew Pennebaker
to Andrew Pennebaker
In particular, if anyone knows a way to implement a general concatenation
function Concat(Arr1, Arr2), let me know.

Cheers,

Andrew Pennebaker
www.yellosoft.us

On Tue, Oct 18, 2011 at 1:59 PM, Andrew Pennebaker <

Show quoted text 29 lines
wrote: Thrice is designed to work for *any* array type, e.g. arrays of arrays of arrays of bytes. Even if I hardcoded several thousand possible types, Thrice wouldn't work for custom user types. If you do find a way to make this work, please let me know. Cheers, Andrew Pennebaker www.yellosoft.us On Tue, Oct 18, 2011 at 5:39 AM, Vladimir Zhirov wrote: > Sven Barth wrote: > > Generic functions are NOT implemented in trunk (at least as > > far as I know...). > > Ouch, sorry. I read about "generic procedural types" at "New > features trunk" wiki page and thought it was what OP need. > Andrew, I apologize for misinformation and thanks Sven for > correcting me. > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal >
Jonas Maebe
to Andrew Pennebaker
Andrew Pennebaker wrote
In particular, if anyone knows a way to implement a general concatenation function Concat(Arr1, Arr2), let me know.

I'm under the impression that you are trying to program in a statically typed language the same way as you'd use a dynamically typed language. Even with generic functions (which, as mentioned before, are not yet supported by FPC) you'd have to explicitly instantiate such a function for every type you'd want to do this for.

More generally, concatenating arrays is an operation that is seldom done, because a) it's slow, especially once the arrays get to a certain size (lots of data copying, memory allocation operations) b) it leads to memory fragmentation (freeing the old arrays, allocating a new one)

Pascal has a separate string type to optimize one common case where concatenating arrays is often required. In other cases, people generally use some form of list structure (generic or not) in case lots of insertions/deletions/concatenations are required.

Jonas

Sven Barth
to Jonas Maebe
Jonas Maebe wrote 7 lines
On 18 Oct 2011, at 20:03, Andrew Pennebaker wrote: > In particular, if anyone knows a way to implement a general concatenation > function Concat(Arr1, Arr2), let me know. I'm under the impression that you are trying to program in a statically typed language the same way as you'd use a dynamically typed language. Even with generic functions (which, as mentioned before, are not yet supported by FPC) you'd have to explicitly instantiate such a function for every type you'd want to do this for.

At least in theory it should work with generic functions (and using the Delphi compatible generic syntax):

=== source begin ===

type
   TGenArray<T> = array of T; // this should work in trunk already
function Concat<T>(Arr1, Arr2: TGenArray<T>): TGenArray<T>;
begin
   SetLength(Result, Length(aArray1) + Length(aArray2));
   if Length(aArray1) > 0 then
     Move(aArray1[0], Result[0], Length(aArray1) * SizeOf(T));
   if Length(aArray2) > 0 then
     Move(aArray2[0], Result[Length(aArray1)], Length(aArray2) * SizeOf(T));
end;
var
   arr1, arr2, res: array of Integer;
begin
   // init arr1
   ...
   // init arr2
   ...
   res := Concat<Integer>(arr1, arr2);
   ...
end.

=== source end ===

(tested using a non generic integer version)

Regards,
Sven

Jonas Maebe
to Sven Barth
Sven Barth wrote 12 lines
type TGenArray<T> = array of T; // this should work in trunk already function Concat<T>(Arr1, Arr2: TGenArray<T>): TGenArray<T>; begin SetLength(Result, Length(aArray1) + Length(aArray2)); if Length(aArray1) > 0 then Move(aArray1[0], Result[0], Length(aArray1) * SizeOf(T)); if Length(aArray2) > 0 then Move(aArray2[0], Result[Length(aArray1)], Length(aArray2) * SizeOf(T)); end;

This implementation will result in crashes if T is a reference-counted type.

Jonas

Andrew Pennebaker
to Sven Barth: At least in theory it should work with generic functions (and using the Delphi compatible…

Barth, something's not quite right. I've compiled and installed the trunk version of fpc, but it won't recognize this syntax.

paycheck.pas:

unit Paycheck;
interface
type
TArray<T> = array of T;
...

Trace:

fpc example.pas
Compiling example.pas
Compiling paycheck.pas
paycheck.pas(4,8) Fatal: Syntax error, "=" expected but "<" found Fatal: Compilation aborted

Either my syntax is wrong, or trunk doesn't have the syntax, or I'm having trouble getting the trunk version.

Cheers,

Andrew Pennebaker
www.yellosoft.us

Sven Barth wrote 55 lines
On 18.10.2011 21:30, Jonas Maebe wrote: > > On 18 Oct 2011, at 20:03, Andrew Pennebaker wrote: > > In particular, if anyone knows a way to implement a general concatenation >> function Concat(Arr1, Arr2), let me know. >> > > I'm under the impression that you are trying to program in a statically > typed language the same way as you'd use a dynamically typed language. Even > with generic functions (which, as mentioned before, are not yet supported by > FPC) you'd have to explicitly instantiate such a function for every type > you'd want to do this for. > At least in theory it should work with generic functions (and using the Delphi compatible generic syntax): === source begin === type TGenArray<T> = array of T; // this should work in trunk already function Concat<T>(Arr1, Arr2: TGenArray<T>): TGenArray<T>; begin SetLength(Result, Length(aArray1) + Length(aArray2)); if Length(aArray1) > 0 then Move(aArray1[0], Result[0], Length(aArray1) * SizeOf(T)); if Length(aArray2) > 0 then Move(aArray2[0], Result[Length(aArray1)], Length(aArray2) * SizeOf(T)); end; var arr1, arr2, res: array of Integer; begin // init arr1 ... // init arr2 ... res := Concat<Integer>(arr1, arr2); ... end. === source end === (tested using a non generic integer version) Regards, Sven ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>
Sven Barth
to Jonas Maebe: This implementation will result in crashes if T is a reference-counted type. Jonas
Jonas Maebe wrote 17 lines
On 18 Oct 2011, at 21:55, Sven Barth wrote: > > type > TGenArray<T> = array of T; // this should work in trunk already > > function Concat<T>(Arr1, Arr2: TGenArray<T>): TGenArray<T>; > begin > SetLength(Result, Length(aArray1) + Length(aArray2)); > if Length(aArray1)> 0 then > Move(aArray1[0], Result[0], Length(aArray1) * SizeOf(T)); > if Length(aArray2)> 0 then > Move(aArray2[0], Result[Length(aArray1)], Length(aArray2) * SizeOf(T)); > end; This implementation will result in crashes if T is a reference-counted type.

Right... I tend to forget about these... what would the correct way to copy an array of ref counted types? E.g. an "array of string"?

Regards,
Sven

Sven Barth
to Andrew Pennebaker: Barth, something's not quite right. I've compiled and installed the trunk version of fpc,…
Andrew Pennebaker wrote 21 lines
Barth, something's not quite right. I've compiled and installed the trunk version of fpc, but it won't recognize this syntax. paycheck.pas: unit Paycheck; interface type TArray<T> = array of T; ... Trace: fpc example.pas Compiling example.pas Compiling paycheck.pas paycheck.pas(4,8) Fatal: Syntax error, "=" expected but "<" found Fatal: Compilation aborted Either my syntax is wrong, or trunk doesn't have the syntax, or I'm having trouble getting the trunk version.

You either need to add "{$mode delphi}" between "unit Paycheck;" and "interface" or you need to write it like this (though I haven't tested it):

type
   generic TArray<T> = array of T;

Regards,
Sven

PS: It's more polite to use the first name when addressing persons in a mailing list.

Andrew Pennebaker
to Sven Barth: You either need to add "{$mode delphi}" between "unit Paycheck;" and "interface" or you…

Sven, I added the {$mode delphi} macro and prefaced each type with the "generic" specification. I'm still getting errors.

paycheck.pas:

unit Paycheck;
{$mode delphi}
interface
type
    generic TArray<T> = array of T;
    generic TFn<T> = function() : T;
...

Trace:

fpc example.pas
Compiling example.pas
Compiling paycheck.pas
paycheck.pas(5,32) Error: Identifier not found "T"
paycheck.pas(5,32) Error: Error in type definition
paycheck.pas(6,2) Error: This type can't be a generic
paycheck.pas(6,33) Error: Identifier not found "T"
paycheck.pas(7,1) Error: This type can't be a generic
paycheck.pas(7,25) Fatal: Syntax error, ";" expected but "<" found
Fatal: Compilation aborted

Cheers,

Andrew Pennebaker
www.yellosoft.us

Sven Barth wrote 42 lines
Am 18.10.2011 23:08, schrieb Andrew Pennebaker: Barth, something's not quite right. I've compiled and installed the > trunk version of fpc, but it won't recognize this syntax. > > paycheck.pas: > > unit Paycheck; > interface > type > TArray<T> = array of T; > ... > > Trace: > > fpc example.pas > Compiling example.pas > Compiling paycheck.pas > paycheck.pas(4,8) Fatal: Syntax error, "=" expected but "<" found > Fatal: Compilation aborted > > Either my syntax is wrong, or trunk doesn't have the syntax, or I'm > having trouble getting the trunk version. > You either need to add "{$mode delphi}" between "unit Paycheck;" and "interface" or you need to write it like this (though I haven't tested it): type generic TArray<T> = array of T; Regards, Sven PS: It's more polite to use the first name when addressing persons in a mailing list. ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>
Jonas Maebe
to Marco van de Voort: In our previous episode, Sven Barth said: copy () ? :-)
Marco van de Voort wrote 7 lines
In our previous episode, Sven Barth said: >> This implementation will result in crashes if T is a reference- >> counted type. > > Right... I tend to forget about these... what would the correct way > to > copy an array of ref counted types? E.g. an "array of string"?

For-loops.

copy () ? :-)

copy() cannot be used to concatenate two arrays, because it is a function that returns a new array with contantes of (a potentially sub- array of) the original array.

Jonas

Sven Barth
to Marco van de Voort: In our previous episode, Sven Barth said: copy () ? :-)
Marco van de Voort wrote 7 lines
In our previous episode, Sven Barth said: >> This implementation will result in crashes if T is a reference-counted type. > > Right... I tend to forget about these... what would the correct way to > copy an array of ref counted types? E.g. an "array of string"? copy () ? :-)

I thought about "copy", too, but how would you implement a generic "concat" using "copy" (or even just an "array of String" one)?

Regards,
Sven

Sven Barth
to Andrew Pennebaker: Sven, I added the {$mode delphi} macro and prefaced each type with the "generic"…
Andrew Pennebaker wrote
Sven, I added the {$mode delphi} macro and prefaced each type with the "generic" specification. I'm still getting errors.

Either add "{$mode delphi}" XOR "generic"

E.g.

Solution 1:

unit Foo;
interface
type
   generic TGenArray<T> = array of T;
...

Solution 2:

unit Foo;
{$mode delphi}
interface
type
   TGenArray<T> = array of T;

I just tested. Both work.

Regards,
Sven

Marco van de Voort
to Jonas Maebe: For-loops. copy() cannot be used to concatenate two arrays, because it is a function that…

In our previous episode, Jonas Maebe said:

Show quoted text 11 lines
>> Right... I tend to forget about these... what would the correct way >> to >> copy an array of ref counted types? E.g. an "array of string"? For-loops. > copy () ? :-) copy() cannot be used to concatenate two arrays, because it is a function that returns a new array with contantes of (a potentially sub- array of) the original array.

True. I only reacted on the last bit though. Create a deep copy. Not the application which copies to a certain element number. There is no procedure for that. There is a procedure to do it the other way around though (get sub array from array) called slice.

Sven Barth
to Jonas Maebe: For-loops. copy() cannot be used to concatenate two arrays, because it is a function that…
Jonas Maebe wrote 11 lines
On 19 Oct 2011, at 09:59, Marco van de Voort wrote: > In our previous episode, Sven Barth said: >>> This implementation will result in crashes if T is a >>> reference-counted type. >> >> Right... I tend to forget about these... what would the correct way to >> copy an array of ref counted types? E.g. an "array of string"? For-loops.

*sigh*

For-loops it is then...

Show quoted text 5 lines
> copy () ? :-) copy() cannot be used to concatenate two arrays, because it is a function that returns a new array with contantes of (a potentially sub-array of) the original array.

That's what I remembered about "copy" as well.

Regards,
Sven

Marco van de Voort
to Sven Barth: I thought about "copy", too, but how would you implement a generic "concat" using "copy"…

In our previous episode, Sven Barth said:

Show quoted text 8 lines
>> >> Right... I tend to forget about these... what would the correct way to >> copy an array of ref counted types? E.g. an "array of string"? > > copy () ? :-) I thought about "copy", too, but how would you implement a generic "concat" using "copy" (or even just an "array of String" one)?

(as said I only reacted on the other bit).

Not without creating a compiler magic function that does it for a refcounted types as opposite to slice(). But then you start down a slippery slope trying to create a list based language, and LISP already has been invented :-)

Andrew Pennebaker
to Sven Barth: Either add "{$mode delphi}" XOR "generic" E.g. Solution 1: unit Foo; interface type…

Right, I tried just {$mode delphi} and just generic, and when both failed I tried them at the same time.

Maybe I'm not using a recent enough version?

Free Pascal Compiler version 2.4.4 [2011/05/01] for i386

Cheers,

Andrew Pennebaker
www.yellosoft.us

Sven Barth wrote 35 lines
Am 19.10.2011 10:01, schrieb Andrew Pennebaker: Sven, I added the {$mode delphi} macro and prefaced each type with the > "generic" specification. I'm still getting errors. > Either add "{$mode delphi}" XOR "generic" E.g. Solution 1: unit Foo; interface type generic TGenArray<T> = array of T; ... Solution 2: unit Foo; {$mode delphi} interface type TGenArray<T> = array of T; I just tested. Both work. Regards, Sven ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>
Florian Klämpfl
to Sven Barth: *sigh* For-loops it is then... That's what I remembered about "copy" as well. Sven
Sven Barth wrote 16 lines
Am 19.10.2011 10:27, schrieb Jonas Maebe: > > On 19 Oct 2011, at 09:59, Marco van de Voort wrote: > >> In our previous episode, Sven Barth said: >>>> This implementation will result in crashes if T is a >>>> reference-counted type. >>> >>> Right... I tend to forget about these... what would the correct way to >>> copy an array of ref counted types? E.g. an "array of string"? > > For-loops. *sigh* For-loops it is then...

Compared with the affort for ref. counting this is negliable imo. Modern processors don't perform that bad on a simple loop to copy memory.

Show quoted text 8 lines
>> copy () ? :-) > > copy() cannot be used to concatenate two arrays, because it is a > function that returns a new array with contantes of (a potentially > sub-array of) the original array. That's what I remembered about "copy" as well.

Copy does a one level deep copy.

Sven Barth
to Andrew Pennebaker: Right, I tried just {$mode delphi} and just generic, and when both failed I tried them at…
Andrew Pennebaker wrote 6 lines
Right, I tried just {$mode delphi} and just generic, and when both failed I tried them at the same time. Maybe I'm not using a recent enough version? Free Pascal Compiler version 2.4.4 [2011/05/01] for i386

That's why I said "trunk". Trunk is the development version of the compiler. You can look for compiler snapshots on the FPC website (look at the Development page). Also you can download the sources of the compiler and compile them using your existing 2.4.4 compiler. Another possibility is to wait until the 2.6 release is released. That will contain the features as well.

Regards,
Sven

Andrew Pennebaker
to Sven Barth

2.6, eh? Awesome.

I'm using the SVN trunk, but it's not working for me for some reason. I'll just wait for v2.6 then.

Cheers,

Andrew Pennebaker
www.yellosoft.us

Sven Barth wrote 25 lines
Am 19.10.2011 20:08, schrieb Andrew Pennebaker: Right, I tried just {$mode delphi} and just generic, and when both > failed I tried them at the same time. > > Maybe I'm not using a recent enough version? > > Free Pascal Compiler version 2.4.4 [2011/05/01] for i386 > That's why I said "trunk". Trunk is the development version of the compiler. You can look for compiler snapshots on the FPC website (look at the Development page). Also you can download the sources of the compiler and compile them using your existing 2.4.4 compiler. Another possibility is to wait until the 2.6 release is released. That will contain the features as well. Regards, Sven ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>
waldo kitty
to Andrew Pennebaker
Andrew Pennebaker wrote
2.6, eh? Awesome. I'm using the SVN trunk, but it's not working for me for some reason.

this is why the latest version of the compiler, 2.4.4 is the one supported ;)

I'll just wait for v2.6 then.

always another possibility... depending on the waittime, of course ;)

Graeme Geldenhuys
to Andrew Pennebaker: 2.6, eh? Awesome. I'm using the SVN trunk, but it's not working for me for some reason.…
Andrew Pennebaker wrote
I'll just wait for v2.6 then.

No need to wait, checkout the fixes_2_6 branch, which is currently at version 2.5.1, but will become the v2.6.0 release. This also means you will help test the future 2.6.0 release and catch any possible bugs _before_ the actual release. Lets try and make v2.6.0 a solid release because Trunk looks like it will take damn long before its kind of in a stable state.

svn co http://svn.freepascal.org/svn/fpc/branches/fixes_2_6

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/
Andrew Pennebaker
to Sven Barth

Something's wrong with the makefiles. I checked out the Subversion trunk<http://svn.freepascal.org/svn/fpc/trunk/>and ran sudo make install.

Partway through the process, when I run "fpc" in a new terminal, I get:

$ fpc
Free Pascal Compiler version 2.7.1

But when make finishes installing, I run fpc again and get:

$ fpc
Free Pascal Compiler version 2.4.4

At some point during the installation process, an old fpc is being copied over the new.

I've tried removing the old fpc. But when I rerun make install, the same thing happens.

Cheers,

Andrew Pennebaker
www.yellosoft.us

Sven Barth wrote 18 lines
Am 20.10.2011 17:08, schrieb Andrew Pennebaker: 2.6, eh? Awesome. > > I'm using the SVN trunk, but it's not working for me for some reason. > I'll just wait for v2.6 then. > Didn't you just say that you're using 2.4.4? Trunk is currently 2.7.1. Regards, Sven ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>
Andrew Pennebaker
to Andrew Pennebaker

I forcibly sudo cp ppc386 /usr/local/bin/fpc, mitigating the issue. Yeah, something in the makefile installation process is definitely moving over an older version. (I deleted the whole directory for the v2.4.4 subversion, so that's not the problem.)

Cheers,

Andrew Pennebaker
www.yellosoft.us

On Mon, Oct 31, 2011 at 3:33 AM, Andrew Pennebaker <

Show quoted text 48 lines
wrote: Something's wrong with the makefiles. I checked out the Subversion trunk<http://svn.freepascal.org/svn/fpc/trunk/>and ran sudo make install. Partway through the process, when I run "fpc" in a new terminal, I get: $ fpc Free Pascal Compiler version 2.7.1 But when make finishes installing, I run fpc again and get: $ fpc Free Pascal Compiler version 2.4.4 At some point during the installation process, an old fpc is being copied over the new. I've tried removing the old fpc. But when I rerun make install, the same thing happens. Cheers, Andrew Pennebaker www.yellosoft.us On Fri, Oct 21, 2011 at 9:47 AM, Sven Barth wrote: > Am 20.10.2011 17:08, schrieb Andrew Pennebaker: > > 2.6, eh? Awesome. >> >> I'm using the SVN trunk, but it's not working for me for some reason. >> I'll just wait for v2.6 then. >> > > Didn't you just say that you're using 2.4.4? Trunk is currently 2.7.1. > > > Regards, > Sven > > ______________________________**_________________ > fpc-pascal maillist - > http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal> >
Andrew Pennebaker
to Sven Barth: Didn't you just say that you're using 2.4.4? Trunk is currently 2.7.1. Sven

Sven, recap: I want to make a GenArray function that returns an array populated by a generator anonymous function. For example, GenString would generate a random string by doing GenArray(GenChar). Users could create their own generators, e.g. GenTree wrapping around GenArray(GenLeaf), GenGraph wrapping around GenArray(GenNode) and GenArray(GenEdge), etc.

paycheck.pas:

unit Paycheck;
interface
type
    generic TArray<T> = array of T;
    generic TFn<T> = function() : T;
function GenInt () : TFn<integer>;
function GenBool() : TFn<boolean>;
function GenChar() : TFn<char>;
function GenArray(gen : TFn<T>) : TArray<T>;
function GenString() : TFn<string>;
{ ... }

I'm getting compiler errors for the generics.

$ fpc example.pas
Free Pascal Compiler version 2.7.1 [2011/10/31] for i386 Copyright (c) 1993-2011 by Florian Klaempfl and others Target OS: Darwin for i386
Compiling example.pas
Compiling paycheck.pas
paycheck.pas(6,25) Error: Generics without specialization cannot be used as a type for a variable
paycheck.pas(6,25) Fatal: Syntax error, ";" expected but "<" found Fatal: Compilation aborted

Cheers,

Andrew Pennebaker
www.yellosoft.us

Sven Barth wrote 18 lines
Am 20.10.2011 17:08, schrieb Andrew Pennebaker: 2.6, eh? Awesome. > > I'm using the SVN trunk, but it's not working for me for some reason. > I'll just wait for v2.6 then. > Didn't you just say that you're using 2.4.4? Trunk is currently 2.7.1. Regards, Sven ______________________________**_________________ fpc-pascal maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-pascal<http://lists.freepascal.org/mailman/listinfo/fpc-pascal>
Sven Barth
to Andrew Pennebaker
Andrew Pennebaker wrote 26 lines
paycheck.pas: unit Paycheck; interface type generic TArray<T> = array of T; generic TFn<T> = function() : T; function GenInt () : TFn<integer>; function GenBool() : TFn<boolean>; function GenChar() : TFn<char>; function GenArray(gen : TFn<T>) : TArray<T>; function GenString() : TFn<string>; { ... } I'm getting compiler errors for the generics. $ fpc example.pas Free Pascal Compiler version 2.7.1 [2011/10/31] for i386 Copyright (c) 1993-2011 by Florian Klaempfl and others Target OS: Darwin for i386 Compiling example.pas Compiling paycheck.pas paycheck.pas(6,25) Error: Generics without specialization cannot be used as a type for a variable paycheck.pas(6,25) Fatal: Syntax error, ";" expected but "<" found Fatal: Compilation aborted

Ok, you're experiencing two different problems here:

1. you are trying to do inline specializations in the functions "GenInt", "GenBool", "GenChar" and "GenString". This is not supported in mode "ObjFPC". You need to use "{$mode delphi}" instead (though I don't know whether this will indeed work in trunk).

2. Your function "GenArray" is a generic function. These are not yet supported by FPC (they are on my ToDo list though). Once they are implemented your declaration will need to look like this:

function GenArray<T>(gen: TFn<T>): TArray<T>;

And you will call them like this:

function Foo: Integer;
...
var
   intarray: TArray<Integer>;
begin
   intarray := GenArray<Integer>(@Foo);
end.

This does NOT work yet.

Regards,
Sven

Jonas Maebe
to Andrew Pennebaker: I forcibly sudo cp ppc386 /usr/local/bin/fpc, mitigating the issue. Yeah, something in…
Andrew Pennebaker wrote
I forcibly sudo cp ppc386 /usr/local/bin/fpc, mitigating the issue. Yeah, something in the makefile installation process is definitely moving over an older version.

Create a symlink from /usr/local/bin/ppc386 to /usr/local/lib/fpc/2.7.1/ppc386 (or ppcx64 in case you're on x86-64). "fpc" searches for a compiler binary in the same directory as where its own binary is located. "make install" does not create/overwrite ppcXXX, because that changes the default compiler (which is a separate step from installing a new version in parallel with another version).

Jonas

Andrew Pennebaker
to Jonas Maebe

Sven, awesome! Looks like FPC will be getting some exciting features in the near future.

Jonas, "make install" does, however, overwrite /usr/local/bin/fpc, which is not a symlink, with an old version during install. Try running fpc -version halfway and after "make install".

Cheers,

Andrew Pennebaker
www.yellosoft.us

Jonas Maebe wrote 22 lines
On 31 Oct 2011, at 08:36, Andrew Pennebaker wrote: > I forcibly sudo cp ppc386 /usr/local/bin/fpc, mitigating the issue. Yeah, > something in the makefile installation process is definitely moving over an > older version. Create a symlink from /usr/local/bin/ppc386 to /usr/local/lib/fpc/2.7.1/ppc386 (or ppcx64 in case you're on x86-64). "fpc" searches for a compiler binary in the same directory as where its own binary is located. "make install" does not create/overwrite ppcXXX, because that changes the default compiler (which is a separate step from installing a new version in parallel with another version). Jonas _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Jonas Maebe
to Andrew Pennebaker
Andrew Pennebaker wrote
Jonas, "make install" does, however, overwrite /usr/local/bin/fpc, which is not a symlink, with an old version during install. Try running fpc -version halfway and after "make install".

The "fpc" binary does not have a version number. It reports the version number of the compiler binary that it finds.

Jonas

PS: "-version" does not mean "print the version". It means enable the e, r, s, i, o and n verbosity switches (but your /etc/fpc.cfg probably contains the -l switch, and the logo includes the version number). -iV is the command line option to make the compiler prints just its version.

Andrew Pennebaker
to Jonas Maebe: The "fpc" binary does not have a version number. It reports the version number of the…

Jonas: Thanks, I'll use fpc -iV from now on.

But "make install" still puts an fpc binary in /usr/local/bin that reports "2.7.1" and then overwrites *something* so that a second fpc call reports "2.4.4".

Cheers,

Andrew Pennebaker
www.yellosoft.us

Jonas Maebe wrote 23 lines
On 31 Oct 2011, at 18:29, Andrew Pennebaker wrote: > Jonas, "make install" does, however, overwrite /usr/local/bin/fpc, which is > not a symlink, with an old version during install. Try running fpc -version > halfway and after "make install". The "fpc" binary does not have a version number. It reports the version number of the compiler binary that it finds. Jonas PS: "-version" does not mean "print the version". It means enable the e, r, s, i, o and n verbosity switches (but your /etc/fpc.cfg probably contains the -l switch, and the logo includes the version number). -iV is the command line option to make the compiler prints just its version._______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal