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

The CHOOSE (switch) statement for Forth

1,094 views
Skip to first unread message

Gerry Jackson

unread,
Oct 19, 2019, 3:11:42 PM10/19/19
to
I came across this post in c.l.f.

https://groups.google.com/forum/?hl=en#!searchin/comp.lang.forth/choose.htm%7Csort:date/comp.lang.forth/ZGCesckN0qI/zUh5IYNaa_UJ

Message-ID:
<594fc8e8-f584-40e0...@b15g2000yqd.googlegroups.com>

Unfortunately the link to choose.htm in that post doesn't work, it goes
to a Russian site with, I think, a page not found message.

I cannot find the file choose.htm anywhere on the internet - does anyone
know where a copy can be found?

--
Gerry

Ilya Tarasov

unread,
Oct 19, 2019, 8:12:10 PM10/19/19
to
суббота, 19 октября 2019 г., 22:11:42 UTC+3 пользователь Gerry Jackson написал:
'mlg' seems to be nickname of Michail Gassanenko. What else you want to know about choose statement? We have some threads about CASE, which is the same.

dxforth

unread,
Oct 19, 2019, 8:55:18 PM10/19/19
to

Gerry Jackson

unread,
Oct 20, 2019, 6:20:31 AM10/20/19
to
Thank you, I tend to forget the Wayback Machine.
That's the file I vaguely remember from a few years ago.

--
Gerry

Gerry Jackson

unread,
Oct 20, 2019, 9:16:27 AM10/20/19
to
On looking over the choose.htm file (link provided by dxforth) I am
reminded that Michael Gassanenko's CHOOSE generates and uses a jump
table. While CASE may look similar to CHOOSE to the user, CASE isn't
usually implemented using a jump table and is therefore much slower in
general. Also CHOOSE actions can be shared by values and/or ranges
of values.

--
Gerry

hughag...@gmail.com

unread,
Oct 20, 2019, 7:51:47 PM10/20/19
to
I wrote a <SWITCH construct back in 2016.
I'm not providing the Forth-200x committee with a path to success though.
We have this thread:
https://groups.google.com/forum/#!topic/comp.lang.forth/9IHvRJmMn20
I said this:

On Thursday, June 20, 2019 at 9:58:00 PM UTC-7, hughag...@gmail.com wrote:
> I challenge the Forth-200x committee to put their heads together
> and write a substitute for Eaker's CASE that isn't retarded.
> So far, the only attempt made was by Andrew Haley:
> https://wiki.forth-ev.de/doku.php/events:ef2018:case
> His only Forth experience was teaching the Forth Inc. novice class,
> so he unsurprisingly failed to write any working Forth code.
> All he had was a vague dream about how a perfect hash function
> would be super-duper (in a word: "perfect").
> He isn't going to succeed in writing Forth code, but maybe if all
> the Forth-200x committee members work together they can succeed.
>
> These are the criteria they need to meet to succeed:
> 1.) Their code can be no more than twice as complicated as my code.
> 2.) Their generated code can be no less that half as efficient as my code.
> 3.) They can't copy my code or my algorithm.

Now Gerry Jackson is hoping that Michail Gassanenko can rescue
the Forth-200x committee from their pit of incompetence by providing
them with a CHOOSE that generates and uses a jump-table.
This is their best hope for meeting my criteria for success!
With a little help from Russia the Forth-200x committee can succeed!

This is my code originally written in 2016 but slightly upgraded since then:
-----------------------------------------------------------------------
\ ******
\ ****** This is a <SWITCH control-structure like in C that generates a jump-table.
\ ******

\ You can build a colon word called XXX that switches on targ values. This is how:
\ <SWITCH
\ :NONAME ... ; targ CASE-OF
\ ...
\ :NONAME ... ; FAST-SWITCH> xxx ( selector -- )

\ There are some simple additions as well: RANGE-OF CHARS-OF for a range of values or a set of chars.
\ Also, we have CASE: suggested by DXForth that can be used instead of CASE-OF .

\ The colon word XXX executes a table-entry corresponding to the targ value.
\ If there is no match, then the xt value prior to FAST-SWITCH> is executed as the default.
\ All of the table-entries and the default are given the selector value which they DROP if not needed.
\ It was HAA's suggestion that the selector value be provided --- I had dropped it internally previously.

\ The targ values don't have to be provided in any particular order --- they get sorted internally.
\ If a duplicate targ value is provided, CASE-OF will abort with an error message at compile-time.

\ This is pretty crude because, unlike in C, the table entries can't have common local variables.
\ I would have liked to use my rquotations, but they don't have an xt that is known at compile-time,
\ so it is not possible to build a jump-table at compile-time. They have a "continuation" that is only known at run-time.
\ My <SWITCH that I have here uses :NONAME for the table entries --- they can have common global variables.

\ FAST-SWITCH> uses the selector value as an index to do the table look up. This is very fast.
\ If the range is too large however, then FAST-SWITCH> will abort with an error message to save memory.
\ In this case, use SLOW-SWITCH> instead. This builds a smaller table and uses BSEARCH to look up the table-entry.

\ Set JT-LIMIT to the range that you want FAST-SWITCH> to support.
\ It is currently set at 2^16 so you can have jump-tables with up to 64K entries. These consume a lot of memory.
\ If memory usage is an issue, then set JT-LIMIT to a smaller value. Use SLOW-SWITCH> instead of FAST-SWITCH>.
\ If the jump-table is sparse, SLOW-SWITCH> might be faster because there is less data-cache thrashing.

\ <SWITCH is primarily provided for writing VM simulators.
\ JT-LIMIT is currently set at 2^16, so it supports simulating a micro-processor with 16-bit opcodes (such as the AVR).
\ SLOW-SWITCH> would be needed for a micro-processor with 32-bit opcodes (such as the ARM or MIPS).

\ Some micro-processors (or byte-code VMs) have 8-bit opcodes, but also have post-bytes on some of the opcodes.
\ These variable-sized opcodes could be done with nested FAST-SWITCH> constructs.

list
w field .xt
w field .targ
constant jt

: init-jt ( xt targ node -- node )
init-list >r
r@ .targ !
r@ .xt !
r> ;

: new-jt ( xt targ -- node )
jt alloc
init-jt ;

: kill-jt ( head -- )
each[ dealloc ]each ;

: show-jt ( head -- )
each[ cr .targ @ . ]each ;

: jt> ( new-node node -- new-node flag ) \ used by INSERT-ORDERED to build an ascending list without duplicates
.targ @ over .targ @
2dup = abort" *** <SWITCH structures not allowed to have duplicate targ values ***"
> ;

: <switch ( -- head )
nil ;

: case-of ( head xt targ -- new-head ) \ provide a targ value
new-jt \ -- head node
['] jt> swap insert-ordered drop ;

: range-of { head xt lo hi -- new-head } \ provide a range from LO to HI inclusive
head
hi 1+ lo do
xt I case-of
loop ;

: chars-of { head xt adr cnt -- new-head } \ provide a string containing targ chars
head
adr cnt + adr do
xt I c@ case-of
loop ;

: digit-of ( head xt -- new-head )
[char] 0 [char] 9 range-of ;

: lower-of ( head xt -- new-head )
[char] a [char] z range-of ;

: upper-of ( head xt -- new-head )
[char] A [char] Z range-of ;

: alpha-of { head xt -- new-head }
head
xt lower-of xt upper-of ;

: punctuation-of ( head xt -- new-head )
s| .,!?'";:[]()@#$%&| chars-of ;

: blank-of ( head xt -- new-head )
0 32 range-of ;

1 16 lshift value jt-limit \ should be at least 256 so we can support byte-code simulators

\ JT-LIMIT is the index that is too big for the jump-table. This can be any reasonable size.
\ The jump-table size is limited so the programmer doesn't accidentally build a jump-table consuming megabytes.
\ I set it at 2^16 to support simulating a micro-processor with 16-bit opcodes.

: fast-switch> { head default | adr offset size -- } \ stream: name
align here to adr
head .targ @ to offset
head tail .targ @ offset - to size
size jt-limit u> abort" *** FAST-SWITCH> has too large of a range. Use SLOW-SWITCH> instead. ***"
offset head each[ >r \ -- targ
begin r@ .targ @ over <> while default , 1+ repeat
r> .xt @ , 1+ ]each drop
: ( selector -- )
dup, offset lit, -, \ -- selector index
dup, size lit, u>, if, drop, default lit, execute, end,
w lit, *, adr lit, +, @, execute, ;,
head kill-jt ;

: slow-search ( array limit target -- element|false ) \ hard-coded for use by SLOW-SWITCH>
>r \ -- array limit \ return: -- target
begin dup while
dup 1 rshift \ -- array limit mid
dup d * fourth + \ -- array limit mid mid-element
r@ over @ = if nip nip nip rdrop exit then \ if found, return MID-ELEMENT
r@ over @ < if \ search left side
drop nip \ -- array mid \ MID is the new limit
else
d + >r \ -- array limit mid \ return: -- target new-array \ NEW-ARRAY is one element above middle element
1+ - \ -- array new-limit \ the 1+ is so we don't include the middle element
nip r> swap \ -- new-array new-limit \ MID-ELEMENT is the new ARRAY
then
repeat \ LIMIT is zero, so it can be used as a FALSE flag
nip rdrop ; \ -- false

\ SLOW-SEARCH assumes that the array element is D in size (two cells),
\ and the first cell is the integer that we are comparing against.

: slow-switch> { head default | adr size -- } \ stream: name
dalign here to adr \ use DALIGN so the element SLOW-SEARCH finds will be in the same data-cache line
head length to size
head each[ dup .targ @ , .xt @ , ]each
: ( selector -- )
adr lit, size lit, rover, postpone slow-search
dup, if, w lit, +, @, execute, end,
drop, default lit, execute, ;,
head kill-jt ;

\ CASE: and ;; were suggested by DXForth on comp.lang.forth to improve readability.
\ This works well when there is a list of integers, similar to CASE END-CASE in ANS-Forth.

get-current synonym case: :noname \ head targ -- head targ

: ;; ( head targ -- new-head ) \ this concludes the CASE: function (rather than ; as used in :NONAME usually)
postpone ; \ -- head targ xt
swap case-of ;
immediate

\ Note that the default should still be :NONAME and end with ; as usual.
-----------------------------------------------------------------------

Gerry Jackson

unread,
Oct 21, 2019, 7:21:11 AM10/21/19
to
I've never examined your switch construct or passed any opinion on it.
Looking at the above it is not clear to me how your switch construct is
actually used. You didn't provide an example of usage and a quick search
of c.l.f. didn't find an example.

A simple example using MLG's CHOOSE is:

: test
choose
1 when 1111 . end
7 9 ... 12 when 3333 . end
2 3 when 2222 . end
other 7777 . end \ Any other integer - the default
end
;

where the word ... denotes a range
\ Testing with GForth
1 test \ displays 1111
2 test \ displays 2222
3 test \ displays 2222
10 test \ displays 3333
99 test \ displays 7777

How would you write an equivalent using your FAST-SWITCH>, SLOW_SWITCH> etc?

--
Gerry

bruno degazio

unread,
Oct 21, 2019, 10:21:09 AM10/21/19
to
On Saturday, 19 October 2019 15:11:42 UTC-4, Gerry Jackson wrote:

What is the expected performance difference between this approach and a the common CASE implementation?

Helmar Wodtke

unread,
Oct 21, 2019, 10:38:23 AM10/21/19
to
Am Montag, 21. Oktober 2019 16:21:09 UTC+2 schrieb bruno degazio:
> On Saturday, 19 October 2019 15:11:42 UTC-4, Gerry Jackson wrote:
>
> What is the expected performance difference between this approach and a the common CASE implementation?

What is "common" for "CASE"?
Today a good compiler structure optimized out IF-constructs that follow right after the other.
Eaker-CASE is for the "OF"-word, that is basically "OVER = IF DROP", more or less a syntactical sugar for consequent IF-constructs.

Regards,
-Helmar

A. K.

unread,
Oct 21, 2019, 11:00:38 AM10/21/19
to
Am Montag, 21. Oktober 2019 16:21:09 UTC+2 schrieb bruno degazio:
> On Saturday, 19 October 2019 15:11:42 UTC-4, Gerry Jackson wrote:
>
> What is the expected performance difference between this approach and a the common CASE implementation?

There are too many implementation options to give a meaningful answer.

F.ex. MinForth transpiles Forth to C code. Throw that at a good C compiler
and enable optimization with -O2 ...

bruno degazio

unread,
Oct 21, 2019, 11:56:12 AM10/21/19
to
Sorry to be vague in my query, not a Forth implementor myself. I guess what was on my mind were the CASE implementations in VFX and IFORTH.

Gerry Jackson

unread,
Oct 21, 2019, 1:06:54 PM10/21/19
to
On 21/10/2019 15:21, bruno degazio wrote:
> On Saturday, 19 October 2019 15:11:42 UTC-4, Gerry Jackson wrote:
>
> What is the expected performance difference between this approach and a the common CASE implementation?
>

In general if the selecting value is an integer (or character) the
CHOOSE/SWITCH approach would be quicker as using the integer as an index
into a table of instruction addresses would usually be quicker than a
series of IF statements which is how the OF ... ENDOF parts of CASE are
usually implemented. How much quicker is impossible to say as it depends
on the particular application.

The worst case time for CASE is where none of the cases are met and
every possibility is tried. CHOOSE doesn't have that problem.

Another issue is that CASE statements are more general than CHOOSE and
can be used where CHOOSE is inappropriate.

--
Gerry

dxforth

unread,
Oct 21, 2019, 9:19:29 PM10/21/19
to
ANS forths have little option but to supply Eaker-based Case i.e. IF ELSE
due to the syntax rules. While there is nothing stopping them providing
additional Case constructs, few do due to the lack of demand.

hughag...@gmail.com

unread,
Oct 22, 2019, 12:24:59 AM10/22/19
to
On Monday, October 21, 2019 at 4:21:11 AM UTC-7, Gerry Jackson wrote:
> On 21/10/2019 00:51, hughag...@gmail.com wrote:
> > Now Gerry Jackson is hoping that Michail Gassanenko can rescue
> > the Forth-200x committee from their pit of incompetence by providing
> > them with a CHOOSE that generates and uses a jump-table.
> > This is their best hope for meeting my criteria for success!
> > With a little help from Russia the Forth-200x committee can succeed!
> > ...
>
> I've never examined your switch construct or passed any opinion on it.
> Looking at the above it is not clear to me how your switch construct is
> actually used. You didn't provide an example of usage and a quick search
> of c.l.f. didn't find an example.
>
> A simple example using MLG's CHOOSE is:
>
> : test
> choose
> 1 when 1111 . end
> 7 9 ... 12 when 3333 . end
> 2 3 when 2222 . end
> other 7777 . end \ Any other integer - the default
> end
> ;
>
> where the word ... denotes a range
> \ Testing with GForth
> 1 test \ displays 1111
> 2 test \ displays 2222
> 3 test \ displays 2222
> 10 test \ displays 3333
> 99 test \ displays 7777
>
> How would you write an equivalent using your FAST-SWITCH>, SLOW_SWITCH> etc?

You aren't asking for a demonstration of my FAST-SWITCH and SLOW-SWITCH>
because you are interested in the code. You just want to attack it.
You always attack, attack, attack...

MLG's WHEN apparently uses DEPTH to allow it to have a variable
number of parameters. You can attack me for not doing this.
That would be a good start for you.

Here is a demonstration:
--------------------------------------------------------------------------
<switch
:noname drop 1111 . ; 1 case-of
:noname drop 3333 . ; 7 case-of
:noname drop 3333 . ; 9 12 range-of
:noname drop 2222 . ; 2 3 range-of
:noname drop 7777 . ; fast-switch> ggg ( n -- )

<switch
:noname drop 1111 . ; s| .,!?'";:[]()@#$%&| chars-of
:noname drop 2222 . ; -2999 -2000 range-of
:noname drop 3333 . ; alpha-of
:noname ." invalid #: " . ; fast-switch> ccc ( n -- )
--------------------------------------------------------------------------

This is a test run:
--------------------------------------------------------------------------
1 ggg 1111 ok
2 ggg 2222 ok
3 ggg 2222 ok
10 ggg 3333 ok
99 ggg 7777 ok
ok
char ? ccc 1111 ok
char M ccc 3333 ok
char m ccc 3333 ok
char 9 ccc invalid #: 57 ok
-2500 ccc 2222 ok
-3500 ccc invalid #: -3500 ok
2500 ccc invalid #: 2500 ok
--------------------------------------------------------------------------

CCC is slightly more complicated. It has negatives and sets of chars.
There are lots of ways to use RANGE-OF --- my ALPHA-OF and CHARS-OF
use RANGE-OF internally --- the user can do this too.

SLOW-SWITCH> is the same as FAST-SWITCH> except that you get a
binary search rather than an indexed jump-table.
FAST-SWITCH> is limited to tables of 64K total range and gives an
error message if the jump-table is too big, in which case you use
SLOW-SWITCH> instead. You may also use SLOW-SWITCH> if your switch
is not time-critical and you want to save memory.

I also have DXForth's suggested CASE: that uses CASE-OF internally:
--------------------------------------------------------------------------
<switch
13 case: cr . ." is the 6th prime number." ;;
2 case: cr . ." is the 1st prime number." ;;
3 case: cr . ." is the 2nd prime number." ;;
5 case: cr . ." is the 3rd prime number." ;;
7 case: cr . ." is the 4th prime number." ;;
11 case: cr . ." is the 5th prime number." ;;
17 case: cr . ." is the 7th prime number." ;;
19 case: cr . ." is the 8th prime number." ;;
23 case: cr . ." is the 9th prime number." ;;
-2 case: cr . ." a negative is invalid." ;;
:noname cr . ." is not in our list of primes." ; fast-switch> ddd ( n -- )
--------------------------------------------------------------------------

This syntax may be more readable when you don't have ranges.
This would likely be the best choice for a VM simulator in which
each item is an opcode. Simulating a VM is the primary purpose of this.

Gerry Jackson

unread,
Oct 22, 2019, 2:30:46 AM10/22/19
to
Thank you for providing this, it makes things a lot clearer. I wasn't
attacking you, just interested in an alternative solution.

My quick conclusion is that your <SWITCH is more versatile as it
provides a wider variety of selectors e.g. characters in a string etc;
and alternative ways to make a selection - FAST-SWITCH> SLOW-SWITCH
CASE:. OTOH MLG's CHOOSE has a cleaner syntax.

I would guess that your code is easier to maintain/extend as MLG's code,
unsurprisingly, uses return stack manipulation extensively which, to me
at least, makes it difficult to understand.

--
Gerry

dxforth

unread,
Oct 22, 2019, 8:31:57 PM10/22/19
to
On Tuesday, 22 October 2019 17:30:46 UTC+11, Gerry Jackson wrote:
> ...
> OTOH MLG's CHOOSE has a cleaner syntax.

And one that's potentially compatible with ANS' syntax. I don't
recall seeing CHOOSE before this and was struck how similar your
example appeared to what I might write using 'Miser's Case':

: test
1 of 1111 . end
cond
7 equal
9 12 range when 3333 . end
cond
2 equal
3 equal when 2222 . end
drop 7777 . \ Any other integer - the default
;

In the above END is just EXIT THEN. If a common exit point was
needed it would be written:

: test2
cond
1 of 1111 . else
cond
7 equal
9 12 range when 3333 . else
cond
2 equal
3 equal when 2222 . else
drop 7777 . \ Any other integer - the default
cont
;

where COND ELSE is ANS' CASE ENDOF respectively, and CONT a non-
DROPing ENDCASE.

I have to admit I've rarely used these extensions as the need almost
never arises - despite nearly every application I've written using
'case' and sometimes many times over.

hughag...@gmail.com

unread,
Oct 22, 2019, 8:40:51 PM10/22/19
to
On Monday, October 21, 2019 at 11:30:46 PM UTC-7, Gerry Jackson wrote:
> I would guess that your code is easier to maintain/extend as MLG's code,
> unsurprisingly, uses return stack manipulation extensively which, to me
> at least, makes it difficult to understand.

I haven't seen MLG's code. Where can I download it?
I don't know why it:
"unsurprisingly, uses return stack manipulation extensively."
I would have to know more about what he is doing in order to
be surprised or not surprised about return-stack manipulation.

I do use some return-stack manipulation in SLOW-SEARCH because
locals are very slow under SwiftForth:
--------------------------------------------------------------
char & comment \ this is a version of SLOW-SEARCH that uses locals, which are slow under SwiftForth

: slow-search { array limit target | mid-element -- element|false } \ hard-coded for use by SLOW-SWITCH>
limit begin dup while \ -- limit
dup 1 rshift \ -- limit mid
dup d * array + to mid-element \ MID-ELEMENT is a pointer into the array
target mid-element @ = if 2drop mid-element exit then \ if found, return MID-ELEMENT
target mid-element @ < if \ search left side
nip \ -- new-limit \ MID is the new limit
else \ search right side
mid-element d + to array \ new ARRAY is one element above MID-ELEMENT
1+ - \ -- new-limit \ the 1+ is so we don't include the middle element
then
repeat ; \ -- false \ LIMIT is zero, so return it as a FALSE flag

&

: slow-search ( array limit target -- element|false ) \ hard-coded for use by SLOW-SWITCH>
>r \ -- array limit \ return: -- target
begin dup while
dup 1 rshift \ -- array limit mid
dup d * fourth + \ -- array limit mid mid-element
r@ over @ = if nip nip nip rdrop exit then \ if found, return MID-ELEMENT
r@ over @ < if \ search left side
drop nip \ -- array mid \ MID is the new limit
else
d + >r \ -- array limit mid \ return: -- target new-array \ NEW-ARRAY is one element above middle element
1+ - \ -- array new-limit \ the 1+ is so we don't include the middle element
nip r> swap \ -- new-array new-limit \ MID-ELEMENT is the new ARRAY
then
repeat \ LIMIT is zero, so it can be used as a FALSE flag
nip rdrop ; \ -- false

\ SLOW-SEARCH assumes that the array element is D in size (two cells),
\ and the first cell is the integer that we are comparing against.
--------------------------------------------------------------

I really doubt that MLG's code is ANS-Forth.
I don't know how he manages to put his CHOOSE inside of a colon
definition. I couldn't figure out any way to do this.
I don't think this is possible in ANS-Forth because there are
no quotations. I have rquotations, but their address (called an
rq rather than an xt) is determined at run-time, not compile-time,
so there is no way to build a jump-table at compile-time.

There are ways to fake something like quotations. For example,
[ HERE ] may provide the address of the code at that point,
unless it doesn't. This isn't guaranteed in ANS-Forth.
I wouldn't have expected this to work in VFX because I assumed
that VFX didn't generate any code until the semicolon.
It does work though:
--------------------------------------------------------------
: ttt [ cr here h. ] 123 . [ cr here h. ] 456 . [ cr here h. ] 789 . [ cr here h. ] ;
004F,8DB0
004F,8DC0
004F,8DD0
004F,8DE0 ok
see ttt
TTT
( 004F8DB0 8D6DFC ) LEA EBP, [EBP+-04]
( 004F8DB3 895D00 ) MOV [EBP], EBX
( 004F8DB6 BB7B000000 ) MOV EBX, 0000007B
( 004F8DBB E8E035F1FF ) CALL 0040C3A0 .
( 004F8DC0 8D6DFC ) LEA EBP, [EBP+-04]
( 004F8DC3 895D00 ) MOV [EBP], EBX
( 004F8DC6 BBC8010000 ) MOV EBX, 000001C8
( 004F8DCB E8D035F1FF ) CALL 0040C3A0 .
( 004F8DD0 8D6DFC ) LEA EBP, [EBP+-04]
( 004F8DD3 895D00 ) MOV [EBP], EBX
( 004F8DD6 BB15030000 ) MOV EBX, 00000315
( 004F8DDB E8C035F1FF ) CALL 0040C3A0 .
( 004F8DE0 C3 ) NEXT,
( 49 bytes, 13 instructions )
ok
--------------------------------------------------------------
As I said though, this is not guaranteed to work in ANS-Forth,
so if MLG is doing this, his code is not ANS-Forth (even though
it apparently works under Gforth). I can write code similar to
MLG's in VFX, but I don't because I want the novice-package to be
ANS-Forth --- there is no guarantee that this will continue
to work in future versions of VFX as it is an undocumented feature.

My <SWITCH generates a colon word, but it isn't inside of a
colon word. Because of this, the many clauses of the jump-table
can't share local variables of a parent function the way that
the clauses in a C-language SWITCH share locals. They can only
use global variables, which is pretty crude. For my purpose,
which is supporting simulation of a VM, the lack of reentrancy
doesn't matter very much because there is only one simulation
going on at any particular time. Still though, it is pretty crude.

Gerry Jackson

unread,
Oct 23, 2019, 3:03:31 PM10/23/19
to
On 23/10/2019 01:40, hughag...@gmail.com wrote:
> On Monday, October 21, 2019 at 11:30:46 PM UTC-7, Gerry Jackson wrote:
>> I would guess that your code is easier to maintain/extend as MLG's code,
>> unsurprisingly, uses return stack manipulation extensively which, to me
>> at least, makes it difficult to understand.
>
> I haven't seen MLG's code. Where can I download it?

dfxforth provided a link in a response to my first post, repeated here
for convenience:
https://web.archive.org/web/20100222005251/http://www.forth.org.ru/~mlg/SrcLib/choose/choose.htm
That html document contains a link to choose.fth which displays as text
with no line feeds, so you need to do a "Save link as ..." in your browser.
The html document also contains all the code and describes the design in
much detail.

> I don't know why it:
> "unsurprisingly, uses return stack manipulation extensively."

Michael Gassanenko wrote some papers for Euroforth in the 1990's and
2000's describing how to use return stack manipulation for backtracking
and different control structures e.g.:
START ... DIVE ... EMERGE ...
BACK ... TRACKING ...

For how these work see the whole discussion on c.l.f.
https://groups.google.com/forum/?hl=en#!searchin/comp.lang.forth/start$20emerge$20dive/comp.lang.forth/uKNcMBSkDUA/kJVgKRypM_kJ
Message ID: <32ffd8c5.02041...@posting.google.com>

Also you can find some of MLG's papers at:
https://web.archive.org/web/20091219055739/http://www.forth.org.ru/~mlg/
(see BacForth)

> I would have to know more about what he is doing in order to
> be surprised or not surprised about return-stack manipulation.

He seemed to be a keen proponent of the technique but doesn't seem to be
actively using Forth any longer.
It doesn't conform to ANS Forth and this is stated in the choose
document. He mentions the techniques are 'de facto portable' and there
is some truth in this e.g. the code works on GForth, VFX Forth,
SwiftForth and Win32Forth. But not on my system where I have separate
data and code space.

> I don't know how he manages to put his CHOOSE inside of a colon
> definition. I couldn't figure out any way to do this.
> I don't think this is possible in ANS-Forth because there are
> no quotations. I have rquotations, but their address (called an
> rq rather than an xt) is determined at run-time, not compile-time,
> so there is no way to build a jump-table at compile-time.
>
> There are ways to fake something like quotations. For example,
> [ HERE ] may provide the address of the code at that point,

Yes, I think that is what he uses.
--
Gerry

Rick C

unread,
Oct 23, 2019, 6:10:18 PM10/23/19
to
On Wednesday, October 23, 2019 at 3:03:31 PM UTC-4, Gerry Jackson wrote:
> On 23/10/2019 01:40, hughag...@gmail.com wrote:
> > On Monday, October 21, 2019 at 11:30:46 PM UTC-7, Gerry Jackson wrote:
> >> I would guess that your code is easier to maintain/extend as MLG's code,
> >> unsurprisingly, uses return stack manipulation extensively which, to me
> >> at least, makes it difficult to understand.
> >
> > I haven't seen MLG's code. Where can I download it?
>
> dfxforth provided a link in a response to my first post, repeated here
> for convenience:
> https://web.archive.org/web/20100222005251/http://www.forth.org.ru/~mlg/SrcLib/choose/choose.htm
> That html document contains a link to choose.fth which displays as text
> with no line feeds, so you need to do a "Save link as ..." in your browser.
> The html document also contains all the code and describes the design in
> much detail.

Easier, you can open the source in the browser which will display as one, long, run-on line. Then right click and 'view source'. In Firefox at least that displays with line numbers and line breaks.

Just my two cents worth.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209

dxforth

unread,
Oct 23, 2019, 7:09:26 PM10/23/19
to
On Thursday, October 24, 2019 at 9:10:18 AM UTC+11, Rick C wrote:
> On Wednesday, October 23, 2019 at 3:03:31 PM UTC-4, Gerry Jackson wrote:
> > On 23/10/2019 01:40, hughag...@gmail.com wrote:
> > > On Monday, October 21, 2019 at 11:30:46 PM UTC-7, Gerry Jackson wrote:
> > >> I would guess that your code is easier to maintain/extend as MLG's code,
> > >> unsurprisingly, uses return stack manipulation extensively which, to me
> > >> at least, makes it difficult to understand.
> > >
> > > I haven't seen MLG's code. Where can I download it?
> >
> > dfxforth provided a link in a response to my first post, repeated here
> > for convenience:
> > https://web.archive.org/web/20100222005251/http://www.forth.org.ru/~mlg/SrcLib/choose/choose.htm
> > That html document contains a link to choose.fth which displays as text
> > with no line feeds, so you need to do a "Save link as ..." in your browser.
> > The html document also contains all the code and describes the design in
> > much detail.
>
> Easier, you can open the source in the browser which will display as one, long, run-on line. Then right click and 'view source'. In Firefox at least that displays with line numbers and line breaks.

For an archive site it ought to be as easy as clicking a button. Supposedly
they have a website downloader though when I tried it nothing happened.
Eventually discovered the workaround you mention above.

Rick C

unread,
Oct 23, 2019, 11:18:01 PM10/23/19
to
Not sure what you are talking about. The problem is the file is archived *exactly* like the original with Linux new lines rather than DOS CRLF.

You think they should have altered the file?

--

Rick C.

+ Get 1,000 miles of free Supercharging
+ Tesla referral code - https://ts.la/richard11209

dxforth

unread,
Oct 23, 2019, 11:48:05 PM10/23/19
to
On Thursday, October 24, 2019 at 2:18:01 PM UTC+11, Rick C wrote:
> On Wednesday, October 23, 2019 at 7:09:26 PM UTC-4, dxforth wrote:
> > ...
> > For an archive site it ought to be as easy as clicking a button. Supposedly
> > they have a website downloader though when I tried it nothing happened.
> > Eventually discovered the workaround you mention above.
>
> Not sure what you are talking about. The problem is the file is archived *exactly* like the original with Linux new lines rather than DOS CRLF.
>
> You think they should have altered the file?

They don't provide the HMTL file - which is the problem.

Rick C

unread,
Oct 24, 2019, 12:39:17 AM10/24/19
to
What HTML file? They provide what they were provided with. Do you mean the HTML file that has the link to the .fth file? How else did you get to the .fth file?

--

Rick C.

-- Get 1,000 miles of free Supercharging
-- Tesla referral code - https://ts.la/richard11209

dxforth

unread,
Oct 24, 2019, 1:37:21 AM10/24/19
to
On Thursday, October 24, 2019 at 3:39:17 PM UTC+11, Rick C wrote:
> On Wednesday, October 23, 2019 at 11:48:05 PM UTC-4, dxforth wrote:
> > On Thursday, October 24, 2019 at 2:18:01 PM UTC+11, Rick C wrote:
> > > On Wednesday, October 23, 2019 at 7:09:26 PM UTC-4, dxforth wrote:
> > > > ...
> > > > For an archive site it ought to be as easy as clicking a button. Supposedly
> > > > they have a website downloader though when I tried it nothing happened.
> > > > Eventually discovered the workaround you mention above.
> > >
> > > Not sure what you are talking about. The problem is the file is archived *exactly* like the original with Linux new lines rather than DOS CRLF.
> > >
> > > You think they should have altered the file?
> >
> > They don't provide the HMTL file - which is the problem.
>
> What HTML file?

mlg's choose.htm

> They provide what they were provided with.

They don't provide choose.htm. All they do is present the viewer
with a window of the same name whereby he can see choose.htm.
If he tries to 'Save HTML page' with his browser all he'll get is the
window. That you found a way around this impasse and were able
to extract choose.htm proper from archive.org is your good fortune.
Point is they didn't provide it to you - and for all anyone knows it's
not clear whether one is entitled to extract it.

> Do you mean the HTML file that has the link to the .fth file? How else did you get to the .fth file?

That file (choose.fth) was at least was readily downloadable.

Rick C

unread,
Oct 24, 2019, 2:50:14 AM10/24/19
to
On Thursday, October 24, 2019 at 1:37:21 AM UTC-4, dxforth wrote:
> On Thursday, October 24, 2019 at 3:39:17 PM UTC+11, Rick C wrote:
> > On Wednesday, October 23, 2019 at 11:48:05 PM UTC-4, dxforth wrote:
> > > On Thursday, October 24, 2019 at 2:18:01 PM UTC+11, Rick C wrote:
> > > > On Wednesday, October 23, 2019 at 7:09:26 PM UTC-4, dxforth wrote:
> > > > > ...
> > > > > For an archive site it ought to be as easy as clicking a button. Supposedly
> > > > > they have a website downloader though when I tried it nothing happened.
> > > > > Eventually discovered the workaround you mention above.
> > > >
> > > > Not sure what you are talking about. The problem is the file is archived *exactly* like the original with Linux new lines rather than DOS CRLF.
> > > >
> > > > You think they should have altered the file?
> > >
> > > They don't provide the HMTL file - which is the problem.
> >
> > What HTML file?
>
> mlg's choose.htm

Yes, this one that contains the link to choose.fth

https://web.archive.org/web/20100222005251if_/http://www.forth.org.ru:80/~mlg/SrcLib/choose/choose.htm


> > They provide what they were provided with.
>
> They don't provide choose.htm. All they do is present the viewer
> with a window of the same name whereby he can see choose.htm.

I don't know what you are talking about. I found the choose.htm page. I think you don't realize what you are looking at.


> If he tries to 'Save HTML page' with his browser all he'll get is the
> window. That you found a way around this impasse and were able
> to extract choose.htm proper from archive.org is your good fortune.

You just have to open the .htm file separately by right clicking and selecting "Show only this frame".


> Point is they didn't provide it to you - and for all anyone knows it's
> not clear whether one is entitled to extract it.

"Entitled"??? Not sure what you are talking about.


> > Do you mean the HTML file that has the link to the .fth file? How else did you get to the .fth file?
>
> That file (choose.fth) was at least was readily downloadable.

Yeah, so what's the real problem???

--

Rick C.

-+ Get 1,000 miles of free Supercharging
-+ Tesla referral code - https://ts.la/richard11209

Gerry Jackson

unread,
Oct 24, 2019, 3:09:07 AM10/24/19
to
On 23/10/2019 01:31, dxforth wrote:
> On Tuesday, 22 October 2019 17:30:46 UTC+11, Gerry Jackson wrote:
>> ...
>> OTOH MLG's CHOOSE has a cleaner syntax.
>
> And one that's potentially compatible with ANS' syntax. I don't
> recall seeing CHOOSE before this and was struck how similar your
> example appeared to what I might write using 'Miser's Case':
>
> : test
> 1 of 1111 . end
> cond
> 7 equal
> 9 12 range when 3333 . end
> cond
> 2 equal
> 3 equal when 2222 . end
> drop 7777 . \ Any other integer - the default
> ;
>

Yes, that's interesting. MLG's CHOOSE works at a higher level, removing
the need for words COND and EQUAL and RANGE. This is at the cost of
using and generating non-standard Forth - using ANS standard words (such
as R> >R R@ HERE) but in a non-standard way where behaviour is not
guaranteed but does work in several systems.

> I have to admit I've rarely used these extensions as the need almost
> never arises - despite nearly every application I've written using
> 'case' and sometimes many times over.
>

My experience is similar, I was just looking at this out of interest.

--
Gerry

dxforth

unread,
Oct 24, 2019, 4:40:58 AM10/24/19
to
On Thursday, October 24, 2019 at 5:50:14 PM UTC+11, Rick C wrote:
> On Thursday, October 24, 2019 at 1:37:21 AM UTC-4, dxforth wrote:
> > ...
> > mlg's choose.htm
>
> Yes, this one that contains the link to choose.fth
>
> https://web.archive.org/web/20100222005251if_/http://www.forth.org.ru:80/~mlg/SrcLib/choose/choose.htm

> ...
> "Entitled"??? Not sure what you are talking about.

Did archive.org make available the link above? If not then not only haven't
they made the file available, it's questionable users are entitled to d/load it.

Rick C

unread,
Oct 24, 2019, 11:22:50 AM10/24/19
to
Sorry, I don't understand your question the way you are asking it. What do you mean by "make available"? The link is hosted by archive.org. The link works, so it is available, no?

Are you talking about copyright? No, archive.org doesn't get involved in copyright issues. If someone claims a copyright violation they remove material from their web site. Is that what you are talking about?

--

Rick C.

+- Get 1,000 miles of free Supercharging
+- Tesla referral code - https://ts.la/richard11209

dxforth

unread,
Oct 24, 2019, 8:45:32 PM10/24/19
to
On Friday, October 25, 2019 at 2:22:50 AM UTC+11, Rick C wrote:
> ...
> What do you mean by "make available"? The link is hosted by archive.org. The link works, so it is available, no?

It's not hosted if it required a html source debugger to access it.

>
> Are you talking about copyright?

A website's conditions of use at least.

dxforth

unread,
Oct 24, 2019, 9:29:33 PM10/24/19
to
On Thursday, October 24, 2019 at 6:09:07 PM UTC+11, Gerry Jackson wrote:
> ...
> Yes, that's interesting. MLG's CHOOSE works at a higher level, removing
> the need for words COND and EQUAL and RANGE. This is at the cost of
> using and generating non-standard Forth - using ANS standard words (such
> as R> >R R@ HERE) but in a non-standard way where behaviour is not
> guaranteed but does work in several systems.

Simply the possibility of having a table-driven case that's backward
compatible with ANS syntax is virtue enough. Nice if it can be done
portably but not essential.

Rick C

unread,
Oct 25, 2019, 12:01:09 AM10/25/19
to
You snipped everything so I have no idea what you are replying to. Not worth the trouble of digging through old messages. You are upset about something bizarre that is some minor inconvenience. Ok, got it. I have lots of those too. Want to hear about them?

--

Rick C.

++ Get 1,000 miles of free Supercharging
++ Tesla referral code - https://ts.la/richard11209
Message has been deleted

bruce.m...@gmail.com

unread,
Nov 16, 2019, 10:46:45 PM11/16/19
to
It can't be done portably, as sometimes the instruction pointer is a separate register that is popped from and pushed onto the return stack and sometimes the instruction pointer is the top of the return stack. So while they worked for the then current gforth, for SwiftForth 6 and for VFXForth, they might not work for all Forth's aligned with the ANS Forth standard.

But with implementation specific knowledge, an ``enter'' and a ``give>'' could be written for the implementation that cannot use R> and >R directly. May also have to port ``mix>ranges'' ``retrieve-interval'' and ``(choose)'', but on a quick search that looks like that's it as far as words that use ``R>'' ``>R'' and ``R@'' directly.

I don't know what non-standard use of HERE is being done, but that would be a bigger porting challenge if it's a problem for a particular implementation, since HERE is scattered all through the code.

bruce.m...@gmail.com

unread,
Nov 16, 2019, 10:59:42 PM11/16/19
to
On Thursday, October 24, 2019 at 4:40:58 PM UTC+8, dxforth wrote:
> On Thursday, October 24, 2019 at 5:50:14 PM UTC+11, Rick C wrote:
> > On Thursday, October 24, 2019 at 1:37:21 AM UTC-4, dxforth wrote:
> > > ...
> > > mlg's choose.htm
> >
> > Yes, this one that contains the link to choose.fth
> >
> > https://web.archive.org/web/20100222005251if_/http://www.forth.org.ru:80/~mlg/SrcLib/choose/choose.htm
>
> > ...
> > "Entitled"??? Not sure what you are talking about.

> Did archive.org make available the link above?

The full link? They would have had to, if they are archiving material from the web, they have to make available the URL to access the material that they have archived.

The link embedded in their link? The whole point of the project is to preserve material that would otherwise be lost ... if the original link embedded in their link still pointed to the original material, it would not have been necessary to use the wayback machine.

The CONTENTS REFERRED TO by the link? It was originally posted for free public use and the code contents are GPL'd, it would be a reasonable presumption that the author is OK with it being maintained in an archive of that site.

> If not then not only haven't they made the file available, it's questionable users are entitled to d/load it.

Except they literally made the file available, which is why it is possible to read the page on the wayback machine when the site that hosted the material is no longer in business.

Users are certainly entitled to download it, what it open to question is their entitlement to redistribute it. A page containing literate programming code that is explicitly GPL'd, where the page is posted for open access and no explicit restrictions placed on it's redistribution strongly suggests that the author doesn't mind, but if the author objects to that presumption they are certainly in their rights to ask that the archived material be taken down.

dxforth

unread,
Nov 17, 2019, 1:04:19 AM11/17/19
to
On Sunday, November 17, 2019 at 2:59:42 PM UTC+11, bruce.m...@gmail.com wrote:
> ...
> Users are certainly entitled to download it, what it open to question is their entitlement to redistribute it.

Based on current experience they no longer do. OTOH they point you to commercial
sites that apparently will.

https://help.archive.org/hc/en-us/articles/360001834411-Can-I-rebuild-my-website-using-the-Wayback-Machine-

bruce.m...@gmail.com

unread,
Nov 18, 2019, 2:30:03 AM11/18/19
to
My "their" in that sentence was a reference to "Users are...", not to the wayback archive.

The wayback archive IS redistributing the content that they archive when users search for it and find it.

But they don't offer the service of walking through their archive to reconstruct a site based on whatever they have archived from a given site ... that is what the commercial services are doing.

Gerry Jackson

unread,
Nov 18, 2019, 4:57:36 AM11/18/19
to
I managed to get it working on my system. Use of the return stack was no
problem. I had two other problems to solve:

- code space separated from dataspace. The original had the jump table
embedded in the code. Moving it into dataspace, where it belongs,
simplified the code a bit

- my system compiles code in two stages, firstly to an intermediate code
and then to actual code, so HERE, which is always (I think) used to
obtain an address in the code (non-standard usage of course) didn't work
as there was no code address available in the first stage of
compilation. That was much harder to solve.


--
Gerry

Gerry Jackson

unread,
Jun 10, 2020, 5:34:55 PM6/10/20
to
On 19/10/2019 20:11, Gerry Jackson wrote:
> I came across this post in c.l.f.
>
> https://groups.google.com/forum/?hl=en#!searchin/comp.lang.forth/choose.htm%7Csort:date/comp.lang.forth/ZGCesckN0qI/zUh5IYNaa_UJ
>
>
> Message-ID:
> <594fc8e8-f584-40e0...@b15g2000yqd.googlegroups.com>
>
> Unfortunately the link to choose.htm in that post doesn't work, it goes
> to a Russian site with, I think, a page not found message.
>
> I cannot find the file choose.htm anywhere on the internet - does anyone
> know where a copy can be found?
>

I've been meaning to do this for some weeks and just got around to it.
I've written an ANS/Forth 2012 equivalent (nearly) to Michael
Gassanenko's (MLG) choose, and called it switch.

It can be downloaded from https://github.com/gerryjackson/Forth-switch

The main difference is that it is a defining word with syntax:

create-switch <name>
<values-1> when <actions-1-1> end
<values-2> when <actions-2> end
.....
<values-n> when <actions-n> end
other <default-action> end
end

As in MLG's implementation the switch selectors are accumlated on the
stack and processed when the final END is reached. However I found a
simpler method of handling the complex mixture of integers and ranges.
This resulted in less code, e.g. with GForth MLG's version compiled into
673 cells whereas mine occcupies 595 cells.

I found that I couldn't write an exact equivalent to MLG's version (as a
control structure within another Forth definition) in standard Forth
without going to unreasonable lengths. However it can be done with a
system where a [: ... ;] quotation returns an xt in interpretive mode
i.e. behaves as :NONAME but this is undefined behaviour in Forth 200X.

At some stage I'll probably add two alternative versions, one for a
sparse set of selectors using a binary search or hashing, the other for
the common case where each WHEN has only one integer selector.

--
Gerry

A. K.

unread,
Jun 10, 2020, 6:13:02 PM6/10/20
to
Must be about 30y ago that I wrote in a F83-variant a similare CASE- (or SWITCH-
like) construct comprising
- compiling :NONAMES from the code between OFs and ENDOFs
- each OF incremented an offset counter to its noname in the later jump table
- ENDCASE creating that jump table to those nonames, offset generated by OFs
- and ENDCASE resolving forward jumps from preceding OFs to the jump table.

It worked, but I found it too convoluted in the end. Speedwise there was no
measurable advantage. Overoptimization can be counterproductive.

BTW I find a string-OF variant very useful occasionally:
( .. a u )
CASE
OF" teststring1" .. ENDOF
OF" teststring2" .. ENDOF
..
ENDCASE

a...@littlepinkcloud.invalid

unread,
Jun 11, 2020, 6:22:23 AM6/11/20
to
Gerry Jackson <do-no...@swldwa.uk> wrote:
>
> I've been meaning to do this for some weeks and just got around to it.
> I've written an ANS/Forth 2012 equivalent (nearly) to Michael
> Gassanenko's (MLG) choose, and called it switch.
>
> It can be downloaded from https://github.com/gerryjackson/Forth-switch
>
> The main difference is that it is a defining word with syntax:
>
> create-switch <name>
> <values-1> when <actions-1-1> end
> <values-2> when <actions-2> end
> .....
> <values-n> when <actions-n> end
> other <default-action> end
> end

No criticism intended, but this does look remarkably similar to Rick
VanNorman's [SWITCH statement. As I've argued elsethread, I'm
convinced this is the right way to do switches in Forth.

Andrew.

dxforth

unread,
Jun 11, 2020, 7:22:22 AM6/11/20
to
Not sure even Rick VanNorman saw it as the "right way". Writing in
FD V20N3 he says he was satisfying a particular need:

"The ANS-Forth-suggested case statement implementation of the above
code C might look like Listing Two. The execution-time behavior of CASE
and OF can be optimized until your system implementor is exhausted and
performance will be similar to that of the C version.

Given this, why would anyone want to implement a new switch construct in
Forth? For SwiftForth, the reason was the need for extensibility - to be able
to define the base structure and to extend it at will. The traditional CASE
statement does not lend itself to being extended after it is defined."

none albert

unread,
Jun 11, 2020, 8:05:47 AM6/11/20
to
In article <154778d2-3139-467b...@googlegroups.com>,
The above contains far too many new keywords and requires a dictionary
entry without functions.

I would use a compiling word that temporarily switches to interpreting
state
SWITCH
<eval1> [: ... ;]
<eval2> [: ... ;]
<eval3> [: ... ;]
<eval4> [: ... ;]
ENDSWITCH

END-SWITCH finds 4 int's and 4 xt's on the stack and does
its thing. It can analyse the int's whether they are sufficiently
close to make a jump table, order them, organize them in
for a binary search or even (like suggested in the compiler
guide for the transputer) separate in a parts that are treated differently.

Of course in ciforth I would use { } and it would look even better.
SWITCH
1 { + }
2 { * }
3 { - }
4 { / }
ENDSWITCH

This is all rather futile if you have a proper optimiser that
can cut through nested IF ELSE constructs and find opportunities
that would take a lifetime to debug, if done manually.

Groetjes Albert
--
This is the first day of the end of your life.
It may not kill you, but it does make your weaker.
If you can't beat them, too bad.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

a...@littlepinkcloud.invalid

unread,
Jun 11, 2020, 8:43:46 AM6/11/20
to
dxforth <dxf...@gmail.com> wrote:
> On Thursday, June 11, 2020 at 8:22:23 PM UTC+10, a...@littlepinkcloud.invalid wrote:
>> Gerry Jackson <do-no...@swldwa.uk> wrote:
>> >
>> > I've been meaning to do this for some weeks and just got around to it.
>> > I've written an ANS/Forth 2012 equivalent (nearly) to Michael
>> > Gassanenko's (MLG) choose, and called it switch.
>> >
>> > It can be downloaded from https://github.com/gerryjackson/Forth-switch
>> >
>> > The main difference is that it is a defining word with syntax:
>> >
>> > create-switch <name>
>> > <values-1> when <actions-1-1> end
>> > <values-2> when <actions-2> end
>> > .....
>> > <values-n> when <actions-n> end
>> > other <default-action> end
>> > end
>>
>> No criticism intended, but this does look remarkably similar to Rick
>> VanNorman's [SWITCH statement. As I've argued elsethread, I'm
>> convinced this is the right way to do switches in Forth.
>
> Not sure even Rick VanNorman saw it as the "right way". Writing in
> FD V20N3 he says he was satisfying a particular need:

I guess he wasn't, but I am. It ticks all the boxes; the only thing
really wrong AFAICS is that it can't be used inside a definition, but
otherwise it's fine, and I don't think that's such a big deal.

Andrew.

Gerry Jackson

unread,
Jun 11, 2020, 12:13:14 PM6/11/20
to
On 11/06/2020 12:22, dxforth wrote:
> On Thursday, June 11, 2020 at 8:22:23 PM UTC+10, a...@littlepinkcloud.invalid wrote:
>> Gerry Jackson <do-no...@swldwa.uk> wrote:
>>>
>>> I've been meaning to do this for some weeks and just got around to it.
>>> I've written an ANS/Forth 2012 equivalent (nearly) to Michael
>>> Gassanenko's (MLG) choose, and called it switch.
>>>
>>> It can be downloaded from https://github.com/gerryjackson/Forth-switch
>>>
>>> The main difference is that it is a defining word with syntax:
>>>
>>> create-switch <name>
>>> <values-1> when <actions-1-1> end
>>> <values-2> when <actions-2> end
>>> .....
>>> <values-n> when <actions-n> end
>>> other <default-action> end
>>> end
>>
>> No criticism intended, but this does look remarkably similar to Rick
>> VanNorman's [SWITCH statement. As I've argued elsethread, I'm
>> convinced this is the right way to do switches in Forth.
>>
>> Andrew.

I was just implementing the nearest I could get to MLG's CHOOSE in
standard Forth - an interesting challenge. Perhaps he was influenced by
Rick VanNorman's [SWITCH

>
> Not sure even Rick VanNorman saw it as the "right way". Writing in
> FD V20N3 he says he was satisfying a particular need:
>
> "...
>
> Given this, why would anyone want to implement a new switch construct in
> Forth? For SwiftForth, the reason was the need for extensibility - to be able
> to define the base structure and to extend it at will. The traditional CASE
> statement does not lend itself to being extended after it is defined."
>

It's easy enough to extend a CASE statement.

If the order of evaluation isn't important, put the first CASE in a
colon definition and have the case extension call the first one as its
default action. If the order is important have the first one's default
call the second via a deferred word initialised to DROP. So easy it
doesn't need a special syntax and is faster than using a linked list
which was Rick VanNorman's approach.

--
Gerry

Gerry Jackson

unread,
Jun 11, 2020, 2:06:52 PM6/11/20
to
On 10/06/2020 23:13, A. K. wrote:
> Am Mittwoch, 10. Juni 2020 23:34:55 UTC+2 schrieb Gerry Jackson:
>>
>> I've been meaning to do this for some weeks and just got around to it.
>> I've written an ANS/Forth 2012 equivalent (nearly) to Michael
>> Gassanenko's (MLG) choose, and called it switch.
>>
>> It can be downloaded from https://github.com/gerryjackson/Forth-switch
>>
>> The main difference is that it is a defining word with syntax:
>>
>> create-switch <name>
>> <values-1> when <actions-1-1> end
>> <values-2> when <actions-2> end
>> .....
>> <values-n> when <actions-n> end
>> other <default-action> end
>> end
>>

>
> BTW I find a string-OF variant very useful occasionally:
> ( .. a u )
> CASE
> OF" teststring1" .. ENDOF
> OF" teststring2" .. ENDOF
> ..
> ENDCASE
>

Yes that looks useful, of course it can be done by string comparison
before the standard OF .. ENDOF but yours looks better. A standard
definition of OF" could be:

: (of") ( ca1 u1 ca2 u2 -- ca1 u1 u1+1 | ca1 ca1 )
2over compare if dup 1+ else drop dup then
;

: of"
'"' parse postpone sliteral postpone (of")
postpone of
; immediate

: x case
of" jan" 1 . endof
of" feb" 2 . endof
drop ." Don't know"
endcase
;

\ GForth
cr s" jan" x s" feb" x s" mar" x
1 2 Don't know ok

Or more neatly:

: of"
'"' parse postpone sliteral
[: 2over compare if dup 1+ else drop dup then ;]
compile, postpone of
; immediate

--
Gerry

Krishna Myneni

unread,
Jun 11, 2020, 6:20:07 PM6/11/20
to
On 6/10/20 4:34 PM, Gerry Jackson wrote:

> ...
> I've been meaning to do this for some weeks and just got around to it.
> I've written an ANS/Forth 2012 equivalent (nearly) to Michael
> Gassanenko's (MLG) choose, and called it switch.
>
...

You posted the first message on this topic back in October of 2019. I
consider that to be a pretty quick turnaround. I've got
(software-related) things I've been meaning to do from the 1980s!

:-)

Krishna

dxforth

unread,
Jun 11, 2020, 8:36:48 PM6/11/20
to
It doesn't tick the box where all that's needed is a few OF. As for predicting
what one might need in the future, Moore's advice was 'don't'.

dxforth

unread,
Jun 11, 2020, 8:43:01 PM6/11/20
to
On Friday, June 12, 2020 at 4:06:52 AM UTC+10, Gerry Jackson wrote:
> ...
> : x case
> of" jan" 1 . endof
> of" feb" 2 . endof
> drop ." Don't know"
> endcase
> ;

This draws attention to the mistakes made in ENDCASE and ENDOF - which
would be worth correcting.

hughag...@gmail.com

unread,
Jun 11, 2020, 11:14:32 PM6/11/20
to
It took me about two days to write <SWITCH with FAST-SWITCH> and SLOW-SWITCH>
Sometime later I upgraded SLOW-SWITCH> to use a hand-written binary-search
that gave me improved speed --- that was another few hours.
On Gerry's GIT page lists a probable development in the future being:
"a sparse set of switch values (with binary search or hashing
to search the jump table)."
So Gerry is still just dreaming about being able to implement anything
comparable to my SLOW-SWITCH> --- maybe another year or two for that!

Gerry's code as presented is bug-ridden crap, of course.
Here is an example of his code:
-----------------------------------------------------------------------
create-switch gerry
char y char a char e char i char o char u when ." vowel" end
121 when ." why" end
200 299 when ." twos" end
other ." tilt!" end
end

121 gerry vowel ok
-----------------------------------------------------------------------

Here is a comparable example of my code:
-----------------------------------------------------------------------
<switch
:noname drop ." vowel" ; s" yaeiou" chars-of
:noname drop ." why" ; 121 case-of
:noname drop ." twos" ; 200 299 range-of
:noname drop ." tilt!" ; fast-switch> hugh ( n -- )

*** <SWITCH structures not allowed to have duplicate targ values ***
-> :noname drop ." why" ; 121 case-of
^
-----------------------------------------------------------------------

My code aborts with a helpful error message when there are duplicate
targ values, and it points to the offending line so it can be fixed.
Gerry's crap code fails to notice this major bug in the user's code.
Note that it took me about two minutes to find this bug.
There may be other bugs --- I haven't delved into his code deeply.

My <SWITCH is intended to be used for simulating a micro-processor.
There may be hundreds of opcodes. It is important to make sure that
none of them are duplicated.
FAST-SWITCH> allows a table with a range of 64K, so it can be used
to simulate a 16-bit micro-processor.
SLOW-SWITCH> is slower but allows a huge range, so it can be used
to simulate a 32-bit micro-processor.

Gerry Jackson has made a pathetic attempt at bettering me.
He has failed.

Gerry Jackson

unread,
Jun 12, 2020, 2:11:44 AM6/12/20
to
I've plenty of those, not back to the 1980s though, late 90's certainly!

--
Gerry

gwj....@gmail.com

unread,
Jun 12, 2020, 3:44:15 AM6/12/20
to
On Friday, June 12, 2020 at 4:14:32 AM UTC+1, hughag...@gmail.com wrote:
> Gerry's code as presented is bug-ridden crap, of course.

What's pathetic about you is that you can't comment on something without including insults. Luckily most people have killfiled you so your opinions are worthless. But they serve a purpose - newbies to c.l.f can quickly see what an obnoxious person you are and discount anything you say.

> Here is an example of his code:
> -----------------------------------------------------------------------
> create-switch gerry
> char y char a char e char i char o char u when ." vowel" end
> 121 when ." why" end
> 200 299 when ." twos" end
> other ." tilt!" end
> end
>
> 121 gerry vowel ok
> -----------------------------------------------------------------------
>

If you look in the test program you'll see this test showing I was aware of this:

\ Duplicated switch value, the first one "wins"
t{ create-switch ch14 1 when 333 end 1 when 334 end end -> }t
t{ 1 ch14 -> 333 }t

but omitted to document it - thanks for the reminder.

I don't recollect anyone ever complaining about the same thing in CASE statements or seeing any Forth system detecting it - I've just tried 5 systems.

Some things are so unlikely that it isn't worth the cost of detecting them - that's a design decision. A solution such as yours can be used i.e. burden the user with remembering to use different words. As I've often seen quoted "Forth is a sharp knife".

--
Gerry

a...@littlepinkcloud.invalid

unread,
Jun 12, 2020, 4:20:57 AM6/12/20
to
dxforth <dxf...@gmail.com> wrote:
> On Thursday, June 11, 2020 at 10:43:46 PM UTC+10, a...@littlepinkcloud.invalid wrote:
>> dxforth <dxf...@gmail.com> wrote:
>> >>
>> >> No criticism intended, but this does look remarkably similar to Rick
>> >> VanNorman's [SWITCH statement. As I've argued elsethread, I'm
>> >> convinced this is the right way to do switches in Forth.
>> >
>> > Not sure even Rick VanNorman saw it as the "right way". Writing in
>> > FD V20N3 he says he was satisfying a particular need:
>>
>> I guess he wasn't, but I am. It ticks all the boxes; the only thing
>> really wrong AFAICS is that it can't be used inside a definition, but
>> otherwise it's fine, and I don't think that's such a big deal.
>
> It doesn't tick the box where all that's needed is a few OF.

Why not? Creating a definition with a name is no big deal.

> As for predicting what one might need in the future, Moore's advice
> was 'don't'.

Umm, pardon? What has this to do with the issue?

Andrew.

dxforth

unread,
Jun 12, 2020, 5:21:24 AM6/12/20
to
On Friday, June 12, 2020 at 6:20:57 PM UTC+10, a...@littlepinkcloud.invalid wrote:
> dxforth <dxf...@gmail.com> wrote:
> > On Thursday, June 11, 2020 at 10:43:46 PM UTC+10, a...@littlepinkcloud.invalid wrote:
> >> dxforth <dxf...@gmail.com> wrote:
> >> >>
> >> >> No criticism intended, but this does look remarkably similar to Rick
> >> >> VanNorman's [SWITCH statement. As I've argued elsethread, I'm
> >> >> convinced this is the right way to do switches in Forth.
> >> >
> >> > Not sure even Rick VanNorman saw it as the "right way". Writing in
> >> > FD V20N3 he says he was satisfying a particular need:
> >>
> >> I guess he wasn't, but I am. It ticks all the boxes; the only thing
> >> really wrong AFAICS is that it can't be used inside a definition, but
> >> otherwise it's fine, and I don't think that's such a big deal.
> >
> > It doesn't tick the box where all that's needed is a few OF.
>
> Why not? Creating a definition with a name is no big deal.

It's a big deal when the majority of apps currently using an Eaker-
style Case don't need anything more. After all, isn't that what Rick
VanNorman was saying?

>
> > As for predicting what one might need in the future, Moore's advice
> > was 'don't'.
>
> Umm, pardon? What has this to do with the issue?

Looks to me you're speculating on the type of Case you might need in the
future. I've no idea what 'boxes needing ticking' until the app tells me.

a...@littlepinkcloud.invalid

unread,
Jun 12, 2020, 5:33:11 AM6/12/20
to
dxforth <dxf...@gmail.com> wrote:
> On Friday, June 12, 2020 at 6:20:57 PM UTC+10, a...@littlepinkcloud.invalid wrote:
>> dxforth <dxf...@gmail.com> wrote:
>> > On Thursday, June 11, 2020 at 10:43:46 PM UTC+10, a...@littlepinkcloud.invalid wrote:
>> >> dxforth <dxf...@gmail.com> wrote:
>> >> >>
>> >> >> No criticism intended, but this does look remarkably similar to Rick
>> >> >> VanNorman's [SWITCH statement. As I've argued elsethread, I'm
>> >> >> convinced this is the right way to do switches in Forth.
>> >> >
>> >> > Not sure even Rick VanNorman saw it as the "right way". Writing in
>> >> > FD V20N3 he says he was satisfying a particular need:
>> >>
>> >> I guess he wasn't, but I am. It ticks all the boxes; the only thing
>> >> really wrong AFAICS is that it can't be used inside a definition, but
>> >> otherwise it's fine, and I don't think that's such a big deal.
>> >
>> > It doesn't tick the box where all that's needed is a few OF.
>>
>> Why not? Creating a definition with a name is no big deal.
>
> It's a big deal when the majority of apps currently using an Eaker-
> style Case don't need anything more.

OK. ISTM that, given that the ideal Forth definition is pretty short,
it makes little difference in practice. Modifying this form to make it
nestable inside a definition wouldn't be difficult, but perhaps would
need some non-portable assumptions to make it fast.

>> > As for predicting what one might need in the future, Moore's advice
>> > was 'don't'.
>>
>> Umm, pardon? What has this to do with the issue?
>
> Looks to me you're speculating on the type of Case you might need in
> the future.

I've been doing this programming thing for decades so I've got a
pretty good idea what kinds of cases are commonly needed. It doesn't
call for speculation. You either, I would have thought.

Andrew.

dxforth

unread,
Jun 12, 2020, 7:08:11 AM6/12/20
to
On Friday, June 12, 2020 at 7:33:11 PM UTC+10, a...@littlepinkcloud.invalid wrote:
> dxforth <dxf...@gmail.com> wrote:
> > On Friday, June 12, 2020 at 6:20:57 PM UTC+10, a...@littlepinkcloud.invalid wrote:
> >> dxforth <dxf...@gmail.com> wrote:
> >> > On Thursday, June 11, 2020 at 10:43:46 PM UTC+10, a...@littlepinkcloud.invalid wrote:
> >> >> dxforth <dxf...@gmail.com> wrote:
> >> >> >>
> >> >> >> No criticism intended, but this does look remarkably similar to Rick
> >> >> >> VanNorman's [SWITCH statement. As I've argued elsethread, I'm
> >> >> >> convinced this is the right way to do switches in Forth.
> >> >> >
> >> >> > Not sure even Rick VanNorman saw it as the "right way". Writing in
> >> >> > FD V20N3 he says he was satisfying a particular need:
> >> >>
> >> >> I guess he wasn't, but I am. It ticks all the boxes; the only thing
> >> >> really wrong AFAICS is that it can't be used inside a definition, but
> >> >> otherwise it's fine, and I don't think that's such a big deal.
> >> >
> >> > It doesn't tick the box where all that's needed is a few OF.
> >>
> >> Why not? Creating a definition with a name is no big deal.
> >
> > It's a big deal when the majority of apps currently using an Eaker-
> > style Case don't need anything more.
>
> OK. ISTM that, given that the ideal Forth definition is pretty short,
> it makes little difference in practice. Modifying this form to make it
> nestable inside a definition wouldn't be difficult, but perhaps would
> need some non-portable assumptions to make it fast.

I'd only do that were I desperate to use that Case - and I'm not.

>
> >> > As for predicting what one might need in the future, Moore's advice
> >> > was 'don't'.
> >>
> >> Umm, pardon? What has this to do with the issue?
> >
> > Looks to me you're speculating on the type of Case you might need in
> > the future.
>
> I've been doing this programming thing for decades so I've got a
> pretty good idea what kinds of cases are commonly needed.

Presumably so did Rick VanNorman. But feel free to convince Forth Inc
they need to update all their code to your specification.

Stephen Pelc

unread,
Jun 12, 2020, 5:22:22 PM6/12/20
to
On Fri, 12 Jun 2020 02:21:22 -0700 (PDT), dxforth <dxf...@gmail.com>
wrote:

>It's a big deal when the majority of apps currently using an Eaker-
>style Case don't need anything more. After all, isn't that what Rick
>VanNorman was saying?

Except when you need more. It doesn't happen often, but it does
happen. VFX uses it for the user-extensible decompiler/disassembler.
For that [SWITCH and friends is a good solution.

Stephen

--
Stephen Pelc, ste...@mpeforth.com
MicroProcessor Engineering Ltd - More Real, Less Time
133 Hill Lane, Southampton SO15 5AF, England
tel: +44 (0)23 8063 1441, +44 (0)78 0390 3612
web: http://www.mpeforth.com - free VFX Forth downloads

dxforth

unread,
Jun 12, 2020, 9:01:08 PM6/12/20
to
On Saturday, June 13, 2020 at 7:22:22 AM UTC+10, Stephen Pelc wrote:
> On Fri, 12 Jun 2020 02:21:22 -0700 (PDT), dxforth <dxf...@gmail.com>
> wrote:
>
> >It's a big deal when the majority of apps currently using an Eaker-
> >style Case don't need anything more. After all, isn't that what Rick
> >VanNorman was saying?
>
> Except when you need more. It doesn't happen often, but it does
> happen. VFX uses it for the user-extensible decompiler/disassembler.
> For that [SWITCH and friends is a good solution.

Fine but the claim was "It ticks all the boxes". Forth has seen 'one-
size-fits-all' solutions offered before, from strings to arrays. I've been
guilty of it myself. They all come to naught because unlike other
languages, forthers aren't content to live in an abstraction created
for them. Once taken off, it's impossible to put the blinkers back on.

Stephen Pelc

unread,
Jun 13, 2020, 8:23:41 AM6/13/20
to
On Fri, 12 Jun 2020 18:01:06 -0700 (PDT), dxforth <dxf...@gmail.com>
wrote:

>On Saturday, June 13, 2020 at 7:22:22 AM UTC+10, Stephen Pelc wrote:
>> On Fri, 12 Jun 2020 02:21:22 -0700 (PDT), dxforth <dxf...@gmail.com>
>> wrote:
>>
>> >It's a big deal when the majority of apps currently using an Eaker-
>> >style Case don't need anything more. After all, isn't that what Rick
>> >VanNorman was saying?
>>
>> Except when you need more. It doesn't happen often, but it does
>> happen. VFX uses it for the user-extensible decompiler/disassembler.
>> For that [SWITCH and friends is a good solution.
>
>Fine but the claim was "It ticks all the boxes".

I just made a comment. I made no support of "ticks all the boxes".
What I said was that [SWITCH and friends are a good solution in a
particular case.

Gerry Jackson

unread,
Jun 13, 2020, 8:55:36 AM6/13/20
to
What mistakes?

--
Gerry

dxforth

unread,
Jun 13, 2020, 7:26:49 PM6/13/20
to
On Saturday, June 13, 2020 at 10:23:41 PM UTC+10, Stephen Pelc wrote:
> On Fri, 12 Jun 2020 18:01:06 -0700 (PDT), dxforth <dxf...@gmail.com>
> wrote:
>
> >On Saturday, June 13, 2020 at 7:22:22 AM UTC+10, Stephen Pelc wrote:
> >> On Fri, 12 Jun 2020 02:21:22 -0700 (PDT), dxforth <dxf...@gmail.com>
> >> wrote:
> >>
> >> >It's a big deal when the majority of apps currently using an Eaker-
> >> >style Case don't need anything more. After all, isn't that what Rick
> >> >VanNorman was saying?
> >>
> >> Except when you need more. It doesn't happen often, but it does
> >> happen. VFX uses it for the user-extensible decompiler/disassembler.
> >> For that [SWITCH and friends is a good solution.
> >
> >Fine but the claim was "It ticks all the boxes".
>
> I just made a comment. I made no support of "ticks all the boxes".
> What I said was that [SWITCH and friends are a good solution in a
> particular case.

I believe that case was already made by Rick VanNorman in the section
I quoted. Is it being proposed for 200x? Because I see it as a solution
to specific problem rather filling a general need.


dxforth

unread,
Jun 13, 2020, 7:40:38 PM6/13/20
to
The political ones that resulted in:

- ANS CASE existing in its own eco-system disallowing all manner of user-extensions
- DROP built into ENDCASE

hughag...@gmail.com

unread,
Jun 13, 2020, 8:58:22 PM6/13/20
to
On Friday, June 12, 2020 at 12:44:15 AM UTC-7, gwj....@gmail.com wrote:
> On Friday, June 12, 2020 at 4:14:32 AM UTC+1, hughag...@gmail.com wrote:
> > Gerry's code as presented is bug-ridden crap, of course.
>
> What's pathetic about you is that you can't comment on something
> without including insults. Luckily most people have killfiled you
> so your opinions are worthless. But they serve a purpose - newbies
> to c.l.f can quickly see what an obnoxious person you are and
> discount anything you say.

What is pathetic about Gerry Jackson is that he is a liar.
At the top of his source file he has this comment:
--------------------------------------------------------------------
\ switch.fth - an implementation of Michael Gassanenko's (MLG) choose in
\ ANS/2012 Forth. A difference is that CREATE-SWITCH is a defining word and
\ may not be nested

\ Copyright (C) G W Jackson 2020

\ This software is covered by the MIT software license, a copy of which should
\ have accompanied this file. If not see https://opensource.org/licenses/MIT
--------------------------------------------------------------------
Gerry Jackson was not capable of implementing a switch construct,
so he just stole Michael Gassanenko's code and slapped his own
copyright notice on top of it. He did this because he is trying to prove
that he is a better Forth programmer than me --- note that my
<SWITCH construct is entirely my own, and not copied off anybody else.

The reason why Gerry Jackson didn't provide capability comparable
to my SLOW-SWITCH> is that Michael Gassanenko didn't provide this.
Gerry Jackson is dependent upon Michael Gassanenko to figure things out.

In his documentation Gerry says: "This implementation in ANS/Forth..."
This is his code:
--------------------------------------------------------------------
: (...) ( start size ni .. n1 -- ni .. n1 i start' size' )
subseq-size dup >r ( -- start size ni .. n1 i ) ( R: -- n0 i )
[: ?dup 0> if 1- swap >r recurse r@ extent+ r> -rot then ;]
execute ( -- ni .. n1 start' size' )
r> -rot ( -- ni .. n1 i start' size' )
;
--------------------------------------------------------------------
This is a bug --- the Paysan-faked quotations are not ANS-Forth.
To get his code to compile under VFX, I needed to fix this bug:
--------------------------------------------------------------------
: PFQ
?dup 0> if 1- swap >r recurse r@ extent+ r> -rot then ;

: (...) ( start size ni .. n1 -- ni .. n1 i start' size' )
subseq-size dup >r ( -- start size ni .. n1 i ) ( R: -- n0 i )
PFQ ( -- ni .. n1 start' size' )
r> -rot ( -- ni .. n1 i start' size' )
;
--------------------------------------------------------------------
What is also pathetic about Gerry Jackson, is that he doesn't know
what quotations are for. His use of the Paysan-faked quotation
was purely gratuitous. There was no reason not to just make it
a colon word as I did in my bug-fix.

> > Here is an example of his code:
> > -----------------------------------------------------------------------
> > create-switch gerry
> > char y char a char e char i char o char u when ." vowel" end
> > 121 when ." why" end
> > 200 299 when ." twos" end
> > other ." tilt!" end
> > end
> >
> > 121 gerry vowel ok
> > -----------------------------------------------------------------------
> >
>
> If you look in the test program you'll see this test showing I was aware of this:
>
> \ Duplicated switch value, the first one "wins"
> t{ create-switch ch14 1 when 333 end 1 when 334 end end -> }t
> t{ 1 ch14 -> 333 }t
>
> but omitted to document it - thanks for the reminder.
>
> I don't recollect anyone ever complaining about the same thing
> in CASE statements or seeing any Forth system detecting it - I've just
> tried 5 systems.
>
> Some things are so unlikely that it isn't worth the cost of
> detecting them - that's a design decision. A solution such as yours
> can be used i.e. burden the user with remembering to use different words.
> As I've often seen quoted "Forth is a sharp knife".

Here Gerry Jackson is lying again. He says:
"A solution such as yours can be used i.e. burden the user
with remembering to use different words."
This is just one of his many bizarre attacks on me. This is nonsense!
I'm not burdening the user with remembering to use different words.
I don't even know what that means.

The reason why I was able to detect duplicate targ values, and provide
an error message on the line where the error occurred, is because
I sorted my data with an insertion sort. Every time that CASE-OF
executes in inserts ordered and it aborts if the targ value is a duplicate.
Gerry Jackson's code (actually Michael Gassanenko's code) doesn't do
an insertion sort, so the problem with duplicate values is not detected
until the end, rather than on the WHEN where the duplicate occurred.

Now Gerry Jackson pretends that allowing user bugs to slip through
was his "design decision." No it wasn't! He just couldn't figure out how
to detect duplicate values in the WHEN where the duplicate occurs.
Also, as I said, the purpose of <SWITCH is to support processor simulation.
There are going to be hundreds of opcodes in the <SWITCH , so a typo
in the opcode values (which are most likely entered in binary) is likely.
Any time that you have hundreds of numbers being typed in by the user,
typos are likely --- but Gerry says that typos are "unlikely."
Gerry Jackson is a dull knife!

Gerry Jackson

unread,
Jun 14, 2020, 12:14:13 AM6/14/20
to
On 14/06/2020 01:58, hughag...@gmail.com wrote:

Don't know what he wrote in detail as scanning it showed it was full of
abuse.

As I wrote in another discussion, if you can't make your point without
personal insults, I'm not going through to see if you've any valid points.


--
Gerry

Gerry Jackson

unread,
Jun 14, 2020, 12:44:10 AM6/14/20
to
Why do you care? You've made clear your antipathy to the ANS standard.

--
Gerry

dxforth

unread,
Jun 14, 2020, 1:13:31 AM6/14/20
to
Seeing a mistake makes one care.

Gerry Jackson

unread,
Jun 14, 2020, 1:58:09 AM6/14/20
to
However in my scan I did spot one thing, Aguilar makes himself look
foolish because he didn't read the README on GitHub - see the bit headed
compatibility.

--
Gerry

Stephen Pelc

unread,
Jun 14, 2020, 3:35:20 AM6/14/20
to
On Sat, 13 Jun 2020 16:26:47 -0700 (PDT), dxforth <dxf...@gmail.com>
wrote:

>> I just made a comment. I made no support of "ticks all the boxes".
>> What I said was that [SWITCH and friends are a good solution in a
>> particular case.
>
>I believe that case was already made by Rick VanNorman in the section
>I quoted. Is it being proposed for 200x? Because I see it as a solution
>to specific problem rather filling a general need.

To my knowledge, nobody has proposed [SWITCH for 200x. I simply said
that it satisfied one need in VFX.

Gerry Jackson

unread,
Jun 14, 2020, 9:02:00 AM6/14/20
to
On 14/06/2020 00:40, dxforth wrote:
The rest of us go on happily using CASE, where appropriate, without
worrying about so-called mistakes.

--
Gerry

Gerry Jackson

unread,
Jun 14, 2020, 9:17:41 AM6/14/20
to
Nah, given that you've posted comments like:

From Message-ID:
<576e7bb6-e698-4c78...@googlegroups.com> 1 May 2020

<quote>No - on the grounds those clamouring for a Forth standard have
never been satisfied with what's been provided. Their posts provide
hours of entertainment.</quote>

from Message-ID: <0c5e1a1d-c206-4e50...@googlegroups.com>
1 May 2020

<quote>The testimonies of how forth has changed lives, the threats to
leave, the glorification of ANS, the offers of leadership, predictions
of forth's demise if it doesn't have x. What sitcoms can compete with
this?</quote>

I think you're indulging in troll-like behaviour to provoke responses
for your own amusement.

--
Gerry

none albert

unread,
Jun 14, 2020, 9:23:58 AM6/14/20
to
In article <rc5747$o7g$1...@dont-email.me>,
That reminds me. Since Anton taught me CONDS I'm happily
exterminating CASE and there were a few spots left.

I understand `IF `ELSE real good, and I'm really glad
I can now forego looking up the stack effect of `OF and `ENDCASE
all the time.

>
>--
>Gerry
--
This is the first day of the end of your life.
It may not kill you, but it does make your weaker.
If you can't beat them, too bad.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Gerry Jackson

unread,
Jun 14, 2020, 10:06:29 AM6/14/20
to
On 14/06/2020 01:58, hughag...@gmail.com wrote:

On reflection I did look at it. Such a typical Aguliar rant - full of
lies, abuse and insults showing he hasn't looked in detail at anything
in the GitHub repository. I know it's futile to respond point by point
so I'll join the rest of the other dozen or so people you treat the same
way:
*PLONK*

--
Gerry

Rick C

unread,
Jun 14, 2020, 11:21:50 AM6/14/20
to
Indeed. DX is pretty much the dictionary definition. I believe they have his picture as part of the most recent edition.

--

Rick C.

--- Get 1,000 miles of free Supercharging
--- Tesla referral code - https://ts.la/richard11209

dxforth

unread,
Jun 14, 2020, 11:36:54 AM6/14/20
to
Happy is being able to use IF directly and not forced into concoctions
such as this:

On Friday, June 12, 2020 at 4:06:52 AM UTC+10, Gerry Jackson wrote:
>
> : (of") ( ca1 u1 ca2 u2 -- ca1 u1 u1+1 | ca1 ca1 )
> 2over compare if dup 1+ else drop dup then
> ;
>
> : of"
> '"' parse postpone sliteral postpone (of")
> postpone of
> ; immediate

The 200x leadership has been toying with the idea of giving you ?OF.
Instead of removing your chains, they prefer to lengthen them a little :)

dxforth

unread,
Jun 14, 2020, 11:49:50 AM6/14/20
to
On Monday, June 15, 2020 at 1:21:50 AM UTC+10, Rick C wrote:
> ...
> Indeed. DX is pretty much the dictionary definition. I believe they have his picture as part of the most recent edition.

Say the ANS/200x prisoners rattling their chains :)

Gerry Jackson

unread,
Jun 14, 2020, 12:38:58 PM6/14/20
to
That's it, I'm tired of his one-liners

*PLONK*

--
Gerry

Gerry Jackson

unread,
Jun 14, 2020, 1:05:02 PM6/14/20
to
On 14/06/2020 16:36, dxforth wrote:
> On Sunday, June 14, 2020 at 11:02:00 PM UTC+10, Gerry Jackson wrote:
>> On 14/06/2020 00:40, dxforth wrote:
>>> On Saturday, June 13, 2020 at 10:55:36 PM UTC+10, Gerry Jackson wrote:
>>>> On 12/06/2020 01:42, dxforth wrote:
>>>>> On Friday, June 12, 2020 at 4:06:52 AM UTC+10, Gerry Jackson wrote:
>>>>>> ...
>>>>>> : x case
>>>>>> of" jan" 1 . endof
>>>>>> of" feb" 2 . endof
>>>>>> drop ." Don't know"
>>>>>> endcase
>>>>>> ;
>>>>>
>>>>> This draws attention to the mistakes made in ENDCASE and ENDOF - which
>>>>> would be worth correcting.
>>>>>
>>>>
>>>> What mistakes?
>>>
>>> The political ones that resulted in:
>>>
>>> - ANS CASE existing in its own eco-system disallowing all manner of user-extensions
>>> - DROP built into ENDCASE
>>>
>>
>> The rest of us go on happily using CASE, where appropriate, without
>> worrying about so-called mistakes.
>
> Happy is being able to use IF directly and not forced into concoctions
> such as this:

I thought I'd answer this before plonking you.

Nobody's forcing anyone - just ignore it and use your IFs for a wordier
equivalent. Having deffined it people can use it if they want - who cares.

>
> On Friday, June 12, 2020 at 4:06:52 AM UTC+10, Gerry Jackson wrote:
>>
>> : (of") ( ca1 u1 ca2 u2 -- ca1 u1 u1+1 | ca1 ca1 )
>> 2over compare if dup 1+ else drop dup then
>> ;
>>
>> : of"
>> '"' parse postpone sliteral postpone (of")
>> postpone of
>> ; immediate
>
> The 200x leadership has been toying with the idea of giving you ?OF.
> Instead of removing your chains, they prefer to lengthen them a little :)
>

That's a silly way to look at things

--
Gerry

hughag...@gmail.com

unread,
Jun 14, 2020, 7:24:38 PM6/14/20
to
On Friday, June 12, 2020 at 12:44:15 AM UTC-7, gwj....@gmail.com wrote:
> What's pathetic about you is that you can't comment on something
> without including insults. Luckily most people have killfiled you
> so your opinions are worthless. But they serve a purpose - newbies to c.l.f
> can quickly see what an obnoxious person you are
> and discount anything you say.

Well, I upgraded my <SWITCH to support <WHEN ... WHEN> that is
roughly comparable to Michael Gassanenko's WHEN in that it
allows a variable number of targ values for each action.

I still haven't looked at Michael Gassanenko's code in any depth.
Unlike Gerry Jackson, I write my own code --- I don't steal
other people's code and put my own copyright on it.
I'm not disparaging Michael Gassanenko's ability --- he is a
real Forth programmer --- I just don't steal anybody's code.

I also made my duplicate-value error-message more informative
(it tells the user what the duplicate value was, which is useful
if the duplicate occurs inside of a wrapper around CASE-OF
rather than when CASE-OF is used directly).
I improved my documentation slightly.

Here is the code (that I didn't steal from anybody):
-----------------------------------------------------------------
\ ******
\ ****** This is a <SWITCH control-structure like in C that generates a jump-table.
\ ******

\ You can build a colon word called XXX that switches on targ values. This is how:
\ <SWITCH
\ :NONAME drop ... ; targ CASE-OF
\ ...
\ :NONAME drop ... ; FAST-SWITCH> xxx ( selector -- )

\ The DROP in the :NONAME function gets rid of the selector-value. You might need this sometimes though.

\ There are some simple additions, that can be used instead of CASE-OF (they do CASE-OF internally):
\ :NONAME drop ... ; low-targ high-targ RANGE-OF \ matches all of the values from LOW-TARG to HIGH-TARG inclusive
\ :NONAME drop ... ; ." xxx" CHARS-OF \ matches all of the chars in the string
\ :NONAME drop ... ; <WHEN ... WHEN> \ matches all of the values between <WHEN and WHEN> (the .... means zero or more values)

\ Also, we have CASE: suggested by DXForth that can be used instead of CASE-OF .

\ The colon word XXX executes a table-entry corresponding to the targ value.
\ If there is no match, then the xt value prior to FAST-SWITCH> is executed as the default.
\ All of the table-entries and the default are given the selector value which they DROP if not needed.
\ It was HAA's suggestion that the selector value be provided --- I had dropped it internally previously.

\ The targ values don't have to be provided in any particular order --- they get sorted internally.
\ If a duplicate targ value is provided, CASE-OF will abort with an error message at compile-time.
\ This error message shows which line had the duplicate, and what the duplicate value is
\ (This helpful error message is an improvement over Michael Gassanenko's CHOOSE).
\ Note that my <WHEN ... WHEN> was written to provide comparable functionality to Michael Gassanenko's CHOOSE code.

\ This is pretty crude because, unlike in C, the table entries can't have common local variables.
\ I would have liked to use my rquotations, but they don't have an xt that is known at compile-time,
\ so it is not possible to build a jump-table at compile-time. They have a "continuation" that is only known at run-time.
\ My <SWITCH that I have here uses :NONAME for the table entries --- they can have common global variables.

\ FAST-SWITCH> uses the selector value as an index to do the table look up. This is very fast.
\ If the range is too large however, then FAST-SWITCH> will abort with an error message to save memory.
\ In this case, use SLOW-SWITCH> instead. This builds a smaller table and uses BSEARCH to look up the table-entry.

\ Set JT-LIMIT to the range that you want FAST-SWITCH> to support.
\ It is currently set at 2^16 so you can have jump-tables with up to 64K entries. These consume a lot of memory.
\ If memory usage is an issue, then set JT-LIMIT to a smaller value. Use SLOW-SWITCH> instead of FAST-SWITCH>.
\ If the jump-table is sparse, SLOW-SWITCH> might be faster because there is less data-cache thrashing.

\ <SWITCH is primarily provided for writing VM simulators.
\ JT-LIMIT is currently set at 2^16, so it supports simulating a micro-processor with 16-bit opcodes (such as the AVR).
\ SLOW-SWITCH> would be needed for a micro-processor with 32-bit opcodes (such as the ARM or MIPS).

\ Some micro-processors (or byte-code VMs) have 8-bit opcodes, but also have post-bytes on some of the opcodes.
\ These variable-sized opcodes could be done with nested FAST-SWITCH> constructs.

list
w field .xt
w field .targ
constant jt

: init-jt ( xt targ node -- node )
init-list >r
r@ .targ !
r@ .xt !
r> ;

: new-jt ( xt targ -- node )
jt alloc
init-jt ;

: kill-jt ( head -- )
each[ dealloc ]each ;

: show-jt ( head -- )
each[ cr .targ @ . ]each ;

: jt> ( new-node node -- new-node flag ) \ used by INSERT-ORDERED to build an ascending list without duplicates
.targ @ over .targ @
2dup = if
cr ." targ value: " dup . dup h. dup b. dup 128 < if dup 32 > if ." char: " dup emit then then
cr true abort" *** <SWITCH structures not allowed to have duplicate targ values ***"
then
> ;

variable when-marker \ used by <WHEN values... WHEN> to determine how many values there are on the data-stack

: <switch ( -- head )
false when-marker !
nil ;

: case-of ( head xt targ -- new-head ) \ provide a targ value
new-jt \ -- head node
['] jt> swap insert-ordered drop ;

: range-of { head xt lo hi -- new-head } \ provide a range from LO to HI inclusive
head
hi 1+ lo do
xt I case-of
loop ;

: chars-of { head xt adr cnt -- new-head } \ provide a string containing targ chars
head
adr cnt + adr do
xt I c@ case-of
loop ;

: <when ( head xt -- head xt ) \ saves the depth after HEAD XT in WHEN-MARKER
when-marker @ abort" *** <WHEN can't be nested ***"
depth when-marker ! ;

: when> ( head xt values... )
when-marker @ 0= abort" *** <WHEN is needed prior to the values prior to the WHEN> ***"
depth when-marker @ - { total | cnt xt -- }
total 0< abort" *** WHEN> given an invalid marker ***"
total to cnt begin cnt while >r -1 +to cnt repeat \ -- head xt \return: -- values...
to xt \ -- head \return: -- values...
total to cnt begin cnt while xt r> case-of -1 +to cnt repeat \ -- new-head \return: --
false when-marker ! ; \ a <WHEN is needed to set WHEN-MARKER for the next WHEN>

: digit-of ( head xt -- new-head )
[char] 0 [char] 9 range-of ;

: lower-of ( head xt -- new-head )
[char] a [char] z range-of ;

: upper-of ( head xt -- new-head )
[char] A [char] Z range-of ;

: alpha-of { head xt -- new-head }
head
xt lower-of xt upper-of ;

: punctuation-of ( head xt -- new-head )
s| .,!?'";:[]()@#$%&| chars-of ;

: blank-of ( head xt -- new-head )
0 32 range-of ;

1 16 lshift value jt-limit \ should be at least 256 so we can support byte-code simulators

\ JT-LIMIT is the index that is too big for the jump-table. This can be any reasonable size.
\ The jump-table size is limited so the programmer doesn't accidentally build a jump-table consuming megabytes.
\ I set it at 2^16 to support simulating a micro-processor with 16-bit opcodes.

: fast-switch> { head default | adr offset size -- } \ stream: name
align here to adr
head .targ @ to offset
head tail .targ @ offset - to size
size jt-limit u> abort" *** FAST-SWITCH> has too large of a range. Use SLOW-SWITCH> instead. ***"
offset head each[ >r \ -- targ
begin r@ .targ @ over <> while default , 1+ repeat
r> .xt @ , 1+ ]each drop
: ( selector -- )
dup, offset lit, -, \ -- selector index
dup, size lit, u>, if, drop, default lit, execute, end,
w lit, *, adr lit, +, @, execute, ;,
head kill-jt ;

: slow-search ( array limit target -- element|false ) \ hard-coded for use by SLOW-SWITCH>
>r \ -- array limit \ return: -- target
begin dup while
dup 1 rshift \ -- array limit mid
dup d * fourth + \ -- array limit mid mid-element
r@ over @ = if nip nip nip rdrop exit then \ if found, return MID-ELEMENT
r@ over @ < if \ search left side
drop nip \ -- array mid \ MID is the new limit
else
d + >r \ -- array limit mid \ return: -- target new-array \ NEW-ARRAY is one element above middle element
1+ - \ -- array new-limit \ the 1+ is so we don't include the middle element
nip r> swap \ -- new-array new-limit \ MID-ELEMENT is the new ARRAY
then
repeat \ LIMIT is zero, so it can be used as a FALSE flag
nip rdrop ; \ -- false

\ SLOW-SEARCH assumes that the array element is D in size (two cells),
\ and the first cell is the integer that we are comparing against.

: slow-switch> { head default | adr size -- } \ stream: name
dalign here to adr \ use DALIGN so the element SLOW-SEARCH finds will be in the same data-cache line
head length to size
head each[ dup .targ @ , .xt @ , ]each
: ( selector -- )
adr lit, size lit, rover, postpone slow-search
dup, if, w lit, +, @, execute, end,
drop, default lit, execute, ;,
head kill-jt ;

\ CASE: and ;; were suggested by DXForth on comp.lang.forth to improve readability.
\ This works well when there is a list of integers, similar to CASE END-CASE in ANS-Forth.

get-current synonym case: :noname \ head targ -- head targ

: ;; ( head targ -- new-head ) \ this concludes the CASE: function (rather than ; as used in :NONAME usually)
postpone ; \ -- head targ xt
swap case-of ;
immediate

\ Note that the default should still be :NONAME and end with ; as usual.
-----------------------------------------------------------------

hughag...@gmail.com

unread,
Jun 14, 2020, 8:27:01 PM6/14/20
to
On Sunday, June 14, 2020 at 4:24:38 PM UTC-7, hughag...@gmail.com wrote:
> Here is the code (that I didn't steal from anybody):
> -----------------------------------------------------------------
> ...
> : fast-switch> { head default | adr offset size -- } \ stream: name
> align here to adr
> head .targ @ to offset
> head tail .targ @ offset - to size
> size jt-limit u> abort" *** FAST-SWITCH> has too large of a range. Use SLOW-SWITCH> instead. ***"
> offset head each[ >r \ -- targ
> begin r@ .targ @ over <> while default , 1+ repeat
> r> .xt @ , 1+ ]each drop
> : ( selector -- )
> dup, offset lit, -, \ -- selector index
> dup, size lit, u>, if, drop, default lit, execute, end,
> w lit, *, adr lit, +, @, execute, ;,
> head kill-jt ;
> ...
> -----------------------------------------------------------------

Well, I made a slight improvement in speed:
-----------------------------------------------------------------
: fast-switch> { head default | adr offset size -- } \ stream: name
align here to adr
head .targ @ to offset
head tail .targ @ offset - to size
size jt-limit u> abort" *** FAST-SWITCH> has too large of a range. Use SLOW-SWITCH> instead. ***"
offset head each[ >r \ -- targ
begin r@ .targ @ over <> while default , 1+ repeat
r> .xt @ , 1+ ]each drop
: ( selector -- )
dup, offset lit, -, \ -- selector index
dup, size lit, u>, if, drop, default lit, execute, end,
cells, adr lit, +, @, execute, ;,
head kill-jt ;
-----------------------------------------------------------------

The only difference is that I'm using CELLS instead of W * now.
This makes no difference under VFX because W * compiles as:
SHL EBX, 2
This does make a difference under SwiftForth because W* compiles as:
4 # EAX MOV
EBX MUL
EAX EBX MOV
I generally use VFX, so I don't bother with hand-optimizing, because most
optimization is done by the compiler.
In SwiftForth it is necessary to hand-optimize because very little
optimization is done by the compiler.

Note for DXforth --- I used your END macro above.
Are you happy now that someone has finally taken your suggestion?

dxforth

unread,
Jun 14, 2020, 9:33:40 PM6/14/20
to
On Monday, June 15, 2020 at 3:05:02 AM UTC+10, Gerry Jackson wrote:
> On 14/06/2020 16:36, dxforth wrote:
> > On Sunday, June 14, 2020 at 11:02:00 PM UTC+10, Gerry Jackson wrote:
> >> On 14/06/2020 00:40, dxforth wrote:
> >>> On Saturday, June 13, 2020 at 10:55:36 PM UTC+10, Gerry Jackson wrote:
> >>>> On 12/06/2020 01:42, dxforth wrote:
> >>>>> On Friday, June 12, 2020 at 4:06:52 AM UTC+10, Gerry Jackson wrote:
> >>>>>> ...
> >>>>>> : x case
> >>>>>> of" jan" 1 . endof
> >>>>>> of" feb" 2 . endof
> >>>>>> drop ." Don't know"
> >>>>>> endcase
> >>>>>> ;
> >>>>>
> >>>>> This draws attention to the mistakes made in ENDCASE and ENDOF - which
> >>>>> would be worth correcting.
> >>>>>
> >>>>
> >>>> What mistakes?
> >>>
> >>> The political ones that resulted in:
> >>>
> >>> - ANS CASE existing in its own eco-system disallowing all manner of user-extensions
> >>> - DROP built into ENDCASE
> >>>
> >>
> >> The rest of us go on happily using CASE, where appropriate, without
> >> worrying about so-called mistakes.
> >
> > Happy is being able to use IF directly and not forced into concoctions
> > such as this:
>
> I thought I'd answer this before plonking you.

What's not so easily plonked is reality banging on the door of ANS/200x.

>
> Nobody's forcing anyone - just ignore it and use your IFs for a wordier
> equivalent. Having deffined it people can use it if they want - who cares.

Instead of one IF, ANS has forced you into using an IF ELSE in addition to
the IF that's built into OF.

>
> >
> > On Friday, June 12, 2020 at 4:06:52 AM UTC+10, Gerry Jackson wrote:
> >>
> >> : (of") ( ca1 u1 ca2 u2 -- ca1 u1 u1+1 | ca1 ca1 )
> >> 2over compare if dup 1+ else drop dup then
> >> ;
> >>
> >> : of"
> >> '"' parse postpone sliteral postpone (of")
> >> postpone of
> >> ; immediate
> >
> > The 200x leadership has been toying with the idea of giving you ?OF.
> > Instead of removing your chains, they prefer to lengthen them a little :)
> >
>
> That's a silly way to look at things

It's what 200x has offered you courtesy of Anton's proposed CASE extensions.
You are using {: :} for locals because Forth Inc thought more highly of its sad
excuse for a comment delimiter. You are using SYNONYM - not because it's
the best implementation - but because it was in the interest of MPE you do so.

In the days of Forth-83 it was still possible to make meaningful changes but that's
gone. The ANS monster has subsumed everything to the point where even the
major players are now locked in and can't move. A case of 'be careful what you
wish for'.

hughag...@gmail.com

unread,
Jun 14, 2020, 10:27:42 PM6/14/20
to
Eaker's CASE was the winner of a contest in Forth Dimensions
to write a CASE statement. The rule was that the code had to be
written in Forth-83 --- no assembly-language allowed!
Elizabeth Rather later put this into ANS-Forth, not realizing that
it was grossly inefficient because there was no jump-table.
Her mistake was that this made the entire Forth community
appear to be retarded --- fodder for Forth-haters to use against us!

Elizabeth Rather also didn't realize that the failure to use
a jump-table was due to a certain rule of ANS-Forth
(there is no way to find the current location in code memory
inside of colon definition, although HERE usually works).
Michael Gassanenko's CHOOSE just used HERE and it usually works.
My original code and Gerry jackson's minor rewrite of
Michael Gassanenko's CHOOSE both make a stand-alone switch; they both
fail to allow it to be embedded in a colon word, because both are
adhering to the idiotic limitations of ANS-Forth. This also makes
the Forth community appear to be retarded --- the C SWITCH can be
embedded within a function --- it has access to the function's locals.

Anyway, DXforth isn't making sense. Eaker's CASE was written in Forth.
It can easily be extended, as it is just Forth code. Anybody who knows
meta-compiling can do this --- this is intermediate-level Forth --- trivial!
Eaker's CASE is not:
"existing in its own eco-system disallowing all manner of user-extensions."
That would only be true if it were written in assembly-language.
Eaker's CASE is crap code though, because it is grossly inefficient.

ANS-Forth is not a failure because it is putting Forthers in a box
and limiting their creativity, as DXforth imagines.
ANS-Forth is a failure because it is crap from a technical perspective.
Limiting users' creativity is what a standard does. That is okay.
Given a viable standard, Forthers could use their awesome creativity
for something worthwhile, like writing useful applications.
It is a waste of time to be implementing something like my <SWITCH
in the year 2020 --- every other language has had this since day one.
It is likely that C programmers are laughing at us, because they
have had SWITCH since the 1970s, and we are still struggling with it
(somewhat like a teenage who still hasn't graduated from kindergarten,
but he continues struggling to learn the basics year after year).
Forth-200x will also fail to graduate from kindergarten.

hughag...@gmail.com

unread,
Jun 14, 2020, 11:04:54 PM6/14/20
to
Rick Collins is definitely a troll. He knows nothing about Forth programming.
I don't consider DXforth to be a troll.

I consider DXforth to be an intermediate-level Forth programmer.
He has mastered basic meta-compiling such as:
: end postpone exit postpone then ; immediate
He gets on my nerves because he endlessly promotes this trivial code.

Eaker's CASE was also intermediate-level Forth programming.
ANS-Forth gets on my nerves even more than DXforth, because
it standardized this trivial code, and forbade everything worthwhile.

Basic meta-compiling is barely even intermediate-level --- it could be
considered to be novice-level --- this is pretty trivial code!
People should really strive to get to a solid intermediate-level,
or even an advanced-level, before they begin teaching the subject.

dxforth

unread,
Jun 15, 2020, 1:04:13 AM6/15/20
to
On Monday, June 15, 2020 at 1:04:54 PM UTC+10, hughag...@gmail.com wrote:
> On Sunday, June 14, 2020 at 8:49:50 AM UTC-7, dxforth wrote:
> > On Monday, June 15, 2020 at 1:21:50 AM UTC+10, Rick C wrote:
> > > ...
> > > Indeed. DX is pretty much the dictionary definition. I believe they have his picture as part of the most recent edition.
> >
> > Say the ANS/200x prisoners rattling their chains :)
>
> Rick Collins is definitely a troll. He knows nothing about Forth programming.
> I don't consider DXforth to be a troll.
>
> I consider DXforth to be an intermediate-level Forth programmer.
> He has mastered basic meta-compiling such as:
> : end postpone exit postpone then ; immediate
> He gets on my nerves because he endlessly promotes this trivial code.

The idea was to get you to promote it :)
Message has been deleted

foxaudio...@gmail.com

unread,
Jun 15, 2020, 9:19:41 AM6/15/20
to
On Monday, June 15, 2020 at 1:04:13 AM UTC-4, dxforth wrote:

> The idea was to get you to promote it :)

You made me laugh again. :-)

hughag...@gmail.com

unread,
Jun 16, 2020, 12:09:52 AM6/16/20
to
On Sunday, June 14, 2020 at 10:04:13 PM UTC-7, dxforth wrote:
> On Monday, June 15, 2020 at 1:04:54 PM UTC+10, hughag...@gmail.com wrote:
> > I consider DXforth to be an intermediate-level Forth programmer.
> > He has mastered basic meta-compiling such as:
> > : end postpone exit postpone then ; immediate
> > He gets on my nerves because he endlessly promotes this trivial code.
>
> The idea was to get you to promote it :)

I was being generous when I said that your END is intermediate-level.
This is really novice-level --- it provides nothing except that the user
types END rather than EXIT THEN --- this is another word for the user
to remember, further cluttering his already cluttered head.

My <SWITCH is intermediate-level Forth code.
It provides significant speed improvement over CASE and it has ranges
of numbers, strings of chars, etc., making it easier to use.
I wouldn't describe <SWITCH as advanced-level though --- MFX was advanced-level.

Look how well I'm doing at promoting it!

On Sunday, June 14, 2020 at 6:02:00 AM UTC-7, Gerry Jackson wrote:
> The rest of us go on happily using CASE, where appropriate, without
> worrying about so-called mistakes.

I don't want to promote your END that is just useless clutter.
Also, given my track record of complete failure at promoting anything,
you shouldn't want me to promote it either!

I'm more of a programmer than a promoter.

dxforth

unread,
Jun 16, 2020, 10:45:46 PM6/16/20
to
On Tuesday, June 16, 2020 at 2:09:52 PM UTC+10, hughag...@gmail.com wrote:
> ...
> I was being generous when I said that your END is intermediate-level.
> This is really novice-level --- it provides nothing except that the user
> types END rather than EXIT THEN --- this is another word for the user
> to remember, further cluttering his already cluttered head.
>
> My <SWITCH is intermediate-level Forth code.
> It provides significant speed improvement over CASE and it has ranges
> of numbers, strings of chars, etc., making it easier to use.
> I wouldn't describe <SWITCH as advanced-level though --- MFX was advanced-level.

If one accepts EXIT THEN has advantage and is statistically significant
then END is the logical conclusion. I'm not sure the same can be said
about <SWITCH et al.

hughag...@gmail.com

unread,
Jun 17, 2020, 3:05:23 AM6/17/20
to
On Wednesday, June 10, 2020 at 2:34:55 PM UTC-7, Gerry Jackson wrote:
> As in MLG's implementation the switch selectors are accumlated on the
> stack and processed when the final END is reached.
> ...
> At some stage I'll probably add two alternative versions, one for a
> sparse set of selectors using a binary search or hashing, ...

Gerry Jackson put his own copyright notice on Michael Gassanenko's code,
without understanding how the code works.

Michael Gassanenko used a bucket-sort --- the table is essentially
an array of buckets and all of those xt and selector value pairs go into
the buckets (the xt goes into the table and the selector value is the index).

As I have said many times in the past, the bucket-sort only works when
the values are within a small range. The bucket-sort fails when the
values are in a wide range that is too big for an array of buckets.
This is why Michael Gassanenko's algorithm is no good for a sparse set
of selector values --- their range is too big for an array of buckets.

I used my LIST.4TH to hold the selector values and associated xt values.
I used an insertion-sort to sort them on the fly, then FAST-SWITCH>
built the table from the sorted list afterward. Similarly, SLOW-SWITCH>
built the sorted array for the binary-search from the sorted list.
Given the sorted list, SLOW-SWITCH> was trivial to write.
Michael Gassanenko's algorithm is not robust. It worked okay for developing
something comparable to my FAST-SWITCH> but it could not be extended
to develop something comparable to my SLOW-SWITCH> .
My algorithm is more robust in that I built a sorted list which was then
trivial to use in both FAST-SWITCH> and SLOW-SWITCH> .

I'm not saying that Michael Gassanenko is a bad programmer.
He is pretty good. He is not as good as me, though.
He wrote CHOOSE as part of his PhD program. It was a homework assignment.
His professor presumably assigned him to write something roughly
equivalent to my FAST-SWITCH> so he did that, but he did not make his
code robust so it could be extended to something roughly equivalent
to my SLOW-SWITCH> because that wasn't part of the assignment specs.

Now we have Gerry Jackson stealing Michael Gassanenko's code and putting
his own copyright on it. Gerry Jackson's plan for defeating me is to
steal code from a smart Russian and claim that this makes him a better
Forth programmer than I am. This plan isn't going to work because there
aren't any Russians as smart as me, so when Gerry steals Russian code
it is still inferior to mine. Gerry Jackson says that his future plan
is to write code to support "a sparse set of selectors using a binary search
or hashing" (code roughly equivalent to my SLOW-SWITCH> ). This plan isn't
going to work because Michael Gassanenko's algorithm used a bucket-sort
and this doesn't support a wide range of selector values.
Gerry Jackson stole Michael Gassanenko's code without understanding how
the algorithm works, or what the algorithm's limitations were.
Gerry Jackson doesn't understand that there is no way in the future to
extend this algorithm to be roughly equivalent to my SLOW-SWITCH> .
Gerry Jackson needs to use an insertion sort, but where will he steal
the code for that? Maybe there is some other smart Russian somewhere who
has this code, and Gerry Jackson can steal it, in order to prove that he is
a better programmer than I am.

Ron AARON

unread,
Jun 17, 2020, 3:54:30 AM6/17/20
to


On 17/06/2020 10:05, hughag...@gmail.com wrote:
<snip>
> I'm not saying that Michael Gassanenko is a bad programmer.
> He is pretty good. He is not as good as me, though.
<snip>


Oh, Hugh! You just made my day!

So much ironic humour and lack of self-awareness in one post, it's pure
gold! Have you considered doing stand-up?

none albert

unread,
Jun 17, 2020, 5:06:22 AM6/17/20
to
In article <cabbd02f-1f39-4201...@googlegroups.com>,
This would benefit greatly from performance tables like the ones
Anton Ertl and Marcel Hendrix supply in this kind of discussion.

Groetjes Albert

NN

unread,
Jun 17, 2020, 7:03:02 AM6/17/20
to

2 questions keep popping up:

(1) when a case analysis is done, how often do you come across
examples where you mix types

(2) what problem is this addressing ( perhaps an real world
example would help )


hughag...@gmail.com

unread,
Jun 18, 2020, 1:05:17 AM6/18/20
to
On Wednesday, June 17, 2020 at 12:05:23 AM UTC-7, hughag...@gmail.com wrote:
> As I have said many times in the past, the bucket-sort only works when
> the values are within a small range. The bucket-sort fails when the
> values are in a wide range that is too big for an array of buckets.
> This is why Michael Gassanenko's algorithm is no good for a sparse set
> of selector values --- their range is too big for an array of buckets.

My <SWITCH compared to Michael Gassanenko's CHOOSE is a pretty good
example of why code-libraries are useful. I had LIST.4TH available
already, so it was trivial for me to use a list for my data,
and to use an insertion-sort for sorting it on the fly.
Michael Gassanenko was given a homework assignment by his professor
and presumably given a time limit (let say: two weeks). He didn't have
LIST.4TH or any other code-library available, so he had to implement
his CHOOSE in raw Forth. He didn't have time to first implement
LIST.4TH so he went with a bucket-sort because this seemed to be
the most expedient solution, that he could get done quickly.
This is what happens when people are under deadline pressure --- they
choose inappropriate algorithms because they can be quickly implemented
and they don't worry about the future. Michael Gassanenko may have been
aware that the bucket-sort was the worst possible choice because it
doesn't support a wide range of values such as would be needed for
something comparable to my SLOW-SWITCH> but he just hoped that his
professor wouldn't assign this as a homework assignment in the future.
The current homework assignment was just for something comparable
to my FAST-SWITCH> and the bucket-sort was adequate for this, so he
got the assignment done before deadline and didn't worry about the future.

Now, years later, we have Gerry Jackson stealing this CHOOSE code
and putting his own copyright on it. Gerry Jackson doesn't understand
that this is crap code produced under a deadline. Gerry Jackson
doesn't understand that the bucket-sort was the worst possible choice
for how to sort the data, and that it was only chosen because it was
expedient at the time, and there was no code-library available so
CHOOSE had to be written in raw Forth without any support.

I don't think that Gerry Jackson will ever succeed.
He is a maintenance programmer --- he can't program --- he relies
on finding programs written by people who are smarter than he is
(pretty much anybody) and stealing their code, pretending that
he wrote it himself, despite the fact that he doesn't understand
how the code works or what its limitations are.

Gerry Jackson depends upon squirmy little sycophants such as Ron Aaron
to cheer him on, with a complete lack of understanding of the
technical aspects of the software. That is the only future that he has.

hughag...@gmail.com

unread,
Jun 18, 2020, 11:59:40 PM6/18/20
to
On Wednesday, June 10, 2020 at 2:34:55 PM UTC-7, Gerry Jackson wrote:
> As in MLG's implementation the switch selectors are accumlated on the
> stack and processed when the final END is reached. However I found a
> simpler method of handling the complex mixture of integers and ranges.
> This resulted in less code, e.g. with GForth MLG's version compiled into
> 673 cells whereas mine occcupies 595 cells.

This is a very typical brag for a maintenance programmer, that he
reduced the size of the code by a few bytes. Nobody actually cares.
On VFX, my <SWITCH code is 3906 bytes and Gerry's code is 2680 bytes.
Of course, I have SLOW-SWITCH> that Gerry failed completely at.
My code requires LIST.4TH to already be included, and that is many
thousands of bytes in size --- of course, LIST.4TH is also useful
for other purposes, because it is a general-purpose data-structure.

This business of accumulating data on the data-stack is very typical
of programmers who don't have any general-purpose data-structures
available. This is a pretty crude technique! Also, you may have several
hundred data, and this may overflow your data-stack. I had LIST.4TH
available, so I put all the data in a sorted-list. That seemed very
obvious to me --- I didn't even consider piling up hundreds of data
on the data-stack and then processing them in place --- I don't recall
having ever done this (I learned Forth on the 6502, and it had a
pretty small data-stack).

> I found that I couldn't write an exact equivalent to MLG's version (as a
> control structure within another Forth definition) in standard Forth
> without going to unreasonable lengths.

Gerry Jackson is lying again.
He is saying that he knows how to embed a switch construct inside of
a colon word in ANS-Forth, but didn't do so because doing so would require
"going to unreasonable lengths." Bullshit! He doesn't know how to do this.
I don't know how to do this, and if I don't know how to do something,
then it is impossible.

I'm not impressed by Michael Gassanenko's CHOOSE code.
This doesn't mean that Michael Gassanenko is necessarily a bad programmer.
He may have been under an onerous deadline.
Also, this was a homework assignment, and we don't know what the rules
were for getting a passing grade. He may have been told that he was
not allowed to use general-purpose data-structures. Academia is different
from the real world --- there are sometimes bizarre restrictions
put in place to make the job more difficult than it needs to be.
Eaker's CASE was the winner of a "Forth Dimensions" contest.
This contest had restrictive rules not similar to the real world.
In general, code like this is not worth looking at (except by the
teacher who has to decide what grade it gets: 'A' 'B' 'C' 'D' or 'F').

dxforth

unread,
Jun 19, 2020, 1:22:35 AM6/19/20
to
On Friday, June 19, 2020 at 1:59:40 PM UTC+10, hughag...@gmail.com wrote:
> ...
> I'm not impressed by Michael Gassanenko's CHOOSE code.
> This doesn't mean that Michael Gassanenko is necessarily a bad programmer.
> He may have been under an onerous deadline.
> Also, this was a homework assignment, and we don't know what the rules
> were for getting a passing grade. He may have been told that he was
> not allowed to use general-purpose data-structures. Academia is different
> from the real world --- there are sometimes bizarre restrictions
> put in place to make the job more difficult than it needs to be.

No different to the 'requirements' you chose to place on <SWITCH.

> Eaker's CASE was the winner of a "Forth Dimensions" contest.
> This contest had restrictive rules not similar to the real world.

There were three equal winners. Eaker's was the one forth systems
have invariably implemented (long before ANS, I might add).

> In general, code like this is not worth looking at (except by the
> teacher who has to decide what grade it gets: 'A' 'B' 'C' 'D' or 'F').

Eaker's popularity is due to the fact that for non-critical apps it
represented value for money. And still does. The point at which
Eaker becomes inefficient is great enough that most users don't
bother with anything else. That's not to say Eaker can't be made
better value for money.

hughag...@gmail.com

unread,
Jun 20, 2020, 6:42:58 PM6/20/20
to
On Thursday, June 18, 2020 at 10:22:35 PM UTC-7, dxforth wrote:
> Eaker's popularity is due to the fact that for non-critical apps it
> represented value for money. And still does. The point at which
> Eaker becomes inefficient is great enough that most users don't
> bother with anything else. That's not to say Eaker can't be made
> better value for money.

Eaker's CASE has zero value. It can't be made better value
because multiplying zero by anything is still zero.
Putting Eaker's CASE in ANS-Forth was a huge win for the C promoters
because they could point to this as a very obvious flaw in ANS-Forth.
ANS-Forth has multiple gross flaws, but Eaker's CASE was obvious enough
that anybody with one week of programming experience could laugh at it.

Many C enthusiasts have used SWITCH in C to simulate a VM, which allows
them to easily write a Forth system in C. Quite a lot of C enthusiasts
claim to be big Forth experts, because they have implemented a Forth
system, but in the next breath they will say that Forth is a silly toy
that is worthless for practical applications --- the general idea
is that Forth is only interesting as a learning exercise for C students
(this idea is promoted by Anton Ertl the C teacher, and other C teachers).
This is why Rod Pemberton describes C as the "god language"
(he actually used that term; I couldn't make this stuff up!).

ANS-Forth has always been pretty much worthless for simulating a VM
because it lacks a SWITCH. I'm not aware of anybody having ever implemented
C or Pascal or any other language in Forth, primarily because of this problem.
My <SWITCH would work fine for simulating a VM, and it is ANS-Forth,
but it is also about 40 years too late --- this should have been done
in the early 1980s and been put in Forth-83 --- this didn't happen
because Elizabeth Rather was in charge of Forth-83, so it was crap too.

What is pathetic about this is that I implemented <SWITCH in two days.
The first day was for CASE-OF and FAST-SWITCH> and the second day was
for SLOW-SWITCH> --- this is intermediate-level Forth programming.
I already had LIST.4TH that helped a lot, but that is intermediate-level
Forth too --- Peter Knaggs failed to implement a general-purpose list,
but it is not difficult --- it is barely intermediate-level Forth.
Since then I upgraded SLOW-SWITCH> to make it faster, and also added
ranges etc., but this adds up to maybe one more day of work in total.
The ANS-Forth cult continues to fail at writing intermediate-level
Forth code. Four decades is a long time to remain at the novice-level
and fail to graduate to intermediate-level Forth programming.
That is like still being in kindergarten when you are six foot tall
and you no longer fit in the tiny desks that kindergarten children use.

It likely took Michael Gassanenko more than two days to implement his
CHOOSE --- and he only has something comparable to my FAST-SWITCH>
but nothing comparable to my SLOW-SWITCH> --- this is because his code
is a lot more complicated than my code. His code is over-complicated
because he didn't have any general-purpose data-structure available
that he could hold his data in --- he put all of his data (possibly
hundreds of data) on the data-stack and then moved it directly into
the table --- he didn't have a list for intermediate data-holding.
My code is simple and straightforward --- any novice Forth programmer
should be able to look at my code and understand it --- by comparison,
figuring out Michael Gassanenko's code requires a super-duper
maintenance programmer such as Gerry Jackson.

dxforth

unread,
Jun 21, 2020, 2:23:25 AM6/21/20
to
On Sunday, June 21, 2020 at 8:42:58 AM UTC+10, hughag...@gmail.com wrote:
> On Thursday, June 18, 2020 at 10:22:35 PM UTC-7, dxforth wrote:
> > Eaker's popularity is due to the fact that for non-critical apps it
> > represented value for money. And still does. The point at which
> > Eaker becomes inefficient is great enough that most users don't
> > bother with anything else. That's not to say Eaker can't be made
> > better value for money.
>
> Eaker's CASE has zero value. It can't be made better value
> because multiplying zero by anything is still zero.

On the contrary. The thing that OF does - namely 'OVER = IF DROP' - is
commonly encountered in Forth. Also handy is a way to resolve nested
IF ELSE without having to count the THENs - for which I use COND CONT.
Eaker chose to call this a 'CASE statement'. I simply call it useful.

hughag...@gmail.com

unread,
Jun 21, 2020, 3:03:29 PM6/21/20
to
On Saturday, June 20, 2020 at 11:23:25 PM UTC-7, dxforth wrote:
> The thing that OF does - namely 'OVER = IF DROP' - is
> commonly encountered in Forth.

No it isn't.

> Also handy is a way to resolve nested
> IF ELSE without having to count the THENs - for which I use COND CONT.
> Eaker chose to call this a 'CASE statement'. I simply call it useful.

This is not true either.

Here is an example using rquotations:
-------------------------------------------------------------------------
: ttt { adr cnt value -- }
r[
adr cnt s" aaa" compare 0= if 10 +to value rexit then
adr cnt s" bbb" compare 0= if 20 +to value rexit then
adr cnt s" ccc" compare 0= if 30 +to value rexit then
0 to value ]r rex0
cr ." calculated value: " value . ;
-------------------------------------------------------------------------

Here is a test of TTT shown above:
-------------------------------------------------------------------------
s" aaa" 5 ttt
calculated value: 15 ok
s" bbb" 5 ttt
calculated value: 25 ok
s" ccc" 5 ttt
calculated value: 35 ok
s" ddd" 5 ttt
calculated value: 0 ok
-------------------------------------------------------------------------

Please show us how you would do this!

Note that DXForth is well known to hate local variables.
I predict that he will howl that local variables are not necessary
in my example, and I could have used the data-stack instead.
That is not really the point though --- the point is to show how
to avoid an awkward ... IF ... IF ... IF ... THEN THEN THEN construct.
Also, local variables are useful for avoiding a lot of stack juggling
in more complicated code --- this was just a short example.

Here is a version without locals that should make DXForth happy:
-------------------------------------------------------------------------
: vvv ( adr cnt value -- )
r[ >r
2dup s" aaa" compare 0= if r> 10 + rexit then
2dup s" bbb" compare 0= if r> 20 + rexit then
2dup s" ccc" compare 0= if r> 30 + rexit then
rdrop 0 ]r rex0
cr ." calculated value: " .
2drop ;
-------------------------------------------------------------------------

Avoiding nested IF constructs isn't the primary purpose of rquotations.
This is just something that you get with rquotations also.

The Beez

unread,
Jun 21, 2020, 3:36:47 PM6/21/20
to
On Saturday, October 19, 2019 at 9:11:42 PM UTC+2, Gerry Jackson wrote:
> I came across this post in c.l.f.
>
> https://groups.google.com/forum/?hl=en#!searchin/comp.lang.forth/choose.htm%7Csort:date/comp.lang.forth/ZGCesckN0qI/zUh5IYNaa_UJ
4tH has always followed Leo Brodies advise: "The switch() statement is an elegant solution to a misguided problem". Hence, 4tH has NEVER offered a CASE..ENDCASE (although later you could withe the preprocessor).

In 4tH, we tackle this problem differently:

1) if all values are sequential, we create a sequentially laid out table with execution tokens, so that <cells table + @ execute> does the job;
2) if they are not and speed is of no importance, we create a table with values and execution tokens that can be sought sequentially;
3) if they are not and speed is important, we create a table with sorted values and execution tokens that can be sought by binary search.

Problem solved. Works very well and is easily maintainable.

Hans Bezemer

hughag...@gmail.com

unread,
Jun 21, 2020, 4:53:14 PM6/21/20
to
On Sunday, June 21, 2020 at 12:36:47 PM UTC-7, The Beez wrote:
> 4tH has always followed Leo Brodies advise: "The switch() statement is an elegant solution to a misguided problem". Hence, 4tH has NEVER offered a CASE..ENDCASE (although later you could withe the preprocessor).
>
> In 4tH, we tackle this problem differently:
>
> 1) if all values are sequential, we create a sequentially laid out table with execution tokens, so that <cells table + @ execute> does the job;
> 2) if they are not and speed is of no importance, we create a table with values and execution tokens that can be sought sequentially;
> 3) if they are not and speed is important, we create a table with sorted values and execution tokens that can be sought by binary search.
>
> Problem solved. Works very well and is easily maintainable.

Problem solved? Yay! The Beez has done it!
It took me two days to write <SWITCH etc., but he did it in two minutes!

Which problem was that, by the way? This is what I said:

On Thursday, June 11, 2020 at 8:14:32 PM UTC-7, hughag...@gmail.com wrote:
> My <SWITCH is intended to be used for simulating a micro-processor. ...
> FAST-SWITCH> allows a table with a range of 64K, so it can be used
> to simulate a 16-bit micro-processor.
> SLOW-SWITCH> is slower but allows a huge range, so it can be used
> to simulate a 32-bit micro-processor.

Simulating a micro-processor is useful for testing a large program
that has minimal I/O. An example would be a micro-controller
that has a small keypad and small display. The keypad and display
functions can be easily simulated so they use the host computer's
keyboard and display; this is pretty minimal I/O.
The program may be fairly large though, so testing it on the
actual hardware would be a hassle --- with a simulator you can
test it more thoroughly --- you can have break-points and
watch-variables, and other symbolic-debugger features.

Almost all micro-controllers are going to have 16-bit (or 8-bit)
opcodes, so FAST-SWITCH> would be adequate. SLOW-SWITCH> is for
processors with 32-bit opcodes, which is pretty rare.

More likely, SLOW-SWITCH> would be used for cases in which you
happen to have a wide range of values:
----------------------------------------------------------------
<switch ok-1
:noname drop cr ." we have: xx1000" ; <when 1000 101000 201000 301000 when> ok-1
:noname drop cr ." tilt!" ; fast-switch> hhh *** FAST-SWITCH> has too large of a range. Use SLOW-SWITCH> instead. ***
-> :noname drop cr ." tilt!" ; fast-switch> hhh
^
----------------------------------------------------------------
Ruh Roh!
We got a helpful error-message telling us that FAST-SWITCH> doesn't work.
We need to use SLOW-SWITCH> instead:
----------------------------------------------------------------
<switch ok-1
:noname drop cr ." we have: xx1000" ; <when 1000 101000 201000 301000 when> ok-1
:noname drop cr ." tilt!" ; slow-switch> hhh ok
here ' hhh - u. 57 ok
----------------------------------------------------------------
Notice that the table is quite small.

Here is Gerry Jackson's crap code in action:
----------------------------------------------------------------
create-switch ggg ok-5
1000 101000 201000 301000 when cr ." we have: xx1000" end ok-13
other cr ." tilt!" end ok-13
end ok
here ' ggg - u. 1200155 ok
----------------------------------------------------------------
Notice that he is using about a megabyte of dictionary space for
looking up four numbers. LOL
Gerry Jackson apparently doesn't believe in error-checking.

A. K.

unread,
Jun 21, 2020, 4:55:09 PM6/21/20
to
Wow (being impressed)!

Given that CASE..OF..ENDOF..ENDCASE is like an inefficient sequential step-down
ladder, it still has the advantage of being simple and short.

4th's switch constructs are more evolved and faster, but they carry also much
more weight in the compiler. Since the number of comparisons is not reduced,
the runtime performance increase is only caused by replacing those sequential
steps by address calculation or search into a jump table.

Just out of curiosity: did you do benchmarks of how many comparisons ("OFs")
are needed before the jump table method is faster than the simple sequential
method?

hughag...@gmail.com

unread,
Jun 21, 2020, 7:12:53 PM6/21/20
to
You said:
> 4th's switch constructs are more evolved and faster, but they carry also much
> more weight in the compiler.

The Beez's switch construct are not more evolved, nor do they carry much weight.
The Beez doesn't actually have any switch constructs.
All that he does is manually comma the data into a table.

On Thursday, July 25, 2019 at 7:10:56 AM UTC-7, The Beez wrote:
> So instead of a CASE statement, I have this:
>
> create stringtable
> ," drop" ' drop ,
> ," dup" ' dup ,
> ," over" ' over ,
> ," rot" ' rot ,
> ," swap" ' swap ,
> here stringtable - 2/ constant #stringtable ( for bsearch) OR:
> NULL , ( I'm lazy)
> DOES> (searchtable) ;

This has already been discussed here:
https://groups.google.com/forum/#!topic/comp.lang.forth/9IHvRJmMn20
I point out that his code doesn't work. Wow (being unimpressed)!

> Just out of curiosity: did you do benchmarks of how many comparisons ("OFs")
> are needed before the jump table method is faster than the simple sequential
> method?

Its two.
It is loading more messages.
0 new messages