Re: I don't understand the definition of DOES>



On Mar 17, 8:16 am, Frank Buss <f...@xxxxxxxxxxxxx> wrote:
I think I know what DOES> does, but I don't understand the ANS Forth
definition. First I'll try to give a high-level definition of DOES> in my
own words:

DOES> is allowed within a colon definition. When executed, it appends the
compiled code after DOES> and until the closing ";" to the last defined
CREATE name execution semantic (which means that the data field address is
on stack on code entry).

Try it from the top down. DOES> lets you make defining words. A
defining word builds a class of words that each does the same action
but to different data.

For example, ARRAY . You can use DOES to make ARRAY and then use ARRAY
to make arrays.

: ARRAY ( n -- )
CREATE CELLS ALLOT
DOES> ( n -- a-addr )
SWAP CELLS + ;

5 ARRAY MY-ARRAY
30 ARRAY YOUR-ARRAY
22 ARRAY OUR-ARRAY

So you've made a class of words that extend the language. You can do
it without DOES> .

CREATE MY-ARRAY-SPACE 5 CELLS ALLOT
: MY-ARRAY
CELLS MY-ARRAY-SPACE + ;

This is shorter and more efficient than DOES> except it uses two
headers. If you have a few that all have the same code except for the
address, it's easier to use DOOES> .

Here's another way.

: COMPUTE-ARRAY ( n a-addr -- )
SWAP CELLS + ;

: ARRAY HERE SWAP CELLS ALLOT >R : R> ]] LITERAL COMPUTE-ARRAY ; [[ ;

5 ARRAY MY-ARRAY

My example without DOES> doesn't give any way to get the >BODY except
0 MY-ARRAY .
5 ARRAY MY-ARRAY 12 CELLS ALLOT doesn't give you a 17 size array, the
DOES> version does.

As to the complications of how DOES> works, I think those came because
a long time ago they fit an efficient way to do it on some particular
ancient Forth systems.

Nowadays we'd be better to factor DOES> .

First you'd make the code that will execute on the child word.

:NONAME SWAP CELLS + ;

Then after you have an xt, you'd have a word that coupled it with a
data item.

: DOIT ( xt )
HERE SWAP , 0 , >R :NONAME R> ]] 2@ EXECUTE ; [[ ;

You'd have a word that associates an xt with a name. This word, with a
few complications, could be used with every word in the dictionary.

: NAME| ( xt -- )
.( Implementation-dependent code )
>R : R> COMPILE, POSTPONE ; ;

We'd have a word that found the data space given the xt. I don't see
how to do that one portably without a lot of work. On a particular
system it could go something like

: BODY ( xt -- a-addr )
1 CELLS - ;

Given these words we could almost build DOES> . But it would be a bit
complex and tricky because DOES> is so complex and tricky.

: >BODY
BODY @ ;

Etc.

The factored pieces of DOES> are far far more flexible than DOES> .
But of course that flexibility isn't necessary; we've all gotten along
just fine without it for as long as we've been using Forth.


Then I don't understand the initiation semantics. For me it looks like the
description of a special implementation: When a NAME, which has some DOES>
code appended, is executed, then first the data field address is pushed on
stack and then the DOES> code is called (which is my interpretation, that
nest-sys is pushed to r-stack on "initiation semantics" and popped on
exit). But if it is compiled inline, there is no r-stack usage. Would such
an implementation conform to the ANS Forth standard?

Compare initiation semantics for DOES> with initiation semantics
for : . The only difference is that DOES> puts an address on the data
stack. All it's saying is that when you execute a child word you've
called one new word and the return stack has nested deeper. I'd like
to say it means you've nested one deeper and not two, but when there's
no guarantee that a nest-sys has a constant size, this definition
doesn't guarantee that.

What do you think about a simplified and unambigious definition of a Forth
system, down to the bit level, maybe with the help of the defintion of a
virtual machine? This maybe not the fastest or system, or the system which
produces the most compact code, but it could be still conforming to ANS
Forth and would provide a reference implementation of the standard.

I like the idea. However, it isn't particularly helpful to have one
more reference system. What would be better would be to have switches
for lots of implementation choices, and have a Forth that could become
lots of different standard Forths. So if we have N 2-way choices you
could easily build 2^N different standard Forth systems with it.
(Minus the combinations that just don't work together.) That would be
*very interesting*.

I think if you tried that you'd find that there are actually fewer
than 2^N approaches. Some implementation choices have multiple visible
results, and the standard describes all those results separately. But
it doesn't make sense to handle some of them apart from the others.
Like, : can leave an indeterminate number of items on the data stack
to be consumed by ; . If it does, you can't get anything from the data
stack that those items have buried because they're buried at an
indeterminate depth. You can't have control structures branching from
one definition to another because they have to be gone from the
control-flow stack when ; needs the ones that : left. Etc. A whole
bunch of related obstructions come from one choice.

On the other hand, : might leave its data in a special buffer, and if
you try to nest definitions (start a new one before the last one is
finished) then you may overwrite that data. If the data was left on a
stack you wouldn't overwrite it, once the new data was gone you could
continue and use the old data. Putting : data into a fixed buffer has
a different collection of related obstructions from one basic choice.

It would be interesting to see that all worked out, but it's a whole
lot of work with no immediate payoff. I'd contribute a lot of praise
but essentially no money.

.



Relevant Pages

  • Re: Constant array
    ... But I can't quite figure out how to make an array of constants without ... DOES> SWAP CELLS + @ EXECUTE; ...
    (comp.lang.forth)
  • Re: How to create an array
    ... CELLS used in Forth. ... This is the size of the data stack items, both on the stack and in ... This is the size of the character items in memory, ... byte-sized array, instead of a cell-sized array when simply using! ...
    (comp.lang.forth)
  • RE: excel formulas
    ... converts a number from euros to a euro member ... Counts the cells that contain numbers in a database ... Specifies a logical test to perform ... Looks in the top row of an array and returns the value of the indicated cell ...
    (microsoft.public.excel.misc)
  • Re: excel formulas
    ... member currency, or converts a number from one euro member currency ... Counts the cells that contain numbers in a database ... Specifies a logical test to perform ... Looks in the top row of an array and returns the value of the ...
    (microsoft.public.excel.misc)
  • Re: Excel Cell Formats
    ... Disable the update of excel. ... Copy the cells from this new sheet to my selection ... Someone suggested that I create a dummy 2D array containing my ... new ordering, but for my selection only, not the entire row. ...
    (microsoft.public.excel.programming)