Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #30321 > unrolled thread

Re: Quotations revisited

Started byMark Wills <markwills1970@gmail.com>
First post2014-05-13 01:00 -0700
Last post2014-05-14 21:57 -0700
Articles 19 on this page of 39 — 12 participants

Back to article view | Back to comp.lang.forth

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Quotations revisited Mark Wills <markwills1970@gmail.com> - 2014-05-13 01:00 -0700
    Re: Quotations revisited Howerd <howerdo@yahoo.co.uk> - 2014-05-13 01:50 -0700
    Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-13 03:51 -0500
      Re: Quotations revisited Mark Wills <markwills1970@gmail.com> - 2014-05-13 02:25 -0700
        Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-13 05:08 -0500
          Re: Quotations revisited "Elizabeth D. Rather" <erather@forth.com> - 2014-05-13 07:46 -1000
          Re: Quotations revisited Paul Rubin <no.email@nospam.invalid> - 2014-05-13 11:03 -0700
            Re: Quotations revisited "Elizabeth D. Rather" <erather@forth.com> - 2014-05-13 08:12 -1000
            Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-13 13:22 -0500
    Re: Quotations revisited stephenXXX@mpeforth.com (Stephen Pelc) - 2014-05-13 09:15 +0000
      Re: Quotations revisited Mark Wills <markwills1970@gmail.com> - 2014-05-13 02:39 -0700
        Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-13 05:10 -0500
        Re: Quotations revisited stephenXXX@mpeforth.com (Stephen Pelc) - 2014-05-13 11:47 +0000
        Re: Quotations revisited Laurent Laborde <kerdezixe@gmail.com> - 2014-05-13 19:13 -0700
        Re: Quotations revisited Paul Rubin <no.email@nospam.invalid> - 2014-05-13 19:48 -0700
    Re: Quotations revisited Alexander Skobelev <al.skobelev@gmail.com> - 2014-05-13 03:43 -0700
      Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-13 12:35 +0000
        Re: Quotations revisited "Alex McDonald" <blog@rivadpm.com> - 2014-05-13 23:56 +0100
          Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-14 14:15 +0000
            Re: Quotations revisited "Alex McDonald" <blog@rivadpm.com> - 2014-05-14 20:48 -0400
              Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-15 14:16 +0000
        Re: Quotations revisited Alexander Skobelev <al.skobelev@gmail.com> - 2014-05-13 23:30 -0700
          Re: Quotations revisited Paul Rubin <no.email@nospam.invalid> - 2014-05-14 00:32 -0700
            Re: Quotations revisited Alexander Skobelev <al.skobelev@gmail.com> - 2014-05-14 02:02 -0700
              Re: Quotations revisited Paul Rubin <no.email@nospam.invalid> - 2014-05-14 08:02 -0700
                Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-14 15:10 +0000
            Re: Quotations revisited Mark Wills <markwills1970@gmail.com> - 2014-05-14 02:09 -0700
              Re: Quotations revisited Mark Wills <markwills1970@gmail.com> - 2014-05-14 02:14 -0700
                Re: Quotations revisited Mark Wills <markwills1970@gmail.com> - 2014-05-14 02:15 -0700
                  Re: Quotations revisited Paul Rubin <no.email@nospam.invalid> - 2014-05-14 08:22 -0700
              Re: Quotations revisited Coos Haak <chforth@hccnet.nl> - 2014-05-14 12:04 +0200
          Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2014-05-14 04:11 -0500
          Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-14 14:25 +0000
            Re: Quotations revisited Bernd Paysan <bernd.paysan@gmx.de> - 2014-05-14 20:04 +0200
              Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-15 13:50 +0000
                Re: Quotations revisited Bernd Paysan <bernd.paysan@gmx.de> - 2014-05-15 16:24 +0200
                  Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2014-05-15 14:40 +0000
                    Re: Quotations revisited Mark Wills <markwills1970@gmail.com> - 2014-05-15 10:18 -0700
            Re: Quotations revisited Alexander Skobelev <al.skobelev@gmail.com> - 2014-05-14 21:57 -0700

Page 2 of 2 — ← Prev page 1 [2]


#30398

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2014-05-15 14:16 +0000
Message-ID<2014May15.161651@mips.complang.tuwien.ac.at>
In reply to#30390
"Alex McDonald" <blog@rivadpm.com> writes:
>[' '] seems (to me anyhow) to visually better express what we're doing
>here with a quotation. It's the multi part equivalent of ['] <name> which
>also produces an xt, doesn't permit locals and has an identical lifespan.
>For example (contrived)
>
>.. ['] over ... 
>.. [' >r dup r> swap '] ...  
>
>would seem clearer than 
>.. [: >r dup r> swap ;] ...
>
>If ever closures were required, then [: ;] would seem to (visually again)
>be more consistent with an unnamed equivalent to a full : ; definition. 

Why would you want to make closures visually closer to a full colon
definition, but not quotations?  Full colon definitions are closer to
quotations than to closures: Closures can contain references to outer
locals, colon definitions and quotations cannot.

Also, if we ever get around to closures (or at least downward
funargs), I would prefer the same syntax as for quotations.  I don't
want to have to change the brackets just because I insert a reference
to an outer local, or because I delete the last such reference.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#30350

FromAlexander Skobelev <al.skobelev@gmail.com>
Date2014-05-13 23:30 -0700
Message-ID<e769760d-44c7-4558-a8bd-97b8ec17a26b@googlegroups.com>
In reply to#30333
On Tuesday, May 13, 2014 4:35:51 PM UTC+4, Anton Ertl wrote:
> Alexander Skobelev writes:
> >As far as I understand the basic problem with time of a quotation
> >execution is caused with complexity of handling local variables in that
> >case. There is no problem if a quotation doesn't use locals from the
> >enclosing definition.
> 
> Right.  That's why quotations don't support access not outer
> locals and thats why we call them quotations, not closures.

There are two use cases for quotation:
1. When you use a quotation during time extent of the parent definition;
2. When the parent definiton returns quotation's xt so it is going
   to be used later.

My point was why not to allow access to the parent's locals in the first
case and prohibit/not guarantee it in the second one?  In other words,
the quotation can refer the parent's locals, but the locals are valid
only during parent's time extent.

This doesn't turn quotation to closures, but IMO it can made them to be
much more practical. Well, of course if it can be implemented effectively.

[toc] | [prev] | [next] | [standalone]


#30352

FromPaul Rubin <no.email@nospam.invalid>
Date2014-05-14 00:32 -0700
Message-ID<7xwqdohl30.fsf@ruckus.brouhaha.com>
In reply to#30350
Alexander Skobelev <al.skobelev@gmail.com> writes:
> My point was why not to allow access to the parent's locals in the first
> case and prohibit/not guarantee it in the second one?  In other words,
> the quotation can refer the parent's locals, but the locals are valid
> only during parent's time extent.

This could be convenient but also sounds rather bug-prone.  Forth
programs I've looked at (of course the language allows other
possibilities) tend to use static memory allocation (VARIABLE etc.) or
else use the stack (counting locals as being on the stack).  So there
aren't likely to be too many dangling pointers.  Returning xt's that
might mess with already-exited stack frames sounds like asking for
trouble.  I don't have much view on the trade-off.

[toc] | [prev] | [next] | [standalone]


#30355

FromAlexander Skobelev <al.skobelev@gmail.com>
Date2014-05-14 02:02 -0700
Message-ID<8bd463e9-a91f-4674-ad69-d2abc18cc839@googlegroups.com>
In reply to#30352
On Wednesday, May 14, 2014 11:32:19 AM UTC+4, Paul Rubin wrote:
> Alexander Skobelev writes:
> 
> > My point was why not to allow access to the parent's locals in the
> > first case and prohibit/not guarantee it in the second one?  In
> > other words, the quotation can refer the parent's locals, but the
> > locals are valid only during parent's time extent.
> 
> This could be convenient but also sounds rather bug-prone.  Forth
> programs I've looked at (of course the language allows other
> possibilities) tend to use static memory allocation (VARIABLE etc.) or
> else use the stack (counting locals as being on the stack).  So there
> aren't likely to be too many dangling pointers.  Returning xt's that
> might mess with already-exited stack frames sounds like asking for
> trouble.  I don't have much view on the trade-off.

So, your point is that it is a bad thing to return a quotation that
refers to the outer locals, isn't it? So is mine.

[toc] | [prev] | [next] | [standalone]


#30373

FromPaul Rubin <no.email@nospam.invalid>
Date2014-05-14 08:02 -0700
Message-ID<7xsiocl7yf.fsf@ruckus.brouhaha.com>
In reply to#30355
Alexander Skobelev <al.skobelev@gmail.com> writes:
> So, your point is that it is a bad thing to return a quotation that
> refers to the outer locals, isn't it? So is mine.

Beyond "it's a bad idea" there could also be "the compiler should not
allow creating such a quotation" since once created, I don't see how to
detect it being returned.

[toc] | [prev] | [next] | [standalone]


#30374

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2014-05-14 15:10 +0000
Message-ID<2014May14.171010@mips.complang.tuwien.ac.at>
In reply to#30373
Paul Rubin <no.email@nospam.invalid> writes:
>Alexander Skobelev <al.skobelev@gmail.com> writes:
>> So, your point is that it is a bad thing to return a quotation that
>> refers to the outer locals, isn't it? So is mine.
>
>Beyond "it's a bad idea" there could also be "the compiler should not
>allow creating such a quotation" since once created, I don't see how to
>detect it being returned.

Forth allows to shoot yourself in the foot, and we generally don't
consider that possibility as a reason not to provide a way to shoot in
general.  Reasons for not supporting shooting include:

1) There is a better way to achieve the same result.

2) Shooting is too complex in implementation or in usage.

3) The benefits of shooting are not enough.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#30356

FromMark Wills <markwills1970@gmail.com>
Date2014-05-14 02:09 -0700
Message-ID<97bd7650-a9d6-47c2-a0b1-ab46f9c762a2@googlegroups.com>
In reply to#30352
On Wednesday, 14 May 2014 08:32:19 UTC+1, Paul Rubin  wrote:
> Alexander Skobelev <al.skobelev@gmail.com> writes:
> This could be convenient but also sounds rather bug-prone.  Forth
> programs I've looked at (of course the language allows other
> possibilities) tend to use static memory allocation (VARIABLE etc.) or
> else use the stack (counting locals as being on the stack).  So there
> aren't likely to be too many dangling pointers.  Returning xt's that
> might mess with already-exited stack frames sounds like asking for
> trouble.  I don't have much view on the trade-off.

Indeed. Alexander's proposal sounds like a sensible idea, but in practice, is it actually useful. Consider:

: bar ( -- n*2 )
   local_1 2* ;

: foo ( n -- n*2 )
   locals| local_1 |
   [: bar ;] execute ;

At the point at which the closure executes bar, foo is still in scope; it hasn't exited yet but allowing bar to access local_1 is tricky so say the least.

I don't see any problem with this, however:

: bar ( n -- n*2 )
   2* ;

: foo ( n -- n*2 ) 
   locals| local_1 |
   [: local_1 bar ;] execute ;

I.e using the data stack to pass data around. Radical, I know, but hey, that's just how I roll :-)

The key to implementing the second technique is to *not* suspend compilation of the outer defintion and begin a new nameless definition, as specified earlier in the thread, but to have the outer definition compile a branch around the closure. This allows the closure read write access to outer locals at this level:

: fred ( n -- z)
   locals| local_1 |
   [: local_1 do_thing to local_1 ;] ;

But do_thing would not have access to local_1.

By compiling a branch around the closure a lot of the problems evaporate. I don't see why that should be an issue. We're supposed to be using the data stack for passing data anyway!

[toc] | [prev] | [next] | [standalone]


#30358

FromMark Wills <markwills1970@gmail.com>
Date2014-05-14 02:14 -0700
Message-ID<ff9c1c58-fd50-47c8-965d-83f3bb60f360@googlegroups.com>
In reply to#30356
As an alternative, if it's not desired to compile a branch around the closure, then begin a new embedded definition, with it's own locals entry on the locals stack, and (radical) use the stack to pass the data into it:

: bar ( n -- n*2)
    2* ;

: foo ( n -- n*2)
  locals| local_1 |
  local_1 [: bar ;] ;

[toc] | [prev] | [next] | [standalone]


#30359

FromMark Wills <markwills1970@gmail.com>
Date2014-05-14 02:15 -0700
Message-ID<4111b722-d872-4226-b112-4f4d17f939c5@googlegroups.com>
In reply to#30358
Sorry. Make that:

: bar ( n -- n*2) 

    2* ; 

: foo ( n -- n*2) 
  locals| local_1 | 
  local_1 [: locals| my_local | my_local bar ;] ; 

Apologies.

[toc] | [prev] | [next] | [standalone]


#30375

FromPaul Rubin <no.email@nospam.invalid>
Date2014-05-14 08:22 -0700
Message-ID<7xoaz0l70a.fsf@ruckus.brouhaha.com>
In reply to#30359
Mark Wills <markwills1970@gmail.com> writes:
> Sorry. Make that:
> : bar ( n -- n*2)  2* ; 
> : foo ( n -- n*2) 
>   locals| local_1 | 
>   local_1 [: locals| my_local | my_local bar ;] ; 

I'm not sure what you're saying here.  If I understand the notation,
the actual stack effect of foo in that code is ( n -- n xt ) .
Then you could say
  
   : quux ( n -- n*2) foo execute ;

but that is sort of useless.

[toc] | [prev] | [next] | [standalone]


#30360

FromCoos Haak <chforth@hccnet.nl>
Date2014-05-14 12:04 +0200
Message-ID<1b0zpwf6eh317$.1i8g445qh7xc7$.dlg@40tude.net>
In reply to#30356
Op Wed, 14 May 2014 02:09:31 -0700 (PDT) schreef Mark Wills:

> On Wednesday, 14 May 2014 08:32:19 UTC+1, Paul Rubin  wrote:
>> Alexander Skobelev <al.skobelev@gmail.com> writes:
>> This could be convenient but also sounds rather bug-prone.  Forth
>> programs I've looked at (of course the language allows other
>> possibilities) tend to use static memory allocation (VARIABLE etc.) or
>> else use the stack (counting locals as being on the stack).  So there
>> aren't likely to be too many dangling pointers.  Returning xt's that
>> might mess with already-exited stack frames sounds like asking for
>> trouble.  I don't have much view on the trade-off.
> 
> Indeed. Alexander's proposal sounds like a sensible idea, but in practice, is it actually useful. Consider:
> 
>: bar ( -- n*2 )
>    local_1 2* ;
How can bar know in advance the name of this local?

> 
>: foo ( n -- n*2 )
>    locals| local_1 |
>    [: bar ;] execute ;
> 
> At the point at which the closure executes bar, foo is still in scope; it hasn't exited yet but allowing bar to access local_1 is tricky so say the least.
> 
> I don't see any problem with this, however:
> 
>: bar ( n -- n*2 )
>    2* ;
> 
>: foo ( n -- n*2 ) 
>    locals| local_1 |
>    [: local_1 bar ;] execute ;
> 
> I.e using the data stack to pass data around. Radical, I know, but hey, that's just how I roll :-)
local_1 in the parent is on the locals stack, and is known to the
quotation. So the quotation can refer to them and even have its own locals.

> 
> The key to implementing the second technique is to *not* suspend compilation of the outer defintion and begin a new nameless definition, as specified earlier in the thread, but to have the outer definition compile a branch around the closure. This allows the closure read write access to outer locals at this level:
> 
>: fred ( n -- z)
>    locals| local_1 |
>    [: local_1 do_thing to local_1 ;] ;
> 
> But do_thing would not have access to local_1.
No, but the quotation does.

-- 
Coos

CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html 

[toc] | [prev] | [next] | [standalone]


#30357

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2014-05-14 04:11 -0500
Message-ID<WJydnUmx2s-iru7OnZ2dnUVZ_sGdnZ2d@supernews.com>
In reply to#30350
Alexander Skobelev <al.skobelev@gmail.com> wrote:
> On Tuesday, May 13, 2014 4:35:51 PM UTC+4, Anton Ertl wrote:
>> Alexander Skobelev writes:
>> >As far as I understand the basic problem with time of a quotation
>> >execution is caused with complexity of handling local variables in that
>> >case. There is no problem if a quotation doesn't use locals from the
>> >enclosing definition.
>> 
>> Right.  That's why quotations don't support access not outer
>> locals and thats why we call them quotations, not closures.
> 
> There are two use cases for quotation:
> 1. When you use a quotation during time extent of the parent definition;
> 2. When the parent definiton returns quotation's xt so it is going
>   to be used later.
> 
> My point was why not to allow access to the parent's locals in the first
> case and prohibit/not guarantee it in the second one?  In other words,
> the quotation can refer the parent's locals, but the locals are valid
> only during parent's time extent.

It would be significantly more complex than simple quotations.

It may require the parent's locals to be spilled (maybe from
registers) into a memory buffer; this requires changes to the
implementation of locals.

The quotation may need its own locals.  So, locals in a quotation can
come from two places.  Are the locals copies of the parent's locals,
or references to them?  Can you change the values in the parent's
locals?  Eurgh.  Better not to go there.

I'm not convinced that the additional power would really be useful.
We can easily pass everything we need on the stack.  The good examples
of quotations I've seen don't need access to the parent's locals.

In contrast to all this, quotations ATM are a simple addition.

Andrew.

[toc] | [prev] | [next] | [standalone]


#30371

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2014-05-14 14:25 +0000
Message-ID<2014May14.162515@mips.complang.tuwien.ac.at>
In reply to#30350
Alexander Skobelev <al.skobelev@gmail.com> writes:
>On Tuesday, May 13, 2014 4:35:51 PM UTC+4, Anton Ertl wrote:
>> Alexander Skobelev writes:
>> >As far as I understand the basic problem with time of a quotation
>> >execution is caused with complexity of handling local variables in that
>> >case. There is no problem if a quotation doesn't use locals from the
>> >enclosing definition.
>> 
>> Right.  That's why quotations don't support access not outer
>> locals and thats why we call them quotations, not closures.
>
>There are two use cases for quotation:
>1. When you use a quotation during time extent of the parent definition;
>2. When the parent definiton returns quotation's xt so it is going
>   to be used later.
>
>My point was why not to allow access to the parent's locals in the first
>case and prohibit/not guarantee it in the second one?

Supporting the access to outer locals complicates the implementation
even if the lifetime of the closure is not a problem; you have to
implement things like static links and accessing locals through these
static links that you don't have to do with simple quotations.  It is
unclear whether the benefit is worth the cost.

For now I am happy if many systems implement plain quotations.  If
some implementor actually does a generally working implementation of
downward funargs, we can see whether they are useful enough to justify
their implementation cost.

>This doesn't turn quotation to closures,

While they are not full closures, if you consider the meaning of
"closure", they are closures:
<http://en.wikipedia.org/wiki/Closure_(computer_science)#History_and_etymology>
says:

|[...] the term closure refers to a lambda expression whose open
|bindings (free variables) have been closed by (or bound in) the
|lexical environment, resulting in a closed expression, or closure.

However, earlier the article says:

|A closure - unlike a plain function pointer - allows a function to access
|those non-local variables even when invoked outside its immediate
|lexical scope.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#30380

FromBernd Paysan <bernd.paysan@gmx.de>
Date2014-05-14 20:04 +0200
Message-ID<ll0b84$v95$1@online.de>
In reply to#30371
Anton Ertl wrote:

> For now I am happy if many systems implement plain quotations.  If
> some implementor actually does a generally working implementation of
> downward funargs, we can see whether they are useful enough to justify
> their implementation cost.

They'll probably have the impact that you can't do nested functions 
(downward funargs) which outlive their skope.  Downward funargs require some 
sort of trampoline or a similar dynamic structure, and you wouldn't 
implement that on the heap, but inside the corresponding locals frame.  This 
is destroyed when the creating function exits; the quotation isn't.

A case for quotations used in that way is when you want callbacks in an 
asynchronous network protocol.

Variable last-time
: sync-time ( destination -- ) ticks last-time ! req-ticks
  [: ticks last-time @ - 2/ + set-time ;] is reply-ticks ;

You want this sort of stuff be written close together, as it has a logical 
flow, but it's outliving sync-time.

What you can have is quotations and closures share the same syntax.  Both 
can outlive their environment, and the difference is just that the closure 
can access the locals:

: sync-time ( destination -- )  ticks { last-time } req-ticks
  [: ticks last-time - 2/ + set-time ;] is reply-ticks ;

would work with closures.  It for sure would not work with downward funargs, 
unless you add a "wait-for-reply" synchronization inside the function.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

[toc] | [prev] | [next] | [standalone]


#30397

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2014-05-15 13:50 +0000
Message-ID<2014May15.155029@mips.complang.tuwien.ac.at>
In reply to#30380
Bernd Paysan <bernd.paysan@gmx.de> writes:
>Anton Ertl wrote:
>
>> For now I am happy if many systems implement plain quotations.  If
>> some implementor actually does a generally working implementation of
>> downward funargs, we can see whether they are useful enough to justify
>> their implementation cost.
>
>They'll probably have the impact that you can't do nested functions 
>(downward funargs) which outlive their skope. 

Sure.  If they outlive their scope, they would not be downward, but
upward.  What are you getting at?

> Downward funargs require some 
>sort of trampoline or a similar dynamic structure, and you wouldn't 
>implement that on the heap, but inside the corresponding locals frame.  This 
>is destroyed when the creating function exits; the quotation isn't.

Yes, that's how one would implement them.

>A case for quotations used in that way is when you want callbacks in an 
>asynchronous network protocol.
>
>Variable last-time
>: sync-time ( destination -- ) ticks last-time ! req-ticks
>  [: ticks last-time @ - 2/ + set-time ;] is reply-ticks ;
>
>You want this sort of stuff be written close together, as it has a logical 
>flow, but it's outliving sync-time.
>
>What you can have is quotations and closures share the same syntax.  Both 
>can outlive their environment, and the difference is just that the closure 
>can access the locals:
>
>: sync-time ( destination -- )  ticks { last-time } req-ticks
>  [: ticks last-time - 2/ + set-time ;] is reply-ticks ;
>
>would work with closures.  It for sure would not work with downward funargs, 
>unless you add a "wait-for-reply" synchronization inside the function.

Yes, that's an example of full closures (although the rest of the
example is not really clear to me).  And yes, the difference between
quotations and (restricted or full) quotations is in whether outer
locals are used in the quotation/closure; and the difference between
downward funargs and full closures is wheter the xt is used after the
definition that contained the locals has returned.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#30399

FromBernd Paysan <bernd.paysan@gmx.de>
Date2014-05-15 16:24 +0200
Message-ID<ll2in7$r0l$1@online.de>
In reply to#30397
Anton Ertl wrote:

> Bernd Paysan <bernd.paysan@gmx.de> writes:
>>Anton Ertl wrote:
>>
>>> For now I am happy if many systems implement plain quotations.  If
>>> some implementor actually does a generally working implementation of
>>> downward funargs, we can see whether they are useful enough to justify
>>> their implementation cost.
>>
>>They'll probably have the impact that you can't do nested functions
>>(downward funargs) which outlive their skope.
> 
> Sure.  If they outlive their scope, they would not be downward, but
> upward.  What are you getting at?

Just returning a quotation from the enclosing function:

: foo [: ." bar" ;] ;

foo execute should print "bar".  If the generated xt is a trampoline living 
in a local of foo, that won't work.

> Yes, that's an example of full closures (although the rest of the
> example is not really clear to me).

The rest of the example was using a global variable and a normal quotation.  
What apparently isn't clear to you is that quotations outlive the scope they 
are defined in, because they don't refer to anything in that scope.  And 
that this is an important property.

-- 
Bernd Paysan
"If you want it done right, you have to do it yourself"
http://bernd-paysan.de/

[toc] | [prev] | [next] | [standalone]


#30401

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2014-05-15 14:40 +0000
Message-ID<2014May15.164020@mips.complang.tuwien.ac.at>
In reply to#30399
Bernd Paysan <bernd.paysan@gmx.de> writes:
>Anton Ertl wrote:
>
>> Bernd Paysan <bernd.paysan@gmx.de> writes:
>>>They'll probably have the impact that you can't do nested functions
>>>(downward funargs) which outlive their skope.
>> 
>> Sure.  If they outlive their scope, they would not be downward, but
>> upward.  What are you getting at?
>
>Just returning a quotation from the enclosing function:
>
>: foo [: ." bar" ;] ;
>
>foo execute should print "bar".  If the generated xt is a trampoline living 
>in a local of foo, that won't work.
>
>> Yes, that's an example of full closures (although the rest of the
>> example is not really clear to me).
>
>The rest of the example was using a global variable and a normal quotation.  
>What apparently isn't clear to you is that quotations outlive the scope they 
>are defined in, because they don't refer to anything in that scope.  And 
>that this is an important property.

So what you meant above is: Implementing downward funargs will
probably have the impact that you can't do *quotations* which outlive
the containing definition.

I see two solutions for that:

1) The compiler checks whether the inner definition references
outer locals, and only generates a trampoline if it does.

2) We have different syntax for inner definitions whose xts live
beyond the end of the enclosing definitions, and those that do not.
While I would prefer not to have to change the brackets when I insert
or delete an outer local, xt lifetime is a property that the compiler
cannot reliably check itself, and that is relevant when we decide
whether we want to use an outer local in an inner definition or not.

- anton
-- 
M. Anton Ertl  http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
     New standard: http://www.forth200x.org/forth200x.html
   EuroForth 2014: http://www.euroforth.org/ef14/

[toc] | [prev] | [next] | [standalone]


#30403

FromMark Wills <markwills1970@gmail.com>
Date2014-05-15 10:18 -0700
Message-ID<970021c4-eb1d-4b5a-8e27-b7d0f0c8abe0@googlegroups.com>
In reply to#30401
It's an abomination.

[toc] | [prev] | [next] | [standalone]


#30392

FromAlexander Skobelev <al.skobelev@gmail.com>
Date2014-05-14 21:57 -0700
Message-ID<1d23026f-b667-4152-888a-6c56cc577afb@googlegroups.com>
In reply to#30371
On Wednesday, May 14, 2014 6:25:15 PM UTC+4, Anton Ertl wrote: >
Alexander Skobelev writes:
> 
> >On Tuesday, May 13, 2014 4:35:51 PM UTC+4, Anton Ertl wrote:
> >> Alexander Skobelev writes:
> >> >As far as I understand the basic problem with time of a quotation
> >> >execution is caused with complexity of handling local variables in
> >> >that case. There is no problem if a quotation doesn't use locals
> >> >from the enclosing definition.
> >> 
> >> Right.  That's why quotations don't support access not outer locals
> >> and thats why we call them quotations, not closures.
> >
> >There are two use cases for quotation:
> >1. When you use a quotation during time extent of the parent
> >   definition;
> >2. When the parent definiton returns quotation's xt so it is going
> >   to be used later.
> >
> >My point was why not to allow access to the parent's locals in the
> >first case and prohibit/not guarantee it in the second one?
> 
> Supporting the access to outer locals complicates the implementation
> even if the lifetime of the closure is not a problem; you have to
> implement things like static links and accessing locals through these
> static links that you don't have to do with simple quotations.  It is
> unclear whether the benefit is worth the cost.
>

Well, on the whole I agree - it is unclear how to implement it
effectively and how much the benefit. The only example I have is to
implement a cleaner notation for the short-circuit logical operators,
something like that:
https://groups.google.com/d/msg/comp.lang.forth/gQyOKtQ_kLQ/CP9oROkvpE8J

But I can not say if there are many other use cases besides that.

> For now I am happy if many systems implement plain quotations.  If
> some implementor actually does a generally working implementation of
> downward funargs, we can see whether they are useful enough to justify
> their implementation cost.
> 
> 
> >This doesn't turn quotation to closures,
> 
> While they are not full closures, if you consider the meaning of
> "closure", they are closures:
> 
> <http://en.wikipedia.org/wiki/Closure_(computer_science)#History_and_etymology>
> says:
> 
> |[...] the term closure refers to a lambda expression whose open
> |bindings (free variables) have been closed by (or bound in) the
> |lexical environment, resulting in a closed expression, or closure.
> 
> However, earlier the article says:
> 
> |A closure - unlike a plain function pointer - allows a function to
> |access those non-local variables even when invoked outside its
> |immediate lexical scope.
> 

Let's call them subclosures then. :)

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.forth


csiph-web