Sign in Join

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

Mailing lists / fpc-devel / 2013-05

Closures via interfaces

22 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

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

Vasiliy Kevroletin

Hi all,

About 2 months ago there was a big discussion about closures(thread "Delphi anonymous methods"). After this discussion I started work on Delhi-like closures for fpc. I am far from finish and current implementation is not perfect. But I already have positive results: it's possible to declare and use anonymous functions. After few changes closures will be able to capture variables. I created mantis#24481 to handle this work. Everyone who is interested in closures and good in compiler is welcome into mantis. I would be happy if someone looked into changes and said few words.

I described details of proposed and partly implemented approach in mantis. This is Delphi's approach. Some people call it "closures via interfaces". In slightly modified way it will allow to capture variables by value (which was requested in previous discussion). I like this approach because it's simple: it doesn't require to change codegenerator or rtl. On the other hand for each closure it creates new interface. And almost for each closure it creates new class. As a result: space overhead because of virtual tables and rtti.

My question to community is: what do you think about proposed implementation? Are there arguments for another approach?

Vasiliy K.

Reply by email

Sven Barth
to Vasiliy Kevroletin
Vasiliy Kevroletin wrote 23 lines
Hi all, About 2 months ago there was a big discussion about closures(thread "Delphi anonymous methods"). After this discussion I started work on Delhi-like closures for fpc. I am far from finish and current implementation is not perfect. But I already have positive results: it's possible to declare and use anonymous functions. After few changes closures will be able to capture variables. I created mantis#24481 to handle this work. Everyone who is interested in closures and good in compiler is welcome into mantis. I would be happy if someone looked into changes and said few words. I described details of proposed and partly implemented approach in mantis. This is Delphi's approach. Some people call it "closures via interfaces". In slightly modified way it will allow to capture variables by value (which was requested in previous discussion). I like this approach because it's simple: it doesn't require to change codegenerator or rtl. On the other hand for each closure it creates new interface. And almost for each closure it creates new class. As a result: space overhead because of virtual tables and rtti. My question to community is: what do you think about proposed implementation? Are there arguments for another approach?

Thank you for the update. I'm still looking at your changes, but one thing I noticed: please adhere to the coding style used in the compiler ( for example). For example don't use "1 line
if-statements" (e.g. "if x then foo;"), but put the statement into a seperate line.

I should have told you this before you started, but I've forgotten it :(

Regards,
Sven

Reply by email

Sven Barth
to Sven Barth
Sven Barth wrote 32 lines
On 26.05.2013 12:12, Vasiliy Kevroletin wrote: > Hi all, > > About 2 months ago there was a big discussion about closures(thread > "Delphi anonymous methods"). After this discussion I started work on > Delhi-like closures for fpc. I am far from finish and current > implementation is not perfect. But I already have positive results: it's > possible to declare and use anonymous functions. After few changes > closures will be able to capture variables. I created mantis#24481 to > handle this work. Everyone who is interested in closures and good in > compiler is welcome into mantis. I would be happy if someone looked into > changes and said few words. > > I described details of proposed and partly implemented approach in > mantis. This is Delphi's approach. Some people call it "closures via > interfaces". In slightly modified way it will allow to capture variables > by value (which was requested in previous discussion). I like this > approach because it's simple: it doesn't require to change codegenerator > or rtl. On the other hand for each closure it creates new interface. And > almost for each closure it creates new class. As a result: space > overhead because of virtual tables and rtti. > > My question to community is: what do you think about proposed > implementation? Are there arguments for another approach? Thank you for the update. I'm still looking at your changes, but one thing I noticed: please adhere to the coding style used in the compiler ( for example). For example don't use "1 line if-statements" (e.g. "if x then foo;"), but put the statement into a seperate line. I should have told you this before you started, but I've forgotten it :(

Ah, now that I've reached the last commit I see that you've already adjusted most cases. Please change IsClosure to "is_closure" as well.

Regards,
Sven

Reply by email

Maciej Izak
to Sven Barth
It's not yet available in trunk, just a work in progress. Though I DO hope that it will be part of trunk once Vasiliy is finished :)

So I am waiting impatiently ^^. I think it's interesting time for FPC! To be completely happy, there is only one seriously lack - extended RTTI. :)

Regards,
HNB

Reply by email

Dimitri Smits
to Paul Ishenin

Paul,

I think the OP meant the unit called 'rtti' in recent XE versions of Delphi.

kind regards,
Dimitri Smits

----- Oorspronkelijk e-mail -----

Show quoted text 24 lines
Van: "Paul Ishenin" Aan: "FPC developers' list" Verzonden: Maandag 27 mei 2013 02:30:40 Onderwerp: Re: [fpc-devel] Closures via interfaces 27.05.2013 5:52, Maciej Izak пишет: > So I am waiting impatiently ^^. I think it's interesting time for > FPC! To be completely happy, there is only one seriously lack - > extended > RTTI. :) RTTI has been extended recently: http://wiki.lazarus.freepascal.org/User_Changes_Trunk#RTTI_changes Please tell what exactly you are waiting for? Best regards, Paul Ishenin _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Sven Barth
to Paul Ishenin: 27.05.2013 5:52, Maciej Izak пишет: RTTI has been extended recently:…
"Paul Ishenin" wrote 10 lines
27.05.2013 5:52, Maciej Izak пишет: > So I am waiting impatiently ^^. I think it's interesting time for > FPC! To be completely happy, there is only one seriously lack - extended > RTTI. :) RTTI has been extended recently:

http://wiki.lazarus.freepascal.org/User_Changes_Trunk#RTTI_changes

Please tell what exactly you are waiting for?

The new extended RTTI introduced in Delphi 2009 which allows access to private/protected/public members as well together with attributes and things like TVirtualMethodInterceptor, Invoke and TValue.

Regards,
Sven

Reply by email

Paul Ishenin
to Sven Barth

27.05.2013 15:32, Sven Barth пишет:

The new extended RTTI introduced in Delphi 2009 which allows access to private/protected/public members as well together with attributes and things like TVirtualMethodInterceptor, Invoke and TValue.

Sven, I did not ask what and how delphi implemented. I asked Maciej Izak what he wants from extended RTTI. Maybe this is a small subset which is not very hard to implement.

Best regards,
Paul Ishenin

Reply by email

Maciej Izak
to Paul Ishenin
Show quoted text 7 lines
Sven, I did not ask what and how delphi implemented. I asked Maciej Izak what he wants from extended RTTI. Maybe this is a small subset which is not very hard to implement. Best regards, Paul Ishenin

Unfortunately, Sven is right :). I need this to share another free library for FPC. It was originally intended for sale to the Embarcadero. Absolute automatic binary streaming (seriously, for each type that exists in Pascal, including Class, ClassRef, Interfaces, Pointers, menaged records with help of attributes). Small demo:

===begin code===
  // save
  f := TFileStream.Create(dSaveLDFM.FileName, fmCreate);
  f.Write<AnsiChar>(4, FILE_TAG[0]);
  f.Write<UInt32>(1);
  f.Write<TArray<string>>(FDfmDictionary.Keys.ToArray);
  f.Free;
  // read
  f := TFileStream.Create(dOpenLDFM.FileName, fmOpenRead);
  f.Read<AnsiChar>(4, stag);
  if stag  FILE_TAG then raise EProgrammerNotFound.Create('File is
corrupted');
  if f.Read<UInt32>  1 then raise EProgrammerNotFound.Create('Wrong file
version');
  f.Read<TArray<string>>(LList);
  f.Free;
===end code===

Implemented as helpers for streams :). It will be another "stress test" for generic types, and RTTI.
To done this, FPC needs:

1. Extended RTTI (especially with attributes and access to private/protected/public members. This library don't need TVirtualMethodInterceptor,
Invoke (but I think attributes needs Invoke :( ) and TValue)
2. Fix/implementation of: http://bugs.freepascal.org/view.php?id=24254

Regards,
HNB

Reply by email

Paul Ishenin
to Maciej Izak
Maciej Izak wrote 5 lines
Unfortunately, Sven is right :). I need this to share another free library for FPC. It was originally intended for sale to the Embarcadero. Absolute automatic binary streaming (seriously, for each type that exists in Pascal, including Class, ClassRef, Interfaces, Pointers, menaged records with help of attributes). Small demo:

...

1. Extended RTTI (especially with attributes and access to private/protected/public members. This library don't need TVirtualMethodInterceptor, Invoke (but I think attributes needs Invoke :( ) and TValue)

If you don't need RTTI unit then it will be much more simplier to implement your requirements.

Attributes are half ready in a branch. RTTI for non-published elements (together with $RTTI directive) is not a very hard task.

Best regards,
Paul Ishenin

Reply by email

Maciej Izak
to Paul Ishenin
Show quoted text 5 lines
If you don't need RTTI unit then it will be much more simplier to implement your requirements. Attributes are half ready in a branch. RTTI for non-published elements (together with $RTTI directive) is not a very hard task.

I use a lot of TypInfo. If I get RTTI for non-published elements and attributes I think I can elminate RTTI module (or write my own compatible implementation for RTTI). But also important is fix for 24254.

Regards,
HNB

Reply by email

Hans-Peter Diettrich
to Vasiliy Kevroletin: About 2 months ago there was a big discussion about closures(thread "Delphi anonymous…
Show quoted text 11 lines
I described details of proposed and partly implemented approach in mantis. This is Delphi's approach. Some people call it "closures via interfaces". In slightly modified way it will allow to capture variables by value (which was requested in previous discussion). I like this approach because it's simple: it doesn't require to change codegenerator or rtl. On the other hand for each closure it creates new interface. And almost for each closure it creates new class. As a result: space overhead because of virtual tables and rtti. My question to community is: what do you think about proposed implementation? Are there arguments for another approach?

In contrast to anonymous procedures, true closures require fixed and immutable parameters. This requirement will disallow also references to variables outside the function, e.g. in their enclosing procedure. This would require deep(!) copies of all values/variables used in the anonymous procedure body, together with tests of already copied memory objects. How to create a deep copy at all, of e.g. an interface reference or a Handle?

IMO we have to decide in the first place whether to implement anonymous procedures for Delphi compatibility *only*, or whether we want true closures (functional programming) inside the imperative OPL.

ATM I have no opinion about this matter, because I don't plan to use neither anonymous procedures nor functional programming myself. To me it looks safer (better controllable) to use ordinary callback procedures instead of anonymous ones, and for functional programming I'd only accept an full-featured implementation, e.g. a LISP like sub-system *written* in Pascal.

DoDi

Reply by email

Sven Barth
to Hans-Peter Diettrich
"Hans-Peter Diettrich" wrote 5 lines
Vasiliy Kevroletin schrieb: > I described details of proposed and partly implemented approach in

mantis. This is Delphi's approach. Some people call it "closures via interfaces". In slightly modified way it will allow to capture variables by value (which was requested in previous discussion). I like this approach because it's simple: it doesn't require to change codegenerator or rtl. On the other hand for each closure it creates new interface. And almost for each closure it creates new class. As a result: space overhead because of virtual tables and rtti.

> > My question to community is: what do you think about proposed

implementation? Are there arguments for another approach?

Show quoted text 13 lines
In contrast to anonymous procedures, true closures require fixed and immutable parameters. This requirement will disallow also references to variables outside the function, e.g. in their enclosing procedure. This would require deep(!) copies of all values/variables used in the anonymous procedure body, together with tests of already copied memory objects. How to create a deep copy at all, of e.g. an interface reference or a Handle? IMO we have to decide in the first place whether to implement anonymous procedures for Delphi compatibility *only*, or whether we want true closures (functional programming) inside the imperative OPL.

The values of local variables are captured for each closure. While in Delphi they are captured by reference (basically; it's in fact a bit more complicated) Vasiliy plans to also allow capturing by value. Inside the procedure body itself the usual rules apply, so there won't be any immutability. Global variables will behave like in normal procedures and also the state of object oriented variables can be modified. So it's mostly consistent with the remaining way that Pascal's procedures work with a few additional concepts that heed to be documented accordingly.

Also there is no "true" way of closures, as in the end each language does have its own behavior.

Regards,
Sven

Reply by email

Steve Hildebrandt
to Sven Barth

Since I red there will type helper for interfaces, too I would like to know what is the current progress for this feature or whether it is on hold and will not be alvailable in the near feature? Any related information would be aprechiated.

mfg Steve Hildebrandt

Reply by email

Sven Barth
to Steve Hildebrandt
Steve Hildebrandt wrote
Since I red there will type helper for interfaces, too I would like to know what is the current progress for this feature or whether it is on hold and will not be alvailable in the near feature? Any related information would be aprechiated.

Please don't reply to existing mails if you want to start a new thread. This way you mess up the thread view and your mail might also be hidden from potential answerers. Write a new mail and enter the mailing list's address manually (or through an address book) to solve this.

Regards,
Sven

Reply by email

Steve Hildebrandt

Sorry for mistakenly sending this as an answer to another topic got the windows confused.

Since I red there will type helper for interfaces, too I would like to know what is the current progress for this feature or whether it is on hold and will not be alvailable in the near feature? Any related information would be aprechiated.

mfg Steve Hildebrandt

Reply by email

Sven Barth
to Steve Hildebrandt
Steve Hildebrandt wrote
Sorry for mistakenly sending this as an answer to another topic got the windows confused.

Thank you.

Since I red there will type helper for interfaces, too I would like to know what is the current progress for this feature or whether it is on hold and will not be alvailable in the near feature? Any related information would be aprechiated.

Currently there is no progress in this regard, but I'm still planning to add them. Technically it should be rather easy to add, but I've not yet decided what syntax I'll use to make them accessible. Currently I'm preferring to add them to "type helper"...

Regards,
Sven

Reply by email

Steve Hildebrandt
to Sven Barth
Sven Barth wrote 12 lines
On 27.05.2013 19:43, Steve Hildebrandt wrote: > Since I red there will type helper for interfaces, too I would like to > know what is the current progress for this feature or whether it is on > hold and will not be alvailable in the near feature? Any related > information would be aprechiated. Currently there is no progress in this regard, but I'm still planning to add them. Technically it should be rather easy to add, but I've not yet decided what syntax I'll use to make them accessible. Currently I'm preferring to add them to "type helper"...

Regarding the syntax I have no preference whether it will be "type helper" or "interface helper". (As long as it does not work the delphi way "record helper" would be misplaced here^^)
Sice I make heavy use of interfaces I currently broaden them up and add the implementations everywere with macros and include files. So beeing able to use Helper types here would clean things up quite a bit, but since it's no blocker for me..
I thought why not ask what the future brings and if it takes a while revisit this issue at a later date.

Regards,
Steve Hildebrandt

Reply by email

Vasiliy Kevroletin
to Sven Barth: It's not yet available in trunk, just a work in progress. Though I DO hope that it will…
Show quoted text 5 lines
It's not yet available in trunk, just a work in progress. Though I DO hope that it will be part of trunk once Vasiliy is finished :) Regards, Sven

I also hope that my work will be in trunk in the future. But instead of big merge of separate brunch I would prefer to produce series of small patches. I prepare first such patch. It will allow to parse anonymous functions but will not allow to capture variables. Next patch will be capturing of variables(it already works). Further refactoring, bugfixes, optimizations.
First patch can produce some negative side effect. Next will be safer. It should not affect programs which don't use closures. I uploaded patches for review into mantis. Changes are synchronized with latest revision and coding style is fixed.
Fate of this changes is important for me, because it's my graduate work. That is why I need feedback from developers. Most important question: does my work make sense for you? If someone will find time to attentive review then comments about changes quality are welcome. And if first patch is ok but have some minor problems then I'm ready to quickly fix it.

Thanks,
Vasiliy

Reply by email

Sven Barth
to Vasiliy Kevroletin
Vasiliy Kevroletin wrote 22 lines
> It's not yet available in trunk, just a work in progress. Though I DO > hope that it will be part of trunk once Vasiliy is finished :) > > Regards, > Sven I also hope that my work will be in trunk in the future. But instead of big merge of separate brunch I would prefer to produce series of small patches. I prepare first such patch. It will allow to parse anonymous functions but will not allow to capture variables. Next patch will be capturing of variables(it already works). Further refactoring, bugfixes, optimizations. First patch can produce some negative side effect. Next will be safer. It should not affect programs which don't use closures. I uploaded patches for review into mantis. Changes are synchronized with latest revision and coding style is fixed. Fate of this changes is important for me, because it's my graduate work. That is why I need feedback from developers. Most important question: does my work make sense for you? If someone will find time to attentive review then comments about changes quality are welcome. And if first patch is ok but have some minor problems then I'm ready to quickly fix it.

I'll try to take a look at it tomorrow.

Regards,
Sven

Reply by email