Delphi's anonymous functions in Free Pascal

classic Classic list List threaded Threaded
125 messages Options
1234567
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Jürgen Hestermann
Juha Manninen schrieb:
 > Please look at some old Pascal code from 80's. Lots of shortstring
manipulation with pointers. Very much comparable to C, and as prone to
errors as C.

Yes, new string types were needed. But why not doing it right in one
step? Instead we now have lots of different string representations which
all have their own peculiarities which everybody has to learn. To me it
seems that all these changes were hasty hacks and are now cast in stone
to live forever in the (object) Pascal language to annoy following
generations of Pascal programmers. If things are only added and nothing
is ever removed than the language becomes bloated.


 > It is good to realize that Pascal would have died already without the
class/object additions made by Borland.

I doubt that. I don't see any merrit in objects. You can do all the same
with units that declare functions and data types. You can also build an
IDE that helps you finding functions/procedure that act on special data
types. There is no innovation in object oriented programming. Just the
opposite: If I create a button "object" on my form that does something I
would expect it to act when I click on it. But that does not happen
because in the background there is still the procedural processor that
goes through a sequential list of commands. Real objects would be able
to act independently and can interact. But this would require a core for
each object which I fail to see in the near future.

I am just thinking how a child or teenager who learns programming would
think about it. He may not unterstand why you need to add
"Application.ProcessMessages;" calls into loops to keep the button
responsive. This is hiding away important information. Instead of OOP it
should have been named DAF (Data Attached Functions) or so.

Also, why can operators be overloaded? Operators are fundamental parts
of a programming language and to me it makes no sense to irk programmers
by changing its meaning.

Also, why suddenly extend the meaning of := ? It should be a simple byte
movement, nothing else (only exception should be number type
convertion). Doing arbitrary complex things when using it does not make
a clearer code. And for what reason? Just to save writing a function
call? That cannot be the direction to go. Maybe we see BEGIN and END and
the semicolon doing things too. How can one read such code? And how much
does a new user have to learn to use the Pascal language?

It could also be that it's only a matter of documentation and learning.
As many others I don't have very much time to read about and test new
features. And I also don't have to. I never failed to do what I wanted
and it was very speedy (unless I had to use some obscure "library" which
was slow) and the code is still clear and readable.


 > The challenge is to add only the RIGHT features.

That's true. But now the mark is overshot already.


 > IMO the OP additions have been good so far. For example generics
containers eliminate ugly type-casts. It is an improvement, clearly.

I can't say anything about this because I don't know the concept.



 > Closures seem like a powerful thing which can improve code.

Same as for closures, I don't know them.

 > Now Florian mentioned that procedure variables could do the same
thing. I clearly don't understand the topic enough, I must learn more.

I see that many of these new concepts are added because people come from
other languages and want to do things the same way. But often it can
already be done with the existing language and even faster. I was able
to code everything I wanted in the past 25 years without objects and
without closures and all this other stuff. But if I now try to
understand foreign code I am totally lost because here these things are
used.



_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Marco van de Voort

The link below describes two uses for anonymous methods.

http://stackoverflow.com/questions/7818759/delphi-anonymus-methods-pro-and-cons-good-practices-when-using-closuresanony/7821882#comment9576663_7821882

I don't entirely subscribe to the (1) one, it seems to be mostly a shorthand
argument.

But (2) is somewhat logical and interesting. an. funcs allow to wrap a call
to a procedure together with its arguments inside a anonymous function
(closure-like) and queue that in a different thread and have it executed
there by RTL code.

I think that (2) is the main reason for anonymous functions, and people
shouldn't assume that the use of an. funcs is the same as in functional
languages. (IOW for expressions)
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Gregory M. Turner
In reply to this post by Alexander Shishkin
----- Original Message -----

> 18.10.2011 0:53, Andrew Pennebaker пишет:
> > Does Free Pascal have anonymous functions that you can pass around,
> > e.g.
> > to a sort(compare : function, arr : array) function?
> >
>
> anonymous functions = closures = lambdas are part of functional
> paradigm. object pascal itself is not functional language.
> But there is modern trend to design multiparadigm languages (usually
> OO
> + functional + imperative).
> Delphi followed this trend. So the question is: should freepascal
> follow
> this trend too?

Taking these terms in the broadest sense possible, wouldn't we say that OOP is mostly a functional development paradigm?

Not a rhetorical question, I seriously am not sure.

OP's somewhat idiosyncratic requirement to put all the OOP metadata in a separate interface section of your code kind of underlines what I'm talking about.  It seems to me that in OOP, whatever we might happen to do procedurally, there's a strong declarative odor to everything happening at the class/interface level.

-gmt
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Juha Manninen
2011/10/22 Gregory M. Turner <[hidden email]>
Taking these terms in the broadest sense possible, wouldn't we say that OOP is mostly a functional development paradigm?

Not a rhetorical question, I seriously am not sure.

OP's somewhat idiosyncratic requirement to put all the OOP metadata in a separate interface section of your code kind of underlines what I'm talking about.  It seems to me that in OOP, whatever we might happen to do procedurally, there's a strong declarative odor to everything happening at the class/interface level.

Now you are mixing the well-established terms.
Functional programming paradigm is based on lambda calculus. There are no loop constructs or even variables in normal sense.
There are only functions which return a value without side-effects.

In Object Pascal you must define types in interface, but it doesn't change the object oriented paradigm anyhow.
In Java or C# you don't have interface definitions but they still have the same paradigm.

Wikipedia has amazingly much info. See:


On the right edge there is a list "Programming Paradigms".

Regards,
Juha


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

wkitty42
In reply to this post by Jürgen Hestermann
On 10/21/2011 01:25, Jürgen Hestermann wrote:

> Florian Klämpfl schrieb:
>  > If anybody does not see why increasing complexity without a good reason
>  > should be avoided, I recommend:
>
> I agree wholeheartly. In the past Pascal was a simple still powerfull language
> but meanwhile it has become a catchment tank for all features of all other
> languages. This defeats the original intention of Nicholas Wirth and the reason
> for what I love(d) the language. It seems everybody tries to mimic Pascal into
> whatever he is used to do in other languages. So we should no longer call this
> (Object) Pascal but "Chimera".

+1 (based on some of the recent stuff being posted :) )

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

tcoq
In reply to this post by Graeme Geldenhuys-2
+1
----- Mail Original -----
De: "Graeme Geldenhuys" <[hidden email]>
À: "FPC-Pascal users discussions" <[hidden email]>
Envoyé: Vendredi 21 Octobre 2011 10h03:27 GMT +01:00 Amsterdam / Berlin / Berne / Rome / Stockholm / Vienne
Objet: Re: [fpc-pascal] Re: Delphi's anonymous functions in Free Pascal

On 2011-10-20 22:55, Florian Klämpfl wrote:
>
> The same can be done with fpc (nested if needed) procedure variables and
> it will be more readable (imo)? The example still does not take


This seldom happens, but here I fully agree with Florian. ;-) Every
example of anonymous methods I have seen so far, can easily be done with
OP's procedure variables too.  Maybe anonymous methods were introduced
in other languages because they didn't have something like OP's
procedure variables. I guess Object Pascal was yet again ahead of
everybody else. :)



Regards,
  - Graeme -

--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Marco van de Voort
In our previous episode, [hidden email] said:
> > it will be more readable (imo)? The example still does not take
>
> This seldom happens, but here I fully agree with Florian. ;-) Every
> example of anonymous methods I have seen so far, can easily be done with
> OP's procedure variables too.  Maybe anonymous methods were introduced
> in other languages because they didn't have something like OP's
> procedure variables. I guess Object Pascal was yet again ahead of
> everybody else. :)

I hinted on it in earlier procedures, but here a typical anonymous method
usecase.

You are in a thread and want to call a method or procedure in a different
thread. (to the mainthread or a different event driven thread)

BUT, the said function takes parameters. WDYD?

Classically, you create some record, add all paramters to it, dump it in
some queue (or argument to a windows message if you play it dirty), write a
procedure in the destination thread that gets the record from the queue, and
calls the function with the parameters.

One can avoid doing the queue for every case by using a bit of OOP, but
still you need to inherit and implement that object for every signature of a
method that you want to call cross-thread this way. Loading parameters into
it in the source thread, and calling the destination procedure with
parameters in the execute method for the destination thread.

Using the anonymous function however, you put the call within the anonymous
function block. This blocks captures all necessary state, and boom it is
away.

Visually:


Problem:

call

targetobject.destinationfunction(a:integer;b:someobject;c:string);

in a different thread.


Classic solution:

type  // for every signature:
   TMyobject = class(TpseudoClosure)
                a:integer;
                b:someobject;
                c:string;
                tgob: TTargetObject;
                procedure execute; override;
              end;

procedure TMyObject.Execute;

begin
  tgob.destinationfunction(a,b,c);
end;  

// once:

var
  thrqueue :TSomeGenericThreadsafeQUeue<TPseudoClosure>;

procedure tmythread.syncfunc;

var x:TPseudoClosure;
begin
  x:=getqueuecurrentthread().popitem; // get closure object from queue
  x.execute;
  x.free;
end;

// calling from source thread;

var x : TPseudoclosure

x:=TMyObject.Create;
x.a:=a;
x.b:=b;
x.c:=c;
tboj:=targetobject;
queuefortargetthread.pushitem(x);
queuefortargetthread.queue(syncfunc); // call item async in other thread.
                                      // tthread.queue not yet in FPC

I have many such constructs in my current framework. Of course you start to
double use simple objects, and not all cases use 3 parameters. It is just
for the idea.

Note that tabstractclosure, the generic queue etc must also be defined, but that is
so general it could be in the RTL, and not a burden

---------------------------------
vs
-~-------------------------------

Equivalent solution with anon functions:

targethread.queue(
   procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
              begin
                targetobject.destinationprocedure(a,b,c);
              end;

Note how common this looks compared to the original.


Btw: I don't know this function this well. I only described it how I
saw it in several D2010 blogs. I still support D2009, and the framework
design was even older, so I don't actively use it.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

michael.vancanneyt


On Tue, 25 Oct 2011, Marco van de Voort wrote:

> In our previous episode, [hidden email] said:
>>> it will be more readable (imo)? The example still does not take
>>
>> This seldom happens, but here I fully agree with Florian. ;-) Every
>> example of anonymous methods I have seen so far, can easily be done with
>> OP's procedure variables too.  Maybe anonymous methods were introduced
>> in other languages because they didn't have something like OP's
>> procedure variables. I guess Object Pascal was yet again ahead of
>> everybody else. :)
>
> I hinted on it in earlier procedures, but here a typical anonymous method
> usecase.

[snip]

> -~-------------------------------
>
> Equivalent solution with anon functions:
>
> targethread.queue(
>   procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>              begin
>                targetobject.destinationprocedure(a,b,c);
>              end;
>
> Note how common this looks compared to the original.

One point is that you could do the above with a local (and named)
procedure as well, and still have all the context.
At the very least you would not be raping pascal's readability by putting a
complete procedure declaration inside a code block.

I don't know about you, but I have serious trouble reading the above monstrosity.
It looks like you forgot the closing ) for the queue call.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Marco van de Voort
In our previous episode, [hidden email] said:

> >
> > targethread.queue(
> >   procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
> >              begin
> >                targetobject.destinationprocedure(a,b,c);
> >              end;
> >
> > Note how common this looks compared to the original.
>
> One point is that you could do the above with a local (and named)
> procedure as well, and still have all the context.

> At the very least you would not be raping pascal's readability by putting a
> complete procedure declaration inside a code block.
>
> I don't know about you, but I have serious trouble reading the above monstrosity.
> It looks like you forgot the closing ) for the queue call.

One can debate the syntax. I won't, since even while I have similar
reservations, that will lead to the usual Delphi sucks debate, possible
implementation of an-orphaned-at-birth FPC specific syntax, and in the end
the Delphi syntax always prevails, leading to a lot of wasted time in
discussion and implementation of own inventions.

That is such a common pattern on these lists, I'm thinking about an acronym
for it to save time :-) So sufficient to say, I think own syntax inventions
are worse than the problem in the first place, and sooner or later we have
to live with it.

However there was also a questioning of the use(functionality) of anonymous
functions, I hope that I have now at least explained a typical use case, so
we can put that to rest.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

michael.vancanneyt


On Tue, 25 Oct 2011, Marco van de Voort wrote:

> In our previous episode, [hidden email] said:
>>>
>>> targethread.queue(
>>>   procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>>>              begin
>>>                targetobject.destinationprocedure(a,b,c);
>>>              end;
>>>
>>> Note how common this looks compared to the original.
>>
>> One point is that you could do the above with a local (and named)
>> procedure as well, and still have all the context.
>
>> At the very least you would not be raping pascal's readability by putting a
>> complete procedure declaration inside a code block.
>>
>> I don't know about you, but I have serious trouble reading the above monstrosity.
>> It looks like you forgot the closing ) for the queue call.
>
> One can debate the syntax. I won't, since even while I have similar
> reservations, that will lead to the usual Delphi sucks debate, possible
> implementation of an-orphaned-at-birth FPC specific syntax, and in the end
> the Delphi syntax always prevails, leading to a lot of wasted time in
> discussion and implementation of own inventions.
>
> That is such a common pattern on these lists, I'm thinking about an acronym
> for it to save time :-) So sufficient to say, I think own syntax inventions
> are worse than the problem in the first place, and sooner or later we have
> to live with it.
>
> However there was also a questioning of the use(functionality) of anonymous
> functions, I hope that I have now at least explained a typical use case, so
> we can put that to rest.

Please note that I didn't question their use, just the syntax :)

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal OT]

el_es
In reply to this post by Marco van de Voort
On 25/10/2011 12:52, Marco van de Voort wrote:

> One can debate the syntax. I won't, since even while I have similar
> reservations, that will lead to the usual Delphi sucks debate, possible
> implementation of an-orphaned-at-birth FPC specific syntax, and in the end
> the Delphi syntax always prevails, leading to a lot of wasted time in
> discussion and implementation of own inventions.
>
> That is such a common pattern on these lists, I'm thinking about an acronym
> for it to save time :-) So sufficient to say, I think own syntax inventions
> are worse than the problem in the first place, and sooner or later we have
> to live with it.
>

[OT]
It's the Let's Screw FPC Guys Life [LSFGL] warrior call of the Borland/CodeGear/Embracadero
employees ;)

L.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal [OT]

el_es
On 26/10/2011 09:44, Lukasz Sokol wrote:

> On 25/10/2011 12:52, Marco van de Voort wrote:
>
>> One can debate the syntax. I won't, since even while I have
>> similar reservations, that will lead to the usual Delphi sucks
>> debate, possible implementation of an-orphaned-at-birth FPC
>> specific syntax, and in the end the Delphi syntax always prevails,
>> leading to a lot of wasted time in discussion and implementation of
>> own inventions.
>>
>> That is such a common pattern on these lists, I'm thinking about an
>> acronym for it to save time :-) So sufficient to say, I think own
>> syntax inventions are worse than the problem in the first place,
>> and sooner or later we have to live with it.
>>
>
> [OT] It's the Let's Screw FPC Guys Life [LSFGL] warrior call of the
> Borland/CodeGear/Embracadero employees ;)
>
> L.
>

or Change Lazarus And QUit Emancipating language-Rules (CLAQUER).

:J
L.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Bernd Kreuss
In reply to this post by michael.vancanneyt
2011/10/25  <[hidden email]>:

>> targethread.queue(
>>  procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>>             begin
>>               targetobject.destinationprocedure(a,b,c);
>>             end;
>>
>> Note how common this looks compared to the original.
>
> One point is that you could do the above with a local (and named) procedure
> as well, and still have all the context. At the very least you would not be
> raping pascal's readability by putting a
> complete procedure declaration inside a code block.

How would you preserve the context without finding some place
somewhere (on the heap) to store the current values of a, b, and c?


The natural alternative to a closure if you don't have them in an OO
language is instead of passing a closure you pass an object (this
pattern is called Functor). The object contains the function along
with some state. Of course in a static language this involves a lot of
boiler plate to define the needed classes with their methods (one
class definition for every different closure) but once you have done
this you can use it like the closure in the above example and its
usage is totally readable:

targetthread.queue(TMyFunctor.Create(targetobject, a, b, c));
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Bernd Kreuss
In reply to this post by Marco van de Voort
2011/10/25 Marco van de Voort <[hidden email]>:
> Equivalent solution with anon functions:
>
> targethread.queue(
>   procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>              begin
>                targetobject.destinationprocedure(a,b,c);
>              end;

shouldn't this be

targethread.queue(
      procedure
             begin
               targetobject.destinationprocedure(a,b,c);
             end;

without any parameters since all these variables are captured from the
current scope into the closure? The other thread should not need to
know anything about them to call it.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Marco van de Voort
In our previous episode, Bernd said:

> > Equivalent solution with anon functions:
> >
> > targethread.queue(
> > ? procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
> > ? ? ? ? ? ? ?begin
> > ? ? ? ? ? ? ? ?targetobject.destinationprocedure(a,b,c);
> > ? ? ? ? ? ? ?end;
>
> shouldn't this be
>
> targethread.queue(
>       procedure
>              begin
>                targetobject.destinationprocedure(a,b,c);
>              end;
>
> without any parameters since all these variables are captured from the
> current scope into the closure? The other thread should not need to
> know anything about them to call it.

Afaik you are right. Delphi also allowed the other form, but I thought the
syntax would force immediately evaluation of the parameters (and thus only
the parameters be stored in case any of a ,b or c are expressions, not all
parts of the expressions).

But indeed then the other side also has to call it with parameters, and in
this example that defeats the purpose.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Alexander Shishkin
In reply to this post by Bernd Kreuss
05.11.2011 22:42, Bernd пишет:

> 2011/10/25<[hidden email]>:
>
>>> targethread.queue(
>>>   procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>>>              begin
>>>                targetobject.destinationprocedure(a,b,c);
>>>              end;
>>>
>>> Note how common this looks compared to the original.
>>
>> One point is that you could do the above with a local (and named) procedure
>> as well, and still have all the context. At the very least you would not be
>> raping pascal's readability by putting a
>> complete procedure declaration inside a code block.
>
> How would you preserve the context without finding some place
> somewhere (on the heap) to store the current values of a, b, and c?
>
>
> The natural alternative to a closure if you don't have them in an OO
> language is instead of passing a closure you pass an object (this
> pattern is called Functor). The object contains the function along
> with some state. Of course in a static language this involves a lot of
> boiler plate to define the needed classes with their methods (one
> class definition for every different closure) but once you have done
> this you can use it like the closure in the above example and its
> usage is totally readable:
>
> targetthread.queue(TMyFunctor.Create(targetobject, a, b, c));
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
>
But modern trend is to add closures into OO languages, because code
become more laconic.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Michael Van Canneyt
In reply to this post by Bernd Kreuss


On Sat, 5 Nov 2011, Bernd wrote:

> 2011/10/25  <[hidden email]>:
>
>>> targethread.queue(
>>>  procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>>>             begin
>>>               targetobject.destinationprocedure(a,b,c);
>>>             end;
>>>
>>> Note how common this looks compared to the original.
>>
>> One point is that you could do the above with a local (and named) procedure
>> as well, and still have all the context. At the very least you would not be
>> raping pascal's readability by putting a
>> complete procedure declaration inside a code block.
>
> How would you preserve the context without finding some place
> somewhere (on the heap) to store the current values of a, b, and c?
>
Procedure SomeOuter;

Var
   d,e,f : SomeType;

   Procedure SomeInner(targetobject:ttargetobject;a:integer;b:someobject;c:string)
  begin
      targetobject.destinationprocedure(a,b,c);
  end;

begin
   Targethread.queue(@SomeInner(aobject,d,e,f));
end;

No difference with 'closure', except more readable.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Alexander Shishkin
06.11.2011 1:46, Michael Van Canneyt пишет:

>
>
> On Sat, 5 Nov 2011, Bernd wrote:
>
>> 2011/10/25 <[hidden email]>:
>>
>>>> targethread.queue(
>>>>  procedure(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>>>>             begin
>>>>               targetobject.destinationprocedure(a,b,c);
>>>>             end;
>>>>
>>>> Note how common this looks compared to the original.
>>>
>>> One point is that you could do the above with a local (and named)
>>> procedure
>>> as well, and still have all the context. At the very least you would
>>> not be
>>> raping pascal's readability by putting a
>>> complete procedure declaration inside a code block.
>>
>> How would you preserve the context without finding some place
>> somewhere (on the heap) to store the current values of a, b, and c?
>>
>
> Procedure SomeOuter;
>
> Var
> d,e,f : SomeType;
>
> Procedure
> SomeInner(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>    begin
>      targetobject.destinationprocedure(a,b,c);
>    end;
>
> begin
> Targethread.queue(@SomeInner(aobject,d,e,f));
> end;
>
> No difference with 'closure', except more readable.
>
> Michael.
>
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Closures can be returned as a function result but nested procedure not
(more strictly, this can be complied but will not work because of
lifetime of nested procedure).
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Bernd Kreuss
In reply to this post by Michael Van Canneyt
2011/11/5 Michael Van Canneyt <[hidden email]>:

> Procedure SomeOuter;
>
> Var
>  d,e,f : SomeType;
>
>  Procedure
> SomeInner(targetobject:ttargetobject;a:integer;b:someobject;c:string)
>   begin
>      targetobject.destinationprocedure(a,b,c);
>   end;
>
> begin
>  Targethread.queue(@SomeInner(aobject,d,e,f));
> end;
>
> No difference with 'closure', except more readable.
>
> Michael.

I doubt that this would even compile. Also As I pointed out already
the example was wrong, the procedure does not have any arguments, the
closure must be "closed over" these variables.

and this:

begin
  Targethread.queue(@SomeInner);
end;

would compile but it would just pass the procedure variable. This is
not a closure. How is the other thread supposed to know the values of
the variables that existed only in the scope of SomeOuter?

A closure would be something like this:

Procedure SomeOuter;
Var
  d,e,f : SomeType;

  Procedure SomeInner
  begin
    targetobject.destinationprocedure(a,b,c);
  end;

begin
  Targethread.queue(SomeInner);
end;

The compiler would need to create an object on the heap containing the
procedure *along* with the needed variables a,b,c and then pass the
entire object. The receiving side could then call this method and it
would still have access to these variables.

A closure has enclosed variables from the surrounding scope where it
was created, hence the name 'closure'. You cannot do this with a
procedure variable alone, you need an object on the heap to contain
the enclosed variables. The Delphi compiler will behind the scenes
create a reference counted object with an 'invoke' method (the
procedure SomeInner) and all its needed variables.

It is basically a syntactic shortcut to explicitly defining this
class, and creating an instance of it.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Delphi's anonymous functions in Free Pascal

Michael Van Canneyt


On Sat, 5 Nov 2011, Bernd wrote:

>
> A closure has enclosed variables from the surrounding scope where it
> was created, hence the name 'closure'. You cannot do this with a
> procedure variable alone, you need an object on the heap to contain
> the enclosed variables. The Delphi compiler will behind the scenes
> create a reference counted object with an 'invoke' method (the
> procedure SomeInner) and all its needed variables.
>
> It is basically a syntactic shortcut to explicitly defining this
> class, and creating an instance of it.

I understand all that. That's not the issue.

I didn't mean to say that my example will work with the compiler NOW.
Obviously, it would need some extension of the compiler to implement closures.

The only thing I am arguing is that the syntax could have been more clear.
Definining a function inside code (or as an argument to another function)
is just not Pascal; It goes against everything Pascal stands for.

You could perfectly explicitly declare the closure function outside the code block
it is used in, as long as it is AFTER the variables it would need from the
outer scope. That is what I wanted to show with my snippet of code. Probably
you'd need some kind of extra keyword to distinguish it from 'normal' nested functions.

I am not against closure functionality, although I highly doubt it is *that*
useful as some people make it out to be. Even so, I use it in my Javascript
programming.

But in Pascal, I would like to see it implemented in a way that doesn't go
against Pascal philosophy. In that regard, I consider the way that
Borland/CodeGear/Embarcadero implemented it a monstrosity.
It simply hurts the eyes...

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
1234567