Liste des Groupes | Revenir à cl forth |
minforth@gmx.net (minforth) writes:On Thu, 25 Jul 2024 12:08:58 +0000, Anton Ertl wrote:>>I am thinking on a much smaller scale i.e. unification of>
operators for xVALUEs and xLOCALs. ANS Forth already has
overloaded TO but stops there.
+TO is a common extension.
Certainly. I have some array operations in mind, but they
are not relevant here. The principle is like
>
: INIT { a }
[[: a ;]] \ read counter
[[: 1 +to a ;]] ; \ increment counter
DEFER count IS count
DEFER read IS read
5 INIT
COUNT COUNT READ -> should give 7
My guess is that three lines here should be
>
DEFER count
DEFER read
5 INIT IS count IS read
>[[: ;]] define closures, but unlike gforth's more flexible>
flat closures, they capture simply all upvalues (here local a).
Gforth's flag closures can be considered lower-level (they come out of
implementation ideas in the Scheme community) and are easier to
implement, but emulating closures that capture outer locals is more
cumbersome. One other aspect is that in Gforth's closures the
programmer decides whether closures are allocated in the dictionary,
on the locals stack, on the heap, or elsewhere. In the present case
the dictionary seems to be a good place, and one can write this
example as:
>
: init ( a -- )
align here >r , \ allocate a on the heap
r@ [n:d @ ;] \ read counter
r> [n:d 1 swap +! ;] \ increment counter
;
DEFER count
DEFER read
5 INIT IS count IS read
count count read . \ prints "7 "
>
INIT uses pure-stack closures [n:d consumes a value (in this exampl,
the address of the cell containing A) from the stack at closure
creation time and pushes it on the stack at closure run-time. Look,
Ma, no locals:-).
>
However, this does not use value-flavoured stuff, because we have to
pass the address of A around, and then it's easier to use the
variable-flavoured words. However, if you prefer the value-flavoured
words, value-flavoured fields were recently added to Gforth and can be
used to do that:
>
begin-structure counter
value: counter-val
end-structure
: init ( a -- )
align here >r counter allot
r@ to counter-val
r@ [n:d counter-val ;]
r> [n:d 1 swap +to counter-val ;]
;
DEFER count
DEFER read
5 INIT IS count IS read
count count read . \ prints "7 "
>
However, you still have to deal with the address explicitly, which
becomes especially obvious in the counter closure.
>
This raises the question of why you want to use closures for this
task. Why not use one of the object-oriented Forth packages, some of
which support value-flavoured fields (Mini-OOF2 among them AFAIK).
>The code compiles unmodified for different types of a.>
Incidentally, it compiles now with +TO, but realistically you
can't declare new 'op'TOs for too many different 'op' operators.
This statement can be read in two different ways. I think there can
be too many, but Stephen Pelc may think otherwise:-).
>
- anton
Les messages affichés proviennent d'usenet.