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


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

Re: Quotations revisited

Started byMichael L Gassanenko <m_l_g3@yahoo.com>
First post2013-03-13 01:54 -0700
Last post2013-03-14 23:09 -0700
Articles 19 — 8 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 Michael L Gassanenko <m_l_g3@yahoo.com> - 2013-03-13 01:54 -0700
    Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2013-03-13 04:21 -0500
      Re: Quotations revisited Michael L Gassanenko <m_l_g3@yahoo.com> - 2013-03-13 03:36 -0700
        Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2013-03-13 07:14 -0500
      Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2013-03-13 11:55 +0000
        Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2013-03-13 07:20 -0500
          Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2013-03-13 14:36 +0000
        Re: Quotations revisited albert@spenarnc.xs4all.nl (Albert van der Horst) - 2013-03-13 13:01 +0000
          Re: Quotations revisited anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2013-03-13 14:21 +0000
    Re: Quotations revisited David Kuehling <dvdkhlng@gmx.de> - 2013-03-13 10:33 +0100
      Re: Quotations revisited Andrew Haley <andrew29@littlepinkcloud.invalid> - 2013-03-13 04:41 -0500
        Re: Quotations revisited David Kuehling <dvdkhlng@gmx.de> - 2013-03-13 11:44 +0100
    Re: Quotations revisited Lars Brinkhoff <lars.spam@nocrew.org> - 2013-03-13 11:23 +0100
    Re: Quotations revisited Bernd Paysan <bernd.paysan@gmx.de> - 2013-03-13 12:52 +0100
      Re: Quotations revisited Lars Brinkhoff <lars.spam@nocrew.org> - 2013-03-14 09:47 +0100
        Re: Quotations revisited Sieur de Bienville <morrimichael@gmail.com> - 2013-03-14 10:45 -0700
          Re: Quotations revisited Lars Brinkhoff <lars.spam@nocrew.org> - 2013-03-14 19:41 +0100
            Re: Quotations revisited Sieur de Bienville <morrimichael@gmail.com> - 2013-03-14 12:58 -0700
      Re: Quotations revisited Michael L Gassanenko <m_l_g3@yahoo.com> - 2013-03-14 23:09 -0700

#20615 — Re: Quotations revisited

FromMichael L Gassanenko <m_l_g3@yahoo.com>
Date2013-03-13 01:54 -0700
SubjectRe: Quotations revisited
Message-ID<771c3aa0-0b95-48af-b0fb-c6ae6269a266@googlegroups.com>
1. We need to decide what RECURSE means for quotations:
call the quotation or call the enclosing named definition?

2. Closures (about which we sort of agreed to speak only 
theoretically), resemble CREATE-DOES> definitions in the 
same way as quotations resemble colon definitions.
Quotations may reside in ROM; closures will need some RAM.

2.1. Closures assume run-time creation of execution tokens.

2.2. As to where the memory for data is allocated,
I think, the best answer is: let the user choose, it may be
ALLOCATE or HERE SWAP ALLOT .

2.3. To create a closure, we will need to: allocate an area of
memory with some room for the "code field"; fill the "data field"
with the data; bind the closure with the desired behavior (writing
to the "code field"); create an xt for that "code field".

So we get something like:
: foo
   ...
   {{ a b }} HERE SWAP ALLOT [DOES> DUP a SWAP b + ;]
   ...
;


On Monday, July 16, 2012 4:01:30 PM UTC+4, Stephen Pelc wrote:
> A revised summary, 16 July 2012
> 
> 
> 
> Given the increasing popularity of talking about "quotations" and
> 
> "closures", it would be useful to have a specification to talk
> 
> about.
> 
> 
> 
> Andrew provided an implementation of quotations that will only
> 
> make sense to people with carnal knowledge of SwiftForth. Bernd
> 
> provided an implementation that will only make sense to people
> 
> with carnal knowledge of VFX Forth.
> 
> 
> 
> I see that that quotations can provide pretty notations at little
> 
> cost. On closures I remain unconvinced, but have not seen a Forth
> 
> implementation or notation.
> 
> 
> 
> I have seen two or three sets of requirements dicussed, but for
> 
> those of us who distinguish between hand-waving, source code and
> 
> specifications, would an interested party be prepared to specify
> 
> what is required? It seems that the interested party is going to
> 
> have to be me.
> 
> 
> 
> Stephen
> 
> P.S. "Go read this in WikiPedia" is inadequate.
> 
> P.P.S. "Read the source, Luke" is inadequate.
> 
> 
> 
> The following notes on quotations and closures incorporate
> 
> material from several people, including Andrew Haley, Marcel
> 
> Hendrix, Bernd Paysan, and Elizabeth Rather. If you have been left
> 
> out and want acknowledgement, please let me know.
> 
> 
> 
> Quotations
> 
> ==========
> 
> 
> 
> Discussion
> 
> ----------
> 
> The essence of quotations is to provide nested colon definitions,
> 
> in which the inside definition(s) are namess. The expression
> 
> 
> 
> : foo ... [: some words ;] ... ;
> 
> 
> 
> is equivalent to
> 
> 
> 
> :noname some words ; Constant #temp#
> 
> : foo ... #temp# ... ;
> 
> 
> 
> If quotations are to have the same privileges as words defined
> 
> with : and :NONAME they should be able to use local variables and
> 
> use RECURSE. Quotations should not be able to access the locals of
> 
> the outer word because we have no knowledge of when the quotation
> 
> is executed and hence whether outer locals are still alive.
> 
> 
> 
> One example use of quotations is to provide a solution to the use
> 
> of CATCH in a form close to other languages' TRY ... EXCEPT
> 
> blocks.
> 
> 
> 
> : foo
> 
>   ...
> 
>   [: fee fi fo fum ;] catch if ... then
> 
>   ...
> 
> ;
> 
> 
> 
> 
> 
> Specification
> 
> -------------
> 
> 
> 
> [: ( -- nested-sys )
> 
> Compilation: suspends compiling to the current definition, starts a
> 
> new
> 
> nested definition, and compilation continues with this nested
> 
> definition. Outer locals are not visible in the nested definition.
> 
> RECURSE applies to the nested definition.
> 
> 
> 
> ;] ( nested-sys -- )
> 
> Compilation: Ends the current nested definition, and resumes
> 
> compilation
> 
> to the previous current definition. It appends the following run-time
> 
> to
> 
> the current definition:
> 
> 
> 
> run-time: ( -- xt )
> 
> xt is the execution token to execute the nested definition.
> 
> 
> 
> 
> 
> Closures
> 
> ========
> 
> 
> 
> Discussion
> 
> ----------
> 
> I have chosen to distinguish nameless words intended as closures
> 
> by using [[: ... ;]] to define them. I have also chosen to
> 
> distinguish the required persistence of data by declaring it using
> 
> {{ ... }} which is syntactically like { ... } locals but has very
> 
> different persistence requirements.
> 
> 
> 
> A quotation can have its own locals, but it can't access the
> 
> locals of the outer word. We have Forth compilers which could
> 
> access locals from the outer scope, but not as a real closure or
> 
> correctly nested frame.
> 
> 
> 
> Closures have different requirements for scope (visibility) and for
> 
> data persistence.
> 
> 
> 
> : foo { a b -- } ... [: ... a b ... ;] execute ;
> 
> 
> 
> Here, a and b referenced in the boy-closure are offsets into the
> 
> locals
> 
> stack which are identical to code generated within foo, and when
> 
> executed from within foo directly, they access the same locals.  These
> 
> are not real closures, not even correctly nested frames.
> 
> 
> 
> Algol 60 (with its famous man-or-boy-test) has nested frames, which
> 
> requires that the xt carries a reference to the scope it was created
> 
> in,
> 
> i.e. [: would produce an xt at run-time, which sets the frame for
> 
> access
> 
> to outer locals, and then runs the code defined within the [: ;]
> 
> boundaries.  Algol-like compilers usually solve that by adding an
> 
> implicit paramenter to the nested function, which points to the
> 
> environment, and the compiler knows to insert the proper parameter,
> 
> but
> 
> in Forth, we can't do this.
> 
> 
> 
> Full closures go even further, they make sure that the environment is
> 
> active as long as the closure (the xt returned after ;]) is alive.
> 
> This
> 
> means that the locals would be allocated on the heap, an some sort of
> 
> garbage collection is necessary to free unused memory.
> 
> 
> 
> : foo {{ a b -- }} ... [[: ... a b ... ;]] execute ;
> 
> 
> 
> Knuth's Man-Or-Boy test creates a quotation that *modifies* the
> 
> outer locals and then recursively calls its host, accessing outer
> 
> locals that one might have expected to long gone out of
> 
> scope. It forces the quotation implementation to store copies of
> 
> *all imaginable* outer locals and make them permanently available.
> 
> 
> 
> This can get even more interesting when a closure is required to
> 
> remember not only locals, but things like BASE, >IN, arbitrary
> 
> variables, file handles, buffer addresses, etc..(*)
> 
> 
> 
> Maybe we first need a convincing example of the usefulness of
> 
> quotations and closures -- (*) would certainly be useful, but
> 
> the cost seems to be a little excessive?
> 
> 
> 
> Aside from looking obscure and clever and satisfying the "[x]
> 
> can do it, why not Forth?" test, what on earth does this buy you?
> 
> 
> 
> What does a closure achieve that cannot be achieved by other
> 
> scoping and persistence mechanisms such as a class and an object
> 
> with heap allocation?
> 
> 
> 
> Specification
> 
> -------------
> 
> 
> 
> TBD
> 
> 
> 
> 
> 
> -- 
> 
> Stephen Pelc, stephenXXX@mpeforth.com
> 
> MicroProcessor Engineering Ltd - More Real, Less Time
> 
> 133 Hill Lane, Southampton SO15 5AF, England
> 
> tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691
> 
> web: http://www.mpeforth.com - free VFX Forth downloads

[toc] | [next] | [standalone]


#20616

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2013-03-13 04:21 -0500
Message-ID<-qidnav9eMy22N3MnZ2dnUVZ_qCdnZ2d@supernews.com>
In reply to#20615
Michael L Gassanenko <m_l_g3@yahoo.com> wrote:
> 1. We need to decide what RECURSE means for quotations:
> call the quotation or call the enclosing named definition?

The only reasonable solution is to call the quotation.  It's more
useful and the enclosing named definition may have been exited.

Andrew.

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


#20624

FromMichael L Gassanenko <m_l_g3@yahoo.com>
Date2013-03-13 03:36 -0700
Message-ID<13df55a4-8e6c-467e-8ddb-d996b9b1545a@googlegroups.com>
In reply to#20616
On Wednesday, March 13, 2013 1:21:47 PM UTC+4, Andrew Haley wrote:
> Michael L Gassanenko wrote:
> 
> > 1. We need to decide what RECURSE means for quotations:
> > call the quotation or call the enclosing named definition?
> 
> The only reasonable solution is to call the quotation.  It's more
> useful

in fact, both are useful. But the named definition may be 
made visible via REVEAL (common but non-standard):

: foo [ reveal ] depth if . foo then ;
: bar [ reveal ] [: bar ;] ;

> and the enclosing named definition may have been exited.

No problem with being exited: RECURSE is just a call, 
the quotation could call that definition using 
EXECUTE , DEFER or the REVEAL trick.

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


#20631

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2013-03-13 07:14 -0500
Message-ID<38-dndZbQNEp8N3MnZ2dnUVZ_qmdnZ2d@supernews.com>
In reply to#20624
Michael L Gassanenko <m_l_g3@yahoo.com> wrote:
> On Wednesday, March 13, 2013 1:21:47 PM UTC+4, Andrew Haley wrote:
>> Michael L Gassanenko wrote:
>> 
>> > 1. We need to decide what RECURSE means for quotations:
>> > call the quotation or call the enclosing named definition?
>> 
>> The only reasonable solution is to call the quotation.  It's more
>> useful
> 
> in fact, both are useful. But the named definition may be 
> made visible via REVEAL (common but non-standard):
> 
> : foo [ reveal ] depth if . foo then ;
> : bar [ reveal ] [: bar ;] ;

And it also may be made visible in a perfectly standard way by

defer bar
:noname [: bar ;] ;  is bar

Therefore it is of no use for RECURSE to call the enclosing named
definition.  The only reasonable solution is to call the quotation.

Andrew.

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


#20628

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2013-03-13 11:55 +0000
Message-ID<2013Mar13.125532@mips.complang.tuwien.ac.at>
In reply to#20616
Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>Michael L Gassanenko <m_l_g3@yahoo.com> wrote:
>> 1. We need to decide what RECURSE means for quotations:
>> call the quotation or call the enclosing named definition?
>
>The only reasonable solution is to call the quotation.  It's more
>useful and the enclosing named definition may have been exited.

It does not matter whether the enclosing definition has been exited.
A recursion is just a call, and calling a colon definition that is not
active is a common case.

That being said, I also agree that RECURSE should be to the quotation
that is innermost when the RECURSE is encountered.  That's probably
more often needed, and the outermost definition is typically named and
can be called through its name in sufficiently capable Forth systems.  E.g.:

: foo recursive
  ...
  [: ...
     recurse \ call the quotation
     foo     \ call FOO
  ;]
  ...
;

- 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 2013: http://www.euroforth.org/ef13/

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


#20632

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2013-03-13 07:20 -0500
Message-ID<krWdnd1KJYaG8t3MnZ2dnUVZ_hydnZ2d@supernews.com>
In reply to#20628
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
> Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>>Michael L Gassanenko <m_l_g3@yahoo.com> wrote:
>>> 1. We need to decide what RECURSE means for quotations:
>>> call the quotation or call the enclosing named definition?
>>
>>The only reasonable solution is to call the quotation.  It's more
>>useful and the enclosing named definition may have been exited.
> 
> It does not matter whether the enclosing definition has been exited.
> A recursion is just a call, and calling a colon definition that is not
> active is a common case.

A recursion is not just a call: it's a call from a definition to
itself, either directly or indirectly.  It makes no sense to use
RECURSE for non-recursive calls.

Andrew.

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


#20637

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2013-03-13 14:36 +0000
Message-ID<2013Mar13.153644@mips.complang.tuwien.ac.at>
In reply to#20632
Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
>> Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>>>The only reasonable solution is to call the quotation.  It's more
>>>useful and the enclosing named definition may have been exited.
>> 
>> It does not matter whether the enclosing definition has been exited.
>> A recursion is just a call, and calling a colon definition that is not
>> active is a common case.
>
>A recursion is not just a call: it's a call from a definition to
>itself, either directly or indirectly.  It makes no sense to use
>RECURSE for non-recursive calls.

That's a good point, but does not have anything to do with what I
wrote: it still does not matter whether the enclosing definition has
been exited.

- 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 2013: http://www.euroforth.org/ef13/

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


#20633

Fromalbert@spenarnc.xs4all.nl (Albert van der Horst)
Date2013-03-13 13:01 +0000
Message-ID<514078a9$0$6084$e4fe514c@dreader36.news.xs4all.nl>
In reply to#20628
In article <2013Mar13.125532@mips.complang.tuwien.ac.at>,
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
>Andrew Haley <andrew29@littlepinkcloud.invalid> writes:
>>Michael L Gassanenko <m_l_g3@yahoo.com> wrote:
>>> 1. We need to decide what RECURSE means for quotations:
>>> call the quotation or call the enclosing named definition?
>>
>>The only reasonable solution is to call the quotation.  It's more
>>useful and the enclosing named definition may have been exited.
>
>It does not matter whether the enclosing definition has been exited.
>A recursion is just a call, and calling a colon definition that is not
>active is a common case.

This is ridiculous. A reasonable programming language calls a procedure
by its name. Being minimalistic Forth has added RECURSE to work around
limitations imposed by its primitiveness.
When adding advanced features like quotations the first priority
is getting rid of RECURSE. Then the problem goes away.

>- anton
Groetjes Albert
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

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


#20636

Fromanton@mips.complang.tuwien.ac.at (Anton Ertl)
Date2013-03-13 14:21 +0000
Message-ID<2013Mar13.152123@mips.complang.tuwien.ac.at>
In reply to#20633
albert@spenarnc.xs4all.nl (Albert van der Horst) writes:
>This is ridiculous. A reasonable programming language calls a procedure
>by its name.

Many programming languages have unnamed procedures (Forth among them)
that obviously cannot be called by their names.  Forth gives us a way
to use recursion even for such procedures: RECURSE.  Other languages
either require naming the procedures or resorting to rather esoteric
stuff like the Y-combinator.

>When adding advanced features like quotations the first priority
>is getting rid of RECURSE.

Given that quotations don't have a name, getting rid of RECURSE is not
just not first priority, it would diminish the language.

> Then the problem goes away.

What problem?

- 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 2013: http://www.euroforth.org/ef13/

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


#20617

FromDavid Kuehling <dvdkhlng@gmx.de>
Date2013-03-13 10:33 +0100
Message-ID<874ngf8x0a.fsf@mosquito.pool>
In reply to#20615
>>>>> "Michael" == Michael L Gassanenko <m_l_g3@yahoo.com> writes:

> 1. We need to decide what RECURSE means for quotations: call the
> quotation or call the enclosing named definition?

Maybe just declare use of RECURSE as an ambiguous condition?

> 2. Closures (about which we sort of agreed to speak only
> theoretically), resemble CREATE-DOES> definitions in the same way as
> quotations resemble colon definitions.  Quotations may reside in ROM;
> closures will need some RAM.

This idea is brilliant.  I didn't think Forth could capture the notion
of quotations, given its low-level nature, but your approach would
nicely match Forth concepts.

I don't think that quotations' data necessarily need to reside in RAM.
There are scenarios where you just want to have constant data
(e.g. compiled via CREATE an , ) associated with a closure.

> 2.1. Closures assume run-time creation of execution tokens.

Doesn't this creation of execution tokens create a memory leak?  

> 2.2. As to where the memory for data is allocated, I think, the best
> answer is: let the user choose, it may be ALLOCATE or HERE SWAP ALLOT
> .

> 2.3. To create a closure, we will need to: allocate an area of memory
> with some room for the "code field"; fill the "data field" with the
> data; bind the closure with the desired behavior (writing to the "code
> field"); create an xt for that "code field".

In GCC this would be called a "trampoline", i.e. something like

: make-trampoline ( xt1 a-addr -- xt2 )
  :NONAME POSTPONE LITERAL COMPILE, POSTPONE ;

created for every execution token.  But how to track that memory?  We'd
have to provide a new word for freeing the trampoline.

FORGET-[DOES>;]  ( xt -- )  

which cannot be implemented in ANS Forth for a definition of
make-trampoline relying on :NONAME .

cheers,

David
-- 
GnuPG public key: http://dvdkhlng.users.sourceforge.net/dk.gpg
Fingerprint: B17A DC95 D293 657B 4205  D016 7DEF 5323 C174 7D40

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


#20619

FromAndrew Haley <andrew29@littlepinkcloud.invalid>
Date2013-03-13 04:41 -0500
Message-ID<t6OdnTH_R9Uz1N3MnZ2dnUVZ_oKdnZ2d@supernews.com>
In reply to#20617
David Kuehling <dvdkhlng@gmx.de> wrote:
>>>>>> "Michael" == Michael L Gassanenko <m_l_g3@yahoo.com> writes:
> 
>> 1. We need to decide what RECURSE means for quotations: call the
>> quotation or call the enclosing named definition?
> 
> Maybe just declare use of RECURSE as an ambiguous condition?

I don't think so.  RECURSE is the only way for a qutation to call
itself, and in practice it's not difficult to get it to work.

>> 2.1. Closures assume run-time creation of execution tokens.
> 
> Doesn't this creation of execution tokens create a memory leak?  

You'd have to FREE them yourself.  There's no good reason not to allow
the user to redefine both FREE and ALLOCATE words for closures.  An
alternative would be to reference count them.  The onus would then be
on the user to use DUP-CLOSURE and EXECUTE-CLOSURE rather than DUP and
EXECUTE.  This would be a pain, but perhaps better than manual FREEing.

Andrew.

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


#20625

FromDavid Kuehling <dvdkhlng@gmx.de>
Date2013-03-13 11:44 +0100
Message-ID<87zjy77f4p.fsf@mosquito.pool>
In reply to#20619
>>>>> "Andrew" == Andrew Haley <andrew29@littlepinkcloud.invalid> writes:

> David Kuehling <dvdkhlng@gmx.de> wrote:

>>> 2.1. Closures assume run-time creation of execution tokens.
>> 
>> Doesn't this creation of execution tokens create a memory leak?

> You'd have to FREE them yourself.  There's no good reason not to allow
> the user to redefine both FREE and ALLOCATE words for closures.  An
> alternative would be to reference count them.  The onus would then be
> on the user to use DUP-CLOSURE and EXECUTE-CLOSURE rather than DUP and
> EXECUTE.  This would be a pain, but perhaps better than manual
> FREEing.

I won't feel comfortable forcing tranpolines to reside on the heap.  On
some architectures/systems they may need to be placed in different
executable memory regions, that's why the call for a new word to free
them.

As trampolines are small in size, providing a word to create a copy of a
trampoline may be the better alternative to doing reference-counting.  

cheer,

David
-- 
GnuPG public key: http://dvdkhlng.users.sourceforge.net/dk.gpg
Fingerprint: B17A DC95 D293 657B 4205  D016 7DEF 5323 C174 7D40

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


#20621

FromLars Brinkhoff <lars.spam@nocrew.org>
Date2013-03-13 11:23 +0100
Message-ID<85d2v3fvjb.fsf@junk.nocrew.org>
In reply to#20615
Michael L Gassanenko wrote:
> So we get something like:
> : foo
>    ...
>    {{ a b }} HERE SWAP ALLOT [DOES> DUP a SWAP b + ;]
>    ...
> ;

This is quite reminiscent of a C++11 lambda function:

  [a,b]() { return a + b; }

(I'm not sure if that's good or bad.)

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


#20627

FromBernd Paysan <bernd.paysan@gmx.de>
Date2013-03-13 12:52 +0100
Message-ID<khpp9q$2r0$1@online.de>
In reply to#20615
Michael L Gassanenko wrote:

> 1. We need to decide what RECURSE means for quotations:
> call the quotation or call the enclosing named definition?

Call the quotation.

> 2. Closures (about which we sort of agreed to speak only
> theoretically), resemble CREATE-DOES> definitions in the
> same way as quotations resemble colon definitions.
> Quotations may reside in ROM; closures will need some RAM.
> 
> 2.1. Closures assume run-time creation of execution tokens.
> 
> 2.2. As to where the memory for data is allocated,
> I think, the best answer is: let the user choose, it may be
> ALLOCATE or HERE SWAP ALLOT .

Hm, this asks for some kind of vector.  Use a deferred word for allocation, 
or use some construct like <heap [:{ a b } ... ;] heap> to redirect 
dictionary allocation temporarily to a heap object (or the other way round - 
heap allocation to here).

However, I'm not convinced that we want closures as persistent objects - we 
already have create does> for that.  The only reason to use closures instead 
of Create DOES> for persistent stuff is that they may be more comfortable to 
write.

> 2.3. To create a closure, we will need to: allocate an area of
> memory with some room for the "code field"; fill the "data field"
> with the data; bind the closure with the desired behavior (writing
> to the "code field"); create an xt for that "code field".
> 
> So we get something like:
> : foo
>    ...
>    {{ a b }} HERE SWAP ALLOT [DOES> DUP a SWAP b + ;]
>    ...
> ;

Yes, that's sort of how you would do it.

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

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


#20658

FromLars Brinkhoff <lars.spam@nocrew.org>
Date2013-03-14 09:47 +0100
Message-ID<85ip4ue5aw.fsf@junk.nocrew.org>
In reply to#20627
Bernd Paysan <bernd.paysan@gmx.de> writes:
> However, I'm not convinced that we want closures as persistent
> objects - we already have create does> for that.  The only reason to
> use closures instead of Create DOES> for persistent stuff is that
> they may be more comfortable to write.

I'm toying with this possible CREATE-DOES>-style combination of
closures and quotations:

: counter ( n -- xt ) ( xt: n1 -- n2 )
   dup . [create , does> tuck +! @ ;] ." is enclosed" ;
 ok
100 counter value f
100 is enclosed ok
1 f execute .
101  ok
2 f execute .
103  ok
42 counter value g
42 is enclosed ok
1 g execute .
43  ok
3 f execute .
106  ok

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


#20670

FromSieur de Bienville <morrimichael@gmail.com>
Date2013-03-14 10:45 -0700
Message-ID<d1134367-4776-4894-8682-a9effaeb455f@c6g2000yqh.googlegroups.com>
In reply to#20658
On Mar 14, 3:47 am, Lars Brinkhoff <lars.s...@nocrew.org> wrote:
> I'm toying with this possible CREATE-DOES>-style combination of
> closures and quotations:
>
> : counter ( n -- xt ) ( xt: n1 -- n2 )
>    dup . [create , does> tuck +! @ ;] ." is enclosed" ;
>  ok
> 100 counter value f
> 100 is enclosed ok
> 1 f execute .
> 101  ok
> 2 f execute .
> 103  ok
> 42 counter value g
> 42 is enclosed ok
> 1 g execute .
> 43  ok
> 3 f execute .
> 106  ok

I can see using quotations to remove otherwise unnecessary do-stuff
words, but I'm not entirely sure how this example is different from:

: counter  dup . ." is enclosed"  create , does> tuck +! @ ; ok

100 counter f 100 is enclosed ok
1 f . 101  ok
2 f . 103  ok
42 counter g 42 is enclosed ok
1 g . 43  ok
3 f . 106  ok

Would you please explain?

Virtually,
Michael Morris

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


#20671

FromLars Brinkhoff <lars.spam@nocrew.org>
Date2013-03-14 19:41 +0100
Message-ID<85ehfhesdn.fsf@junk.nocrew.org>
In reply to#20670
Sieur de Bienville <morrimichael@gmail.com> writes:
> > : counter ( n -- xt ) ( xt: n1 -- n2 )
> >    dup . [create , does> tuck +! @ ;] ." is enclosed" ;
>
> I can see using quotations to remove otherwise unnecessary do-stuff
> words, but I'm not entirely sure how this example is different from:
>
> : counter  dup . ." is enclosed"  create , does> tuck +! @ ; ok

Possibly my sample code wasn't a blinding success in showing off the
supposed advantages.

The main difference is just that the xt can be passed along without
having to give it a name.  This may not seem like much, and indeed you
can do perfectly well without that feature.  But sometime it can be
convenient.

One additional difference is that, as you probably noted, you were not
able to do any computations after the does> part.  Again, a minor
inconvenience at most.

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


#20674

FromSieur de Bienville <morrimichael@gmail.com>
Date2013-03-14 12:58 -0700
Message-ID<5df45cd2-dc48-4485-a460-772f47273a8a@9g2000yqy.googlegroups.com>
In reply to#20671
On Mar 14, 1:41 pm, Lars Brinkhoff <lars.s...@nocrew.org> wrote:
> The main difference is just that the xt can be passed along without
> having to give it a name.  This may not seem like much, and indeed you
> can do perfectly well without that feature.  But sometime it can be
> convenient.
>
> One additional difference is that, as you probably noted, you were not
> able to do any computations after the does> part.  Again, a minor
> inconvenience at most.

Ah, so it's the :NONAME for CREATEd words. That makes sense.

Virtually,
Michael Morris

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


#20682

FromMichael L Gassanenko <m_l_g3@yahoo.com>
Date2013-03-14 23:09 -0700
Message-ID<6fb1e77d-d9e9-47e1-b0a1-7220435d33c4@googlegroups.com>
In reply to#20627
On Wednesday, March 13, 2013 3:52:24 PM UTC+4, Bernd Paysan wrote:
> Michael L Gassanenko wrote:
> > 2. Closures (about which we sort of agreed to speak only
> > theoretically), resemble CREATE-DOES> definitions in the
> > same way as quotations resemble colon definitions.
> > Quotations may reside in ROM; closures will need some RAM.
> > 
> > 2.1. Closures assume run-time creation of execution tokens.
> > 2.2. As to where the memory for data is allocated,
> > I think, the best answer is: let the user choose, it may be
> > ALLOCATE or HERE SWAP ALLOT .
> 
> Hm, this asks for some kind of vector.  Use a deferred word for allocation, 
> or use some construct like <heap [:{ a b } ... ;] heap> to redirect 
> dictionary allocation temporarily to a heap object (or the other way round - 
> heap allocation to here).
> 
> However, I'm not convinced that we want closures as persistent objects - we 
> already have create does> for that.

Allocation at HERE is not necessarily persistent.
The dictionary may be used as a LIFO memory pool, whose
memory is allocated/deallocated using the words like:

: HERE-ALLOT ( size -- addr ) HERE SWAP ALLOT ;
: HERE! ( addr -- ) HERE - ALLOT ;

This may be more convenient than the ALLOCATE heap because
there is no need to deallocate individual objects, HERE!
is a bulk deallocation operation; OTOH, one may need to
explicitly copy objects that must survive such bulk deallocation.


> The only reason to use closures instead 
> of Create DOES> for persistent stuff is that they may be more comfortable to 
> write.

They may be generated by a program, e.g. at compile-time.

> > 2.3. To create a closure, we will need to: allocate an area of
> > memory with some room for the "code field"; fill the "data field"
> > with the data; bind the closure with the desired behavior (writing
> > to the "code field"); create an xt for that "code field".
> > 
> > So we get something like:
> 
> > : foo
> >    ...
> >    {{ a b }} HERE SWAP ALLOT [DOES> DUP a SWAP b + ;]
> >    ...
> > ;
> 
> Yes, that's sort of how you would do it.
> 
> 
> -- 
> 
> Bernd Paysan
> "If you want it done right, you have to do it yourself"
> http://bernd-paysan.de/

[toc] | [prev] | [standalone]


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


csiph-web