forthgforth

gforth : Attempt to use zero-length string as a name

I am a beginner in this language : GForth.

Can someone with some experience tell me what the problem is in the code below ?

Here is a definition.

``````: collatzcount
variable count
0 count !
{ ini } ini
begin dup 1 <> while dup . syr repeat .
count ? ;
\ redefined collatzcount   ok
``````

At this point apparently nothing is wrong. So let us try :

``````1 collatzcount
``````

output

``````:213: Attempt to use zero-length string as a name
1 collatzcount>>><<<
Backtrace:
\$7F21F04AB710 throw
\$7F21F04B0008 name-too-short?
\$7F21F04B1A00 Create
\$7F21F04FD460 Variable
``````

What is this mysterious "Attempt to use zero-length string as a name" ?

Just in case one wants to know, this is the definition of syr :

``````: syr dup 2 mod 0 = if 2 / else 3 * 1 + endif ;
``````

But this is probably irrelevant to the question.

Solution

• `variable` is a defining word and works correctly only at interpreter level i.e. not within a colon definition. (This is true for all Forths, but the symptoms of violating it may vary; in particular a 'state-smart' implementation will likely give you an error during the definition, rather than waiting till you run it.)

Also `count` is a preexisting (and standard) word; using it as a `variable` makes the standard word inaccessible and may break things.

Finally there is no benefit in making `ini` a local when the only use you make of it is to immediately re-push it.

Net:

``````: syr dup 2 mod 0 = if 2 / else 3 * 1 + endif ;

variable cnt
: collatzcount 0 cnt ! begin dup 1 <> while dup . syr repeat . cnt ? ;
1 collatzcount -> 1 0 ok
3 collatzcount -> 3 10 5 16 8 4 2 1 0  ok
``````

This runs, but the count is always 0 because you never changed it. I suspect from the name you wanted to increment `cnt` in the loop so at the end it prints the number of loops executed (i.e. steps) before reaching 1:

``````: collatzcount 0 cnt ! begin dup 1 <> while cnt @ 1+ cnt ! dup . syr repeat . cnt ? ;
3 collatzcount -> 3 10 5 16 8 4 2 1 7  ok
``````