Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

An example of a counter ?

197 views
Skip to first unread message

Bob Armstrong

unread,
Sep 20, 2017, 3:05:47 AM9/20/17
to
Could say I'm being lazy , but I'd like a simple example of a self-contained counter .

After the Vienna conf , I got up to the https://www.dyalog.com/user-meetings/dyalog17.htm APL conference to see old friends .

I got into a chat with Aaron W. Hsu who has developed a parallel APL compiler , https://github.com/arcfide.

I seemed not to be able to convince him that Forth did true compilation , even showing him interactively in CoSy :

: +2 2 + ;

followed by

1 +2

and then

see +2
00634D64 8D 76 FC lea esi,[esi-04]
00634D67 89 06 mov [esi],eax
00634D69 B8 02 00 00 00 mov eax,00000002
00634D6E 01 06 add [esi],eax
00634D70 8B 06 mov eax,[esi]
00634D72 8D 76 04 lea esi,[esi+04]
00634D75 C3 ret

He wanted to see a "real" program like a counter .

Concentrating on constructing the transition to dynamic reference counted generalized lists in CoSy , I've never done such things . In fact I find I never use ' does> anywhere in CoSy , and in fact only use ' create once .

I'm going to send Aaron Ron Aaron's "What are "imediate", "postponed", and "lazy" words?" https://8th-dev.com/forum/index.php?topic=1435.msg7714 , which I hope gets across to him that Forth has a more sophisticated understanding of the notion of compiling and control over it than C programmers ever thought of .

But I'd like to send him a simple example to answer his "counter" challenge also .

Ron Aaron

unread,
Sep 20, 2017, 3:58:48 AM9/20/17
to


On 20/09/2017 10:05, Bob Armstrong wrote:

> I'm going to send Aaron Ron Aaron's "What are "imediate", "postponed", and "lazy" words?" https://8th-dev.com/forum/index.php?topic=1435.msg7714 , which I hope gets across to him that Forth has a more sophisticated understanding of the notion of compiling and control over it than C programmers ever thought of .

I'm honored :)


> But I'd like to send him a simple example to answer his "counter" challenge also .

What do you mean by a 'counter' in this context?

Bob Armstrong

unread,
Sep 20, 2017, 4:31:03 AM9/20/17
to
That's a better question than I was thinking . I was thinking of something with an "internal" cell which would be incremented each time the word was invoked rather than a simple "external" variable as in the example in https://www.forth.com/starting-forth/8-variables-constants-arrays/ . But really a counter is defined by the vocabulary used to invoke it . And I can't see much point in having anything more than a simple variable and common increment and reset words .

I think I'm just going to send Aaron a link to this discussion and let him take it from there .

I think it interesting that Aaron resisted the notion of word-by-word compilation when he lives in word-by-word APL .

minf...@arcor.de

unread,
Sep 20, 2017, 5:08:40 AM9/20/17
to
I am not sure I got it right ... but

: COUNTER ( 'name' -- )
create 0 , does> 1 over +! @ ;
COUNTER MYC
MYC . 1
MYC . 2

Helmar Wodtke

unread,
Sep 20, 2017, 6:10:35 AM9/20/17
to
Am Mittwoch, 20. September 2017 09:05:47 UTC+2 schrieb Bob Armstrong:
> Could say I'm being lazy , but I'd like a simple example of a self-contained counter .

Using gforthisms, you can use:

\ --------------------
: counter \ addr <name>-- \ define <name>, runtime: -- [addr]+=1
>r : r> ]] literal 1 over +! @ ; [[ ;

here 0 , counter what

what .
what .
what .
cr

variable testV

testV counter the-counter

the-counter .
the-counter .
the-counter .
testV @ .
cr
\ --------------------


should give:
1 2 3
1 2 3 3

Regards,
-Helmar

Paul Rubin

unread,
Sep 20, 2017, 6:30:10 AM9/20/17
to
Bob Armstrong <b...@cosy.com> writes:
> He wanted to see a "real" program like a counter .

What is that supposed to mean? Will this do?

0 VALUE x
: count x . x 1+ TO x ;

count
count 0 ok
count
count 1 ok
count
count 2 ok
count
count 3 ok
...

Alex

unread,
Sep 20, 2017, 10:09:38 AM9/20/17
to
On 20-Sep-17 08:05, Bob Armstrong wrote:

>
> But I'd like to send him a simple example to answer his "counter"
> challenge also .
>

How about a factorial counter?

: facc create 1 , 1 ,
does> dup 2@ over >r + r@ rot 2! r> ;
facc f!n
cr
f!n .
f!n .
f!n .
f!n .
f!n .


prints
1 2 3 5 8

and so on.

--
Alex

minf...@arcor.de

unread,
Sep 20, 2017, 10:19:04 AM9/20/17
to
That's automated cheating. ;-)

Julian Fondren

unread,
Sep 20, 2017, 10:57:40 AM9/20/17
to
On Wednesday, September 20, 2017 at 2:05:47 AM UTC-5, Bob Armstrong wrote:
> Could say I'm being lazy , but I'd like a simple example of a self-contained counter .
...
> He wanted to see a "real" program like a counter .

Perhaps he wasn't talking about compilation, but about this?

http://www.paulgraham.com/accgen.html

Even with the strict requirements, with a bignum library it's possible
in Forth, but Paul Graham rejected submissions anyway, on roughly the
basis that requiring the library meant it was no longer simply a
"Forth" submission.

rickman

unread,
Sep 20, 2017, 11:44:48 AM9/20/17
to
http://static.gemplers.com/img/tally-meter-hand-R34500-lrg.jpg

--

Rick C

Viewed the eclipse at Wintercrest Farms,
on the centerline of totality since 1998

Anton Ertl

unread,
Sep 20, 2017, 12:26:54 PM9/20/17
to
Looks to me like a Fibonacci counter, not a factorial counter.

- 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 2017: http://euro.theforth.net/

Mark Wills

unread,
Sep 20, 2017, 12:58:26 PM9/20/17
to
: counter: ( 'name' -- ) ( runtime: -- count+1 )
create 0 , does> 1 over +! @ ;

counter: count

count . 1 ok:0
count . 2 ok:0
count . 3 ok:0

Anything is possible in Forth :-)

al...@rivadpm.com

unread,
Sep 20, 2017, 12:58:39 PM9/20/17
to
Duh, silly me. As usual, more haste and less speed with brain in neutral.

--
Alex

NN

unread,
Sep 20, 2017, 2:41:07 PM9/20/17
to

If I may ask, why would you need to convince him ( Aaron Hsu )that forth did true compilation ?

NN


dxf...@gmail.com

unread,
Sep 20, 2017, 9:38:43 PM9/20/17
to
On Wednesday, September 20, 2017 at 6:31:03 PM UTC+10, Bob Armstrong wrote:
> That's a better question than I was thinking . I was thinking of something with an "internal" cell which would be incremented each time the word was invoked rather than a simple "external" variable as in the example in https://www.forth.com/starting-forth/8-variables-constants-arrays/ . But really a counter is defined by the vocabulary used to invoke it . And I can't see much point in having anything more than a simple variable and common increment and reset words .
>
> I think I'm just going to send Aaron a link to this discussion and let him take it from there .
>
> I think it interesting that Aaron resisted the notion of word-by-word compilation when he lives in word-by-word APL .
>

In Forth the programmer is the compiler but
attempting to convince anyone to use a language
on the basis of its arcane properties is likely
to go nowhere. In Forth it has been something of
a two-edged sword given the distraction such
features have engendered.

arc...@sacrideo.us

unread,
Sep 23, 2017, 3:45:55 PM9/23/17
to
Hello All:

I'm sorry for creating such a mess. :-)

My discussion with Bob was really about trying to understand what Forth calls compilation, and what features or approaches it takes to handling more complex issues of abstraction and static analysis.

We were encountering some clear issues of vocabulary and methodology, so to try to limit the scope of the question, I wanted to address the first issue of the degree of "sophistication" of function handling in the language, and whether or not the language contained closures or the like.

It is easier to demonstrate the counter program that I wanted to see compiled by writing it in Scheme:

(define (make-counter init)
(let ([counter init])
(lambda () (set! counter (+ 1 counter)) counter)))

=> (define a (make-counter 0))
=> (define b (make-counter 5))
=> (a)
1
=> (a)
2
=> (b)
6
=> (b)
7
=> (a)
3
=>

The goal after seeing how this was written was to see how it was "compiled." I was interested to see how Forth dealt with the compilation and handling of internal functions and state.

Finally, I was really trying to find a non-trivial enough example for Bob to demonstrate how Forth handles non-linear compilation tasks. All I saw was what looks like a direct node by node translation of each token/id into assembler, which is more like the process of assembly programming with a macro system than it Is a form of static compilation (though that's splitting hairs).

Whether or not Forth does "compilation" is really irrelevant. What I wanted to see was what kind of compilation it does, and whether or not the compiler was designed to handle the sorts of common transformation tasks that the majority of major compiled languages handle (including APL) such as constant propagation, function inlining, dead/useless code elimination, and constant folding, as well as the handling of scope, nested definitions, &c.

Sorry for the noise! If anyone has a succinct explanation for these things, I'd find them interesting to read.

Yours truly,

Aaron W. Hsu

Julian Fondren

unread,
Sep 23, 2017, 5:16:05 PM9/23/17
to
On Saturday, September 23, 2017 at 2:45:55 PM UTC-5, arc...@sacrideo.us wrote:
> Hello All:
>
> I'm sorry for creating such a mess. :-)
>
> My discussion with Bob was really about trying to understand what Forth calls compilation, and what features or approaches it takes to handling more complex issues of abstraction and static analysis.
>
> We were encountering some clear issues of vocabulary and methodology, so to try to limit the scope of the question, I wanted to address the first issue of the degree of "sophistication" of function handling in the language, and whether or not the language contained closures or the like.

I would investigate a new language by making a list of language
features and asking what they would like in the language. You'll get
responses like "it looks like this", "there's no direct support for
that but you could fake it with this", "we would never do that because
we have this other feature, but if you *really wanted to*--", and more
rarely "that's basically impossible, we would do this other stuff
instead in this or that usage of it".

http://rosettacode.org can help you find answers like that.

A question like "how do you do sophisticated abstraction?" is pretty
guaranteed to result in a thread like this, meanwhile.

>
> It is easier to demonstrate the counter program that I wanted to see compiled by writing it in Scheme:
>
> (define (make-counter init)
> (let ([counter init])
> (lambda () (set! counter (+ 1 counter)) counter)))
>
> => (define a (make-counter 0))
> => (define b (make-counter 5))
> => (a)
> 1
> => (a)
> 2
> => (b)
> 6
> => (b)
> 7
> => (a)
> 3
> =>
>

This is Paul Graham's accumulator generator--I referred to it above.
There are three important parts to it:

1. first-class functions (a function assigned to a variable and then
called as a function; a function returned from a function)

2. closures (a first-class function is created with its own copy of
some lexically determined state)

3. (as Paul Graham put it) bignums. The result of the calling the
counter must always be one plus the previous result. It can't be
suddenly less than the previous result, or equal to the previous
result.

Forth has the first. Libraries grant the third to Forth.

The second though is a case of "there's no direct support for that but
you can fake it". Forth doesn't have lexical variables, and functions
don't have hidden copies of state. But there are all several examples
of faking exactly this in the thread.

> The goal after seeing how this was written was to see how it was "compiled." I was interested to see how Forth dealt with the compilation and handling of internal functions and state.
>
> Finally, I was really trying to find a non-trivial enough example for Bob to demonstrate how Forth handles non-linear compilation tasks. All I saw was what looks like a direct node by node translation of each token/id into assembler, which is more like the process of assembly programming with a macro system than it Is a form of static compilation (though that's splitting hairs).

... you're asking about language features so that you can have an
understanding of compiler sophistication?

OK, this closure example, you can do it in eforth which doesn't do
function inlining or constant folding or any of that, and you can do
it in iforth which does do those things. Compiler sophistication
varies without changing the language.

"Isn't this just an assembler?" is a question I can't bring myself to
care about.

Bob Armstrong

unread,
Sep 23, 2017, 6:10:30 PM9/23/17
to
On Wednesday, September 20, 2017 at 3:08:40 AM UTC-6, minf...@arcor.de wrote:

Yea , just that simple " create ... does> ... " is what I was thinking of .

There is some interesting answers here , tho .

Bob Armstrong

unread,
Sep 23, 2017, 6:13:36 PM9/23/17
to
On Wednesday, September 20, 2017 at 12:41:07 PM UTC-6, NN wrote:
> If I may ask, why would you need to convince him ( Aaron Hsu )that forth did true compilation ?
>
> NN

Actually , I think we're coming to see we really have been thinking different definitions .

All that really matters is the " ding an sich " .

Paul Rubin

unread,
Sep 23, 2017, 6:35:51 PM9/23/17
to
Julian Fondren <julian....@gmail.com> writes:
> The second though is a case of "there's no direct support for that but
> you can fake it". Forth doesn't have lexical variables, and functions
> don't have hidden copies of state.

The alternative to closures in procedural languages is usually some form
of OOP. There are lots of OOP libraries for Forth.

Elizabeth D. Rather

unread,
Sep 23, 2017, 6:50:23 PM9/23/17
to
The basic problem with your question is that there's a whole range of
approached to "compilation" in various Forth implementations, ranging
from the original approach of indirect threaded code (colon definitions
consist of execution tokens that are processed by an address
interpreter) through subroutine threaded code (colon definitions compile
a sequence of calls or jsr's) to different strategies for optimizing
compilation to code with processes similar to other HLL compilers. There
have also been a number of token-based compilers. The term "Forth"
really only defines the programmer's view of the programming process
(available commands and programming strategies), not the execution model.

Cheers,
Elizabeth

--
Elizabeth D. Rather
FORTH, Inc.
6080 Center Drive, Suite 600
Los Angeles, CA 90045
USA

arc...@sacrideo.us

unread,
Sep 23, 2017, 10:19:55 PM9/23/17
to
On Saturday, September 23, 2017 at 5:16:05 PM UTC-4, Julian Fondren wrote:
> ... you're asking about language features so that you can have an
> understanding of compiler sophistication?

I wasn't getting anywhere trying to clarify the process that Bob was trying to describe to me, so I was trying to do it by "example program analysis" if you will. Often what the compiler produces for a given output is very elucidatory regarding hidden aspects of the language that aren't always obvious at first glance, but that usually requires picking some specific language feature to play with at a time to avoid being overwhelmed. At this point, with the help of this thread and some other indirect communication I've been able to get a clearer picture of what he was talking about and what his perspective is on these things.

Thank you to everyone for providing an interesting thread with plenty of resources. It's been fun. :-)

And just to be clear, lest people think that I'm conflating a language with its implementation, Bob and I were talking about a specific implementation of Forth that he had on his machine at the time, so my discussion was in the context of that specific implementation, the name of which is not quite clear to me.

Anyways, thanks for your patience with a strange set of questions.

Elizabeth D. Rather

unread,
Sep 23, 2017, 10:42:43 PM9/23/17
to
Thank you for the clarification. I do hope you explain to Bob that
whatever implementation that is, it is only one example of Forth
compiler structure, and not an inherent feature of Forth as a
programming language.

Paul Rubin

unread,
Sep 23, 2017, 11:07:05 PM9/23/17
to
arc...@sacrideo.us writes:
> I wasn't getting anywhere trying to clarify the process that Bob was
> trying to describe to me, so I was trying to do it by "example program
> analysis" if you will.

I think I understand what was wanted. A word something like

: foo ( n -- xt ) .... ;

so if you say

3 foo VALUE bar

then "bar execute bar execute bar execute" will put 3 4 5 on the stack.

Ron Aaron

unread,
Sep 23, 2017, 11:53:48 PM9/23/17
to


On 24/09/2017 5:19, arc...@sacrideo.us wrote:

> And just to be clear, lest people think that I'm conflating a language with its implementation, Bob and I were talking about a specific implementation of Forth that he had on his machine at the time, so my discussion was in the context of that specific implementation, the name of which is not quite clear to me.

The specific implementation Bob's got in this CoSy system is "Reva
Forth", which is a subroutine-compiled Forth I wrote. It only does
"tail-call removal" and "small function inlining" as optimizations, but
nothing else.

My current Forth implementation, "8th", doesn't do the inlining either,
just the tail-call removal.

But there are plenty of Forth implementations which do all the various
kinds of optimizations common in e.g. C compilers, so judging the entire
field of offerings by what Reva Forth offers is not a useful exercise.
0 new messages