Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #20615 > unrolled thread
| Started by | Michael L Gassanenko <m_l_g3@yahoo.com> |
|---|---|
| First post | 2013-03-13 01:54 -0700 |
| Last post | 2013-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.
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
| From | Michael L Gassanenko <m_l_g3@yahoo.com> |
|---|---|
| Date | 2013-03-13 01:54 -0700 |
| Subject | Re: 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]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2013-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]
| From | Michael L Gassanenko <m_l_g3@yahoo.com> |
|---|---|
| Date | 2013-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]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2013-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2013-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]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2013-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2013-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]
| From | albert@spenarnc.xs4all.nl (Albert van der Horst) |
|---|---|
| Date | 2013-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]
| From | anton@mips.complang.tuwien.ac.at (Anton Ertl) |
|---|---|
| Date | 2013-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]
| From | David Kuehling <dvdkhlng@gmx.de> |
|---|---|
| Date | 2013-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]
| From | Andrew Haley <andrew29@littlepinkcloud.invalid> |
|---|---|
| Date | 2013-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]
| From | David Kuehling <dvdkhlng@gmx.de> |
|---|---|
| Date | 2013-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]
| From | Lars Brinkhoff <lars.spam@nocrew.org> |
|---|---|
| Date | 2013-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]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2013-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]
| From | Lars Brinkhoff <lars.spam@nocrew.org> |
|---|---|
| Date | 2013-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]
| From | Sieur de Bienville <morrimichael@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Lars Brinkhoff <lars.spam@nocrew.org> |
|---|---|
| Date | 2013-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]
| From | Sieur de Bienville <morrimichael@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Michael L Gassanenko <m_l_g3@yahoo.com> |
|---|---|
| Date | 2013-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