• Re: Parsing timestamps?

    From Anthony Howe@21:1/5 to dxf on Sun Oct 6 11:35:24 2024
    On 2024-10-06 03:51, dxf wrote:
    Is there an easier way of doing this? End goal is a double number representing centi-secs.

    Isn't there an ISO 8601 parsing package?

    --
    Anthony C Howe
    achowe@snert.com BarricadeMX & Milters http://nanozen.snert.com/ http://software.snert.com/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to dxforth@gmail.com on Mon Oct 7 13:00:10 2024
    In article <1f433fabcb4d053d16cbc098dedc6c370608ac01@i2pn2.org>,
    dxf <dxforth@gmail.com> wrote:
    Is there an easier way of doing this? End goal is a double number >representing centi-secs.


    empty decimal

    : SPLIT ( a u c -- a2 u2 a3 u3 ) >r 2dup r> scan 2swap 2 pick - ;
    : >INT ( adr len -- u ) 0 0 2swap >number 2drop drop ;

    : /T ( a u -- $hour $min $sec )
    2 0 do [char] : split 2swap dup if 1 /string then loop
    2 0 do dup 0= if 2rot 2rot then loop ;

    : .T 2swap 2rot cr >int . ." hr " >int . ." min " >int . ." sec " ;

    s" 1:2:3" /t .t
    s" 02:03" /t .t
    s" 03" /t .t
    s" 23:59:59" /t .t
    s" 0:00:03" /t .t

    After ca. 50 years I have completed the $@ $! $+! $C+ $/ with
    $\ . Now I can do this

    "12:03:43" &: $\ TYPE &: $\ TYPE &: $\ TYPE
    43 03 12 OK

    "12:03:43" &: $/ TYPE &: $/ TYPE &: $/ TYPE
    12 03 43 OK

    Insert
    "hr" TYPE
    as required.

    I can't believe the long posts this sparks.

    Groetjes Albert
    --
    Temu exploits Christians: (Disclaimer, only 10 apostles)
    Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
    Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
    And Gifts For Friends Family And Colleagues.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From sjack@21:1/5 to dxf on Mon Oct 7 16:20:29 2024
    dxf <dxforth@gmail.com> wrote:
    The HH:MM:SS format is easy but how to deal with the variants shown above? They occur in the real world.

    Toad code:
    fload job
    : xx. 0 <# bl hold # # #> type ;
    : tab3. tab rot xx. swap xx. xx. ;

    -- &num ( g -- s )
    -- Convert g-string to numeric string address
    : &num drop 1- ;
    -- Note g-string is ANS string ( addr u )

    -- ts_elms ( "[hh:][mm:]ss<bl>" -- 0 0 ss | 0 mm ss | hh mm ss )
    -- Parse timestamp elements: hh=hours mm=minutes ss=seconds
    -- Input hh: element and hh:mm: combination elements may be left out
    -- if zero(s).
    : ts_elms
    bl word here count
    o+s do i c@ asc : = if bl i c! then loop
    0 0 0 here count
    begin
    bl split dup 0> while &num number drop
    5 roll drop -rot
    repeat 4drop
    ;


    ts_elms 25
    i. tab3. --> 00 00 25
    i. ts_elms 25 tab3. --> 00 00 25
    i. ts_elms 10:25 tab3. --> 00 10 25
    i. ts_elms 2:10:25 tab3. --> 02 10 25
    OK

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to dxforth@gmail.com on Tue Oct 8 09:41:07 2024
    In article <1f433fabcb4d053d16cbc098dedc6c370608ac01@i2pn2.org>,
    dxf <dxforth@gmail.com> wrote:
    Is there an easier way of doing this? End goal is a double number >representing centi-secs.


    empty decimal

    : SPLIT ( a u c -- a2 u2 a3 u3 ) >r 2dup r> scan 2swap 2 pick - ;
    : >INT ( adr len -- u ) 0 0 2swap >number 2drop drop ;

    : /T ( a u -- $hour $min $sec )
    2 0 do [char] : split 2swap dup if 1 /string then loop
    2 0 do dup 0= if 2rot 2rot then loop ;

    : .T 2swap 2rot cr >int . ." hr " >int . ." min " >int . ." sec " ;

    s" 1:2:3" /t .t
    s" 02:03" /t .t
    s" 03" /t .t
    s" 23:59:59" /t .t
    s" 0:00:03" /t .t

    This problem is ill posed. You don't specify what happens
    with less that 3 fields, or the meaning of the fields.
    Normally I make the tests to run before attempting to code.

    Groetjes Albert
    --
    Temu exploits Christians: (Disclaimer, only 10 apostles)
    Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
    Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
    And Gifts For Friends Family And Colleagues.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From sjack@21:1/5 to Ahmed on Tue Oct 8 15:19:25 2024
    Ahmed <melahi_ahmed@yahoo.fr> wrote:
    I know you don't care about this case, but:

    Yes, originally I had syntax checks, left them out to focus more on getting
    the zeros in.

    -- ts_elms ( "[hh:][mm:]ss<bl>" -- 0 0 ss | 0 mm ss | hh mm ss )
    -- Parse timestamp elements: hh=hours mm=minutes ss=seconds
    -- Input hh: element and hh:mm: combination elements may be left out
    -- if zero(s).
    : ts_elms
    bl word here count
    over c@ asc : = >r ( leading char check )
    2dup + 1- c@ asc : = ( lagging char check )
    r> or if ." --Invalid " 2drop rdrop exit then
    o+s do i c@ asc : = if bl i c! then loop
    0 0 0 here count
    begin
    bl split dup 0> while &num number drop
    5 roll drop -rot
    repeat 4drop
    ;

    [s] Invalid syntax
    i. ts_elms 25: tab3. --> --Invalid
    i. ts_elms :25 tab3. --> --Invalid
    i. ts_elms :25: tab3. --> --Invalid

    [s] Valid syntax
    ts_elms 25
    i. tab3. --> 00 00 25
    i. ts_elms 25 tab3. --> 00 00 25
    i. ts_elms 10:25 tab3. --> 00 10 25
    i. ts_elms 2:10:25 tab3. --> 02 10 25

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerry Jackson@21:1/5 to dxf on Fri Oct 18 15:46:27 2024
    On 06/10/2024 08:51, dxf wrote:
    Is there an easier way of doing this? End goal is a double number representing centi-secs.


    empty decimal

    : SPLIT ( a u c -- a2 u2 a3 u3 ) >r 2dup r> scan 2swap 2 pick - ;
    : >INT ( adr len -- u ) 0 0 2swap >number 2drop drop ;

    : /T ( a u -- $hour $min $sec )
    2 0 do [char] : split 2swap dup if 1 /string then loop
    2 0 do dup 0= if 2rot 2rot then loop ;

    : .T 2swap 2rot cr >int . ." hr " >int . ." min " >int . ." sec " ;

    s" 1:2:3" /t .t
    s" 02:03" /t .t
    s" 03" /t .t
    s" 23:59:59" /t .t
    s" 0:00:03" /t .t

    Another solution

    : /t ( ca u -- sec min hour )
    3 \ a count, decremented every recurse
    [: -rot dup 0>
    if 0. 2swap >number 1 /string 2swap drop ( -- ct ca' u' n1 )
    >r rot 1-
    recurse r> swap exit
    then 2drop
    ;] execute
    0 ?do 0 loop \ 0 hours and minutes if missing in source string
    ;
    : .t cr . ." hr " . ." min " . ." sec " ;

    cr
    s" 1:2:3" /t .t
    s" 02:03" /t .t
    s" 03" /t .t
    s" 23:59:59" /t .t
    s" 0:00:03" /t .t
    s" " /t .t
    s" :" /t .t
    s" :53" /t .t
    s" 11/12/13" /t .t \ Different separator
    s" 11::13" /t .t
    s" :::" /t .t
    s" 3:" /t .t
    s" 1:2:" /t .t

    \ Results
    1 hr 2 min 3 sec
    0 hr 2 min 3 sec
    0 hr 0 min 3 sec
    23 hr 59 min 59 sec
    0 hr 0 min 3 sec
    0 hr 0 min 0 sec
    0 hr 0 min 0 sec
    0 hr 0 min 53 sec
    11 hr 12 min 13 sec
    11 hr 0 min 13 sec
    0 hr 0 min 0 sec
    0 hr 0 min 3 sec
    0 hr 1 min 2 sec

    The last two could be regarded as wrong but you indicated elsewhere that
    they wouldn't occur.

    Any non-digit is a separator

    --
    Gerry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to mhx on Sat Jun 7 12:38:40 2025
    mhx wrote:

    On Sun, 6 Oct 2024 7:51:31 +0000, dxf wrote:

    Is there an easier way of doing this? End goal is a double number representing centi-secs.


    empty decimal

    : SPLIT ( a u c -- a2 u2 a3 u3 ) >r 2dup r> scan 2swap 2 pick - ;
    : >INT ( adr len -- u ) 0 0 2swap >number 2drop drop ;

    : /T ( a u -- $hour $min $sec )
    2 0 do [char] : split 2swap dup if 1 /string then loop
    2 0 do dup 0= if 2rot 2rot then loop ;

    : .T 2swap 2rot cr >int . ." hr " >int . ." min " >int . ." sec " ;

    s" 1:2:3" /t .t
    s" 02:03" /t .t
    s" 03" /t .t
    s" 23:59:59" /t .t
    s" 0:00:03" /t .t

    Why don't you use the fact that >NUMBER returns the given
    string starting with the first unconverted character?
    SPLIT should be redundant.

    -marcel

    : CHAR-NUMERIC? 48 58 WITHIN ;
    : SKIP-NON-NUMERIC ( adr u -- adr2 u2)
    BEGIN
    DUP IF OVER C@ CHAR-NUMERIC? NOT ELSE 0 THEN
    WHILE
    1 /STRING
    REPEAT ;

    : SCAN-NEXT-NUMBER ( n adr len -- n2 adr2 len2)
    2>R 60 * 0. 2R> >NUMBER
    2>R D>S + 2R> ;

    : PARSE-TIME ( adr len -- seconds)
    0 -ROT
    BEGIN
    SKIP-NON-NUMERIC
    DUP
    WHILE
    SCAN-NEXT-NUMBER
    REPEAT
    2DROP ;

    S" hello 1::36 world" PARSE-TIME CR .
    96 ok

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to B. Pym on Mon Jun 9 12:34:18 2025
    B. Pym wrote:

    mhx wrote:

    On Sun, 6 Oct 2024 7:51:31 +0000, dxf wrote:

    Is there an easier way of doing this? End goal is a double number representing centi-secs.


    empty decimal

    : SPLIT ( a u c -- a2 u2 a3 u3 ) >r 2dup r> scan 2swap 2 pick - ;
    : >INT ( adr len -- u ) 0 0 2swap >number 2drop drop ;

    : /T ( a u -- $hour $min $sec )
    2 0 do [char] : split 2swap dup if 1 /string then loop
    2 0 do dup 0= if 2rot 2rot then loop ;

    : .T 2swap 2rot cr >int . ." hr " >int . ." min " >int . ." sec " ;

    s" 1:2:3" /t .t
    s" 02:03" /t .t
    s" 03" /t .t
    s" 23:59:59" /t .t
    s" 0:00:03" /t .t

    Why don't you use the fact that >NUMBER returns the given
    string starting with the first unconverted character?
    SPLIT should be redundant.

    -marcel

    : CHAR-NUMERIC? 48 58 WITHIN ;
    : SKIP-NON-NUMERIC ( adr u -- adr2 u2)
    BEGIN
    DUP IF OVER C@ CHAR-NUMERIC? NOT ELSE 0 THEN
    WHILE
    1 /STRING
    REPEAT ;

    : SCAN-NEXT-NUMBER ( n adr len -- n2 adr2 len2)
    2>R 60 * 0. 2R> >NUMBER
    2>R D>S + 2R> ;

    : PARSE-TIME ( adr len -- seconds)
    0 -ROT
    BEGIN
    SKIP-NON-NUMERIC
    DUP
    WHILE
    SCAN-NEXT-NUMBER
    REPEAT
    2DROP ;

    S" hello 1::36 world" PARSE-TIME CR .
    96 ok


    Using regular expressions in SP-Forth.

    ( pcre.dll must be in your path.)
    REQUIRE PcreMatch ~ac/lib/string/regexp.f \ PCRE wrapper
    REQUIRE S>NUM ~nn\lib\s2num.f \ String to number


    VARIABLE HOW-MANY-SECONDS
    : INCREMENT-SECONDS ( n adr --)
    SWAP OVER @ 60 * + SWAP ! ;

    : PARSE-TIME ( adr len -- seconds)
    0 HOW-MANY-SECONDS !
    BEGIN
    S" \d+(.*)" PcreGetMatch
    WHILE
    S>NUM HOW-MANY-SECONDS INCREMENT-SECONDS
    REPEAT
    HOW-MANY-SECONDS @ ;

    S" hello 20::_:55 world" PARSE-TIME CR .

    1255

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to B. Pym on Tue Jun 10 09:18:33 2025
    B. Pym wrote:

    mhx wrote:

    On Sun, 6 Oct 2024 7:51:31 +0000, dxf wrote:

    Is there an easier way of doing this? End goal is a double number representing centi-secs.


    empty decimal

    : SPLIT ( a u c -- a2 u2 a3 u3 ) >r 2dup r> scan 2swap 2 pick - ;
    : >INT ( adr len -- u ) 0 0 2swap >number 2drop drop ;

    : /T ( a u -- $hour $min $sec )
    2 0 do [char] : split 2swap dup if 1 /string then loop
    2 0 do dup 0= if 2rot 2rot then loop ;

    : .T 2swap 2rot cr >int . ." hr " >int . ." min " >int . ." sec " ;

    s" 1:2:3" /t .t
    s" 02:03" /t .t
    s" 03" /t .t
    s" 23:59:59" /t .t
    s" 0:00:03" /t .t

    Why don't you use the fact that >NUMBER returns the given
    string starting with the first unconverted character?
    SPLIT should be redundant.

    -marcel

    : CHAR-NUMERIC? 48 58 WITHIN ;
    : SKIP-NON-NUMERIC ( adr u -- adr2 u2)
    BEGIN
    DUP IF OVER C@ CHAR-NUMERIC? NOT ELSE 0 THEN
    WHILE
    1 /STRING
    REPEAT ;

    : SCAN-NEXT-NUMBER ( n adr len -- n2 adr2 len2)
    2>R 60 * 0. 2R> >NUMBER
    2>R D>S + 2R> ;

    : PARSE-TIME ( adr len -- seconds)
    0 -ROT
    BEGIN
    SKIP-NON-NUMERIC
    DUP
    WHILE
    SCAN-NEXT-NUMBER
    REPEAT
    2DROP ;

    S" hello 1::36 world" PARSE-TIME CR .
    96 ok


    : SCAN-NUMBER-OR-SKIP ( n adr len -- n' adr' len')
    DUP >R
    0 0 2SWAP >NUMBER
    DUP R> =
    IF 2SWAP 2DROP 1 /STRING
    ELSE
    2>R D>S SWAP 60 * + 2R>
    THEN ;

    : PARSE-TIME ( adr len -- seconds)
    0 -ROT
    BEGIN
    DUP
    WHILE
    SCAN-NUMBER-OR-SKIP
    REPEAT
    2DROP ;

    S" hi 5 or 1 is 44 ho " PARSE-TIME CR .
    18104

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stephen Pelc@21:1/5 to All on Tue Jun 10 12:07:39 2025
    On 9 Jun 2025 at 23:40:28 CEST, "Hans Bezemer" <the.beez.speaks@gmail.com> wrote:

    Third, any statement must come with proof. And in this case that means extended benchmarking. I can tell you beforehand that I've never seen significant differences between locals and stack. I'm sorry to say that
    - but it's true.

    I suspect tthat the lack difference comes from the underlying Forth system.
    For threaded code systems, the threading costs a lot of performance. In
    our tests, subroutine threaded code on 32 bit systems averages 2.2
    times the performance of direct threaded code for 68k class CPUs.

    Once full native code compilation and optimisation is turned on, you
    can get surprising results. At one stage we (MPE) de-localled a
    substantial portion of the PowerNet TCP/IP stack - all in high-level
    Forth. For the modified code, size decreased by 25% and performance
    increased by 50%.

    Stephen
    --
    Stephen Pelc, stephen@vfxforth.com
    Wodni & Pelc GmbH
    Vienna, Austria
    Tel: +44 (0)7803 903612, +34 649 662 974 http://www.vfxforth.com/downloads/VfxCommunity/
    free VFX Forth downloads

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Stephen Pelc on Tue Jun 10 14:06:37 2025
    Stephen Pelc <stephen@vfxforth.com> writes:
    Once full native code compilation and optimisation is turned on, you
    can get surprising results. At one stage we (MPE) de-localled a
    substantial portion of the PowerNet TCP/IP stack - all in high-level
    Forth. For the modified code, size decreased by 25% and performance
    increased by 50%.

    This demonstrates that you implemented locals less efficiently than
    stack manipulation, not that locals are inevitably slow. For more
    information, see

    @InProceedings{ertl22-locals,
    author = {M. Anton Ertl},
    title = {Are Locals Inevitably Slow?},
    crossref = {euroforth22},
    pages = {48--49},
    url = {http://www.euroforth.org/ef22/papers/ertl-locals.pdf},
    url-slides = {http://www.euroforth.org/ef22/papers/ertl-locals-slides.pdf},
    video = {https://www.youtube.com/watch?v=tPjSKetEJn0},
    OPTnote = {presentation slides},
    abstract = {Code quality of locals on two code examples on
    various systems}
    }

    @Proceedings{euroforth22,
    title = {38th EuroForth Conference},
    booktitle = {38th EuroForth Conference},
    year = {2022},
    key = {EuroForth'22},
    url = {http://www.euroforth.org/ef22/papers/proceedings.pdf}
    }

    - anton
    --
    M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
    comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
    New standard: https://forth-standard.org/
    EuroForth 2023 proceedings: http://www.euroforth.org/ef23/papers/
    EuroForth 2024 proceedings: http://www.euroforth.org/ef24/papers/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to B. Pym on Wed Jun 11 09:25:50 2025
    B. Pym wrote:

    B. Pym wrote:

    mhx wrote:

    On Sun, 6 Oct 2024 7:51:31 +0000, dxf wrote:

    Is there an easier way of doing this? End goal is a double number representing centi-secs.


    empty decimal

    : SPLIT ( a u c -- a2 u2 a3 u3 ) >r 2dup r> scan 2swap 2 pick - ;
    : >INT ( adr len -- u ) 0 0 2swap >number 2drop drop ;

    : /T ( a u -- $hour $min $sec )
    2 0 do [char] : split 2swap dup if 1 /string then loop
    2 0 do dup 0= if 2rot 2rot then loop ;

    : .T 2swap 2rot cr >int . ." hr " >int . ." min " >int . ." sec " ;

    s" 1:2:3" /t .t
    s" 02:03" /t .t
    s" 03" /t .t
    s" 23:59:59" /t .t
    s" 0:00:03" /t .t

    Why don't you use the fact that >NUMBER returns the given
    string starting with the first unconverted character?
    SPLIT should be redundant.

    -marcel

    : CHAR-NUMERIC? 48 58 WITHIN ;
    : SKIP-NON-NUMERIC ( adr u -- adr2 u2)
    BEGIN
    DUP IF OVER C@ CHAR-NUMERIC? NOT ELSE 0 THEN
    WHILE
    1 /STRING
    REPEAT ;

    : SCAN-NEXT-NUMBER ( n adr len -- n2 adr2 len2)
    2>R 60 * 0. 2R> >NUMBER
    2>R D>S + 2R> ;

    : PARSE-TIME ( adr len -- seconds)
    0 -ROT
    BEGIN
    SKIP-NON-NUMERIC
    DUP
    WHILE
    SCAN-NEXT-NUMBER
    REPEAT
    2DROP ;

    S" hello 1::36 world" PARSE-TIME CR .
    96 ok


    : SCAN-NUMBER-OR-SKIP ( n adr len -- n' adr' len')
    DUP >R
    0 0 2SWAP >NUMBER
    DUP R> =
    IF 2SWAP 2DROP 1 /STRING
    ELSE
    2>R D>S SWAP 60 * + 2R>
    THEN ;

    : PARSE-TIME ( adr len -- seconds)
    0 -ROT
    BEGIN
    DUP
    WHILE
    SCAN-NUMBER-OR-SKIP
    REPEAT
    2DROP ;

    S" hi 5 or 1 is 44 ho " PARSE-TIME CR .
    18104


    Using local variables.

    : SCAN-NUMBER-OR-SKIP { n adr len -- n' adr' len' }
    0. adr len >NUMBER { adr' len' } D>S { m }
    len' len =
    IF n adr len 1 /STRING
    ELSE
    n 60 * m + adr' len'
    THEN ;

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to the.beez.speaks@gmail.com on Wed Jun 11 12:18:19 2025
    In article <nnd$215a8dbf$3352f729@c328f69c56780220>,
    Hans Bezemer <the.beez.speaks@gmail.com> wrote:
    On 11-06-2025 03:49, dxf wrote:
    On 11/06/2025 3:34 am, LIT wrote:
    ...
    Fourth, if the definition is extremely time-critical, those
    tricky stack manipulators, (e.g., ROT ROT) can really eat up
    clock cycles. Direct access to variables is faster."

    Pushing variables on the stack, executing them, along with their
    associated @ and ! eats clock cycles. This is certainly the case
    in the systems you use.

    Agreed.

    Yes, Brodie warns us next "but careful with variables' use
    too" - and I still think my use of variables in two examples
    I recently pasted wasn't "legit" in any way. It was just
    applying the tips you see above.

    When is it "legit" to give up? I've written routines I believed
    needed VARIABLEs. But after a 'cooling off' period, I can look
    at the problem again afresh and find I can do better. Folks will
    say in the real world one couldn't afford this. That's true and
    likely why I'm a hobbyist and not a professional programmer.
    OTOH it's pretty rare that I write routines with variables in them
    to begin with.

    As a guy who used Forth programming in a professional environment, I can
    at least tell you how I did it..

    When you're on the spot, you're on the spot - and you got to provide in
    the allotted time, even if it means making sub-optimal code. That's just
    the way it is, that's corporate life.

    Seriously? They ask me beforehand. Philips matlab got upset
    because they were not used to people finishing in the time they
    estimate.
    In another project I was 10% accurate on a total of 30 bugs, and
    within 30% of each bug individually.

    Then I was dropped as project leader into a project that had to finish
    in three months, and I succeeded. If I failed, nobody would complain.

    Fokker Space had a architectural design disapproved by ESO. It was due
    at a certain date. Big kudos if you succeed, and I did.


    If you tell your boss "Brodie told you to", he's gonna shake his head,
    ask who Brodie is and then ship you to the corporate shrink for an
    emergency session.

    There are stupid bosses, that insist on a one line change over
    as 10 line change, as if this made the change more "reliable".
    At the same time they disapprove of test automation.


    But what I did was to either collect stuff in advance ("Hey, that's a
    nice comma'd printout word by Ed. Better make it work in 4tH!") - or
    make certain libraries beforehand. In that case, all you have to do is
    to shove all those elements together and you're done. The tricky stuff
    is already in your tool chest..

    Take a look at the 4tH library and notice how much of this stuff is of
    no interest at all to the occasional user. Well, that was because it
    wasn't written for you. It was written to be applied at work, so I can
    do miracles and save my reputation. If you wanna win, you gotta cheat ;-)

    I don't agree that tool chests built on practice are personal.


    Hans Bezemer


    Groetjes Albert
    --
    Temu exploits Christians: (Disclaimer, only 10 apostles)
    Last Supper Acrylic Suncatcher - 15Cm Round Stained Glass- Style Wall
    Art For Home, Office And Garden Decor - Perfect For Windows, Bars,
    And Gifts For Friends Family And Colleagues.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stephen Pelc@21:1/5 to All on Wed Jun 11 11:39:48 2025
    On 10 Jun 2025 at 22:56:28 CEST, "LIT" <LIT> wrote:

    3. As Mr. Pelc remarked, stack operators are faster.

    This is what Mr. Pelc remarked, regarding such style
    of programming - yes, many years ago I was guilty of
    that too - already 15 years ago:

    https://groups.google.com/g/comp.lang.forth/c/m9xy5k5BfkY/m/FFmH9GE5UJAJ

    "Although the code is compilable and can be made efficient,
    the source code is a maintenance nightmare!"

    Maybe he changed his mind since that time - well, since
    he's here, you may want to ask him a question.

    I take the last paragraph as a sort of passive-aggressive asking
    of some indirectly
    asked question. Hence I don't really know what your/the question
    is. Never mind,
    you opened the box.

    Of course I change my mind in 15 years. I'm a human being and so
    am entitled to
    do so and will do so.

    Working code beats all. Clear maintainable code that is easy to
    understand is
    best. I am stil maintaining 40 year old code and my brain is not
    as fast as it used
    to be. Keep it simple. Poking around in a Forth source tree of 1.4
    million lines
    of source code is not what I want to do.

    Once twp implementation techniques provide performance within
    (say) a factor of
    1.5 or 2 of each other, I stop worrying. Short words are better
    than long ones.

    The locals or Forth stack discussions between Anton and myself
    show up a design
    flaw I made 30 years or more ago when the VFX native code
    generator was new.
    The use of ADDR <local> to return the address of the local is a
    mistake that can
    be replaced by a LOCAL[ size ] buffer. When this is done, code
    generation of
    locals can become significantly better. However, I'm not going to
    wreck client
    code for it. My successors can argue about it.

    On Usenet, I take people who use their real names more seriously
    than those who
    do not. Just get a better flame-proof suit and stop being so
    precious.

    Stephen

    --
    Stephen Pelc, stephen@vfxforth.com
    Wodni & Pelc GmbH
    Vienna, Austria
    Tel: +44 (0)7803 903612, +34 649 662 974 http://www.vfxforth.com/downloads/VfxCommunity/
    free VFX Forth downloads

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kerr-Mudd, John@21:1/5 to Hans Bezemer on Tue Jun 24 10:29:08 2025
    On Tue, 24 Jun 2025 11:12:00 +0200
    Hans Bezemer <the.beez.speaks@gmail.com> wrote:

    On 23-06-2025 20:48, LIT wrote:

    OK, have another song: Mr. FIFO stating that
    "arrays aren't variables" (maybe need a link?).
    Where did they taught you that? At that 'college'
    of yours, "elite programmer"? :D

    Oh honey, you don't understand? That's not a problem, hon. Go to mummy,
    she will explain it to you. But daddy doesn't have time for you. He's
    talking to the grown ups. Go play with your dolls and be a good girl!

    Please, give up the insults; let your coding skills do the talking.

    --
    Bah, and indeed Humbug.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Hans Bezemer on Tue Jun 24 16:23:19 2025
    Hans Bezemer <the.beez.speaks@gmail.com> writes:
    I'm also puzzled why there is always so emphasis on the "speed" issue. I
    mean - if you want speed, do your program in C -O3 so to say. It'll blow
    any Forth out of the water.

    Take a look at the bubble benchmark in Figure 1 of <https://www.complang.tuwien.ac.at/papers/ertl24-interpreter-speed.pdf>. SwiftForth, VFX, and Gforth with all optimizations (the baseline) are
    faster than gcc-12 -O3. The reason for that is:

    |For bubble, gcc -O3 auto-vectorizes, and the result is that there is
    |partial overlap between a store and a following load, which results
    |in the hardware taking a slow path rather than performing one of its |store-to-load forwarding optimizations.

    - anton
    --
    M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
    comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
    New standard: https://forth-standard.org/
    EuroForth 2023 proceedings: http://www.euroforth.org/ef23/papers/
    EuroForth 2024 proceedings: http://www.euroforth.org/ef24/papers/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Tue Jun 24 22:38:33 2025
    dxf <dxforth@gmail.com> writes:
    Forth forces an average programmer to adopt a level of organisation
    sooner than a locals- based language. I suspect forthers that promote
    locals are well aware forth is readable and maintainable but are
    pursuing personal agendas of style which requires implying the
    opposite.

    IDK, I've seen some unreadable Forth code that was written by experts.
    Whether locals could have helped, I don't know.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Hans Bezemer on Wed Jun 25 00:21:23 2025
    Hans Bezemer <the.beez.speaks@gmail.com> writes:
    Fundamentally. I explained the sensation at the end
    of "Why Choose Forth". I've been able to tackle things I would never
    have been to tackle with a C mindset. ( https://youtu.be/MXKZPGzlx14 )

    I just watched this video and enjoyed it, but I don't understand how a C mindset is different. In C you pass stuff as function parameters
    instead of on the stack: what's the big deal? And particularly, the
    video said nothing about the burning question of locals ;).

    It seems to me all the examples mentioned in the video (parsing CSV
    files or floating point numerals) are what someone called
    micro-problems. Today they much easier with languages like Python, and
    back in Forth's heyday there was Lisp, which occupied a mindspace like
    Python does now.

    I agree that Thinking Forth is a great book.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to no.email@nospam.invalid on Wed Jun 25 12:14:30 2025
    In article <87h6041iue.fsf@nightsong.com>,
    Paul Rubin <no.email@nospam.invalid> wrote:
    dxf <dxforth@gmail.com> writes:
    Forth forces an average programmer to adopt a level of organisation
    sooner than a locals- based language. I suspect forthers that promote
    locals are well aware forth is readable and maintainable but are
    pursuing personal agendas of style which requires implying the
    opposite.

    IDK, I've seen some unreadable Forth code that was written by experts. >Whether locals could have helped, I don't know.

    Maybe you are mistaken. I have seen unmaintainable code written by
    some self-proclaimed experts.
    I have not seen unmaintainable code written by real experts.
    I have seen a lot of code. 70% of my 40+ years was spent on removing
    defects or enhancing existing code.

    There is a problem with the word unreadable. The 800 page proof
    of the Fermat theorem is unreadable. At first sight my manx code
    is unreadable. I read children stories in Chinese, to most Westerners
    they are unreadable.

    The story goes that a Boeing doesn't fly until the documentation weight
    rivals that of the airplane. I was in the middle of such a process in
    Dutch railway design where safety matters.
    Pick a document of this gigantic pile and you can't make heads or tails
    of it.
    Or get the deepseek seminal publication. The only thing that most people understand is the "11 million dollars" some how spent.

    Groetjes Albert
    --
    The Chinese government is satisfied with its military superiority over USA.
    The next 5 year plan has as primary goal to advance life expectancy
    over 80 years, like Western Europe.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to albert@spenarnc.xs4all.nl on Wed Jun 25 21:05:15 2025
    albert@spenarnc.xs4all.nl writes:
    Maybe you are mistaken. I have seen unmaintainable code written by
    some self-proclaimed experts.
    I have not seen unmaintainable code written by real experts.

    IDK about unmaintainable by other experts, but I've looked at cmForth
    (written by Moore) and figForth (written I guess by Bill Ragsdale) and
    found both incomprehensible. If those guys aren't experts then the bar
    must be pretty high. I do find eForth readable.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Waldek Hebisch@21:1/5 to Hans Bezemer on Thu Jun 26 05:20:13 2025
    Hans Bezemer <the.beez.speaks@gmail.com> wrote:

    No really, I'm not kidding. When done properly Forth actually changes
    the way you work. Fundamentally. I explained the sensation at the end of
    "Why Choose Forth". I've been able to tackle things I would never have
    been to tackle with a C mindset. ( https://youtu.be/MXKZPGzlx14 )

    I do not look at videos (mostly because they are extremally wasteful
    way of transmiting concepts, with words once can do this faster).
    So I will comment mostly on what you wrote.

    Like I always wanted to do a real programming language - no matter how primitive. Now I've done at least a dozen - and that particular trick
    seems to get easier by the day.

    I am not sure what you mean "do a real programming language".
    I have written compilers. The ones where I did all the work
    I consider to be toys. But I am pretty confident that if
    I wanted I could extend them to a practical language. I also
    work on real compilers, but here majority of work was done by
    other people and I only worked on parts. Still, while in
    a single compiler "my" part (or parts) are minority, they
    together cover all stages of practical compiler.

    I did not write a serious interpreter or even a part of it
    but I looked at code in several interpreters and I think that
    I understand subject well enough to write on if needed.

    And IMHO a lot can be traced back to the very simple principles Forth is based upon - like a stack. Or the triad "Execute-Number-Error". Or the dictionary. But also the lessons from ThinkForth.

    Traditional way to implement Forth is just one way. It is
    relatively simple, so this may be attractive. But I would
    say not the simplest one: bytecode interpreters are less
    clever, so in a sense simpler (at cost of slower execution).
    Compilers generating native code can be simple too, and
    one can argue that they also need less cleverness than Forth
    (but probably more object code).

    You'll also find it in my C work. There are a lot more "small functions"
    than in your average C program. It works for me like an "inner API". Not
    to mention uBasic/4tH - There are plenty of "one-liners" in my
    uBasic/4tH programs.

    But that train of thought needs to be maintained - and it can only be maintained by submitting to the very philosophy Forth was built upon. I
    feel like if I would give in to locals, I'd be back to being an average
    C programmer.

    I still do C from time to time - but it's not my prime language. For
    this reason - and because I'm often just plain faster when using Forth.
    It just results in a better program.

    My philosophy for developing programs is "follow the problem".
    That is we a problem to solve (task to do). We need to
    understand it, introduce some data structures and specify
    needed computation. This is mostly independent from programming
    language. When problem is not well understood we need
    to do some research. In this experiments may help a lot
    and having interactive programming language in useful
    (so this is plus of Forth compared to C). Once we have
    data structures and know what computation is needed we
    need to encode (represent) this in choosen language.
    I would say that large scale structure of the program
    will be mostly independent of programming language.
    There will be differences at small scale, as different
    languages have different idioms. "Builtin" features of
    language or "standard" libraries may do significant
    part of work. Effort of coding may vary widely,
    depending how much is supported by the language and
    surroundig ecosystem and how much must be newly
    coded. Also, debugging features of programming
    system affect speed of coding.

    Frankly, I do not see how missing language features
    can improve design. I mean, there are people who
    try to use fancy features when thay are not needed.
    But large scale structure of a program should not be
    affected by this. And at smaller scale with some
    experience it is not hard to avoid unneeded features.
    I would say that there are natural way to approach
    given problem and usually best program is one that
    follows natural way. Now, if problem naturally needs
    several interdependent attributes we need to represnt
    them in some way. If dependence is naturaly in stack
    way, than stack is a good fit. If dependence is not
    naturaly in a stack way, using stack may be possible
    after some reorganisation. But may experience is
    that if a given structure does not naturally appear
    after some research, than reorganisation is not
    very likely to lead to such structure. And even if
    one mananges to tweak program to such structure, it
    is not clear if it is a gain. Anyway, there is substantial
    number of problem where stack is unlikely to work in
    natural way. So how to represnt attributes? If they
    are needed only inside a single function, than natural
    way is using local variables. One can use globals, but
    for variables that are not needed outside a function
    this in unnatural. One can use stack juggling, this
    works, but IMO is unnatural. One can collect attributes
    in a single structure dynamically allocated at
    function entry and freed at exit. This works, but
    again is unnatural and needs extra code.

    Of course, sometimes other solutions are possible. Maybe
    instead of separate variables one can recompute attributes
    from something more basic. Maybe some group of attributes
    is needed in several functions, then keeping them as part
    of single structure is natural. But assuming that you
    write program in natural way, you would choose alternative
    what it is natural and choose locals only when thay
    are a good fit.

    You have some point about length of functions. While
    pretty small functions using locals are possible, I
    have a few longer functions where main reason for keeping
    code in one function is because various parts need access
    to the same local variables. But I doubt that eliminating
    locals and splitting such functions leads to better code:
    we get a cluster of function which depend via common
    attibutes. This dependence is there regardless of having
    single bigger function or several smaller ones (and
    regardless how one represents attributes). But with a
    single function dependence is explict, and for me easier
    to manage.

    Avoiding dependence helps, but above I mean unavoidable
    dependence. And in fact, I find locals useful to avoid
    false dependencies (where a buch of functons look like
    they depend on something but in fact they do not).

    I still do C from time to time - but it's not my prime language. For
    this reason - and because I'm often just plain faster when using Forth.
    It just results in a better program.

    The only thing I can say is, "it works for me". And when I sometimes
    view the works of others - especially when resorting to a C style - I
    feel like it could work for you as well.

    Nine times out of ten one doesn't need the amount of locals which are applied. One doesn't need a 16 line word - at least not when you
    actually want to maintain the darn thing. One could tackle the problem
    much more elegant.

    My policy is that variable should be a single logical thing.
    Which means that frequently I have more variables than
    "strictly necessary". That is I do not reuse variable for
    different purpose even if that would be possible. IMO
    saving here are compiler job, and in case when compiler is
    not doing this savings are not worth extra effort (and
    IMO worse program structure). Not that in reasonable program
    we are talking here about something like say 100 words
    or maybe 1000 words which may be significant on a small
    embedded system (but compilers for such system are reasonably
    good at reusing variables), but is irrelevant for bigger systems.


    --
    Waldek Hebisch

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Thu Jun 26 00:12:41 2025
    dxf <dxforth@gmail.com> writes:
    Define 'unreadable'. In general I don't need to understand the nitty
    gritty of a routine. But should I and no stack commentary exists, I've
    no objections to creating it. It's par for the course in Forth. If it bugged me I wouldn't be doing Forth.

    Unreadable = I look at the code and have no idea what it's doing. The
    logic is often obscured by stack manipulation. The values in the stack
    are meaningful to the program's operation, but what is the meaning? In
    most languages, meaningful values have names, and the names convey the
    meaning. In Forth, you can write comments for that purpose. Years
    after cmForth was published, someone wrote a set of shadow screens for
    it, and that helped a lot.

    With no named values and no explanatory comments, the program becomes
    opaque.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Thu Jun 26 21:03:46 2025
    dxf <dxforth@gmail.com> writes:
    Yet forthers have no problem with this. Take the SwiftForth source code.
    At best you'll get a general comment as to what a function does. How do
    they maintain it - the same way anyone proficient in C maintains C code.

    Certainly it was a Forther who found cmForth needed that extra
    documentation, and took the trouble to write it. C code as I mentioned partially self-documents because it uses named variables in places where
    Forth would have the value in an anonymous stack slot.

    I looked at some of the SwiftForth library code (the stuff on their web
    site) and I did find that pretty readable.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to dxforth@gmail.com on Fri Jun 27 15:15:38 2025
    In article <cdc7dfbc45ed94246aba7cb36c7272af7c6ba017@i2pn2.org>,
    dxf <dxforth@gmail.com> wrote:
    On 26/06/2025 5:12 pm, Paul Rubin wrote:
    dxf <dxforth@gmail.com> writes:
    Define 'unreadable'. In general I don't need to understand the nitty
    gritty of a routine. But should I and no stack commentary exists, I've
    no objections to creating it. It's par for the course in Forth. If it
    bugged me I wouldn't be doing Forth.

    Unreadable = I look at the code and have no idea what it's doing. The
    logic is often obscured by stack manipulation. The values in the stack
    are meaningful to the program's operation, but what is the meaning? In
    most languages, meaningful values have names, and the names convey the
    meaning. In Forth, you can write comments for that purpose. Years
    after cmForth was published, someone wrote a set of shadow screens for
    it, and that helped a lot.

    With no named values and no explanatory comments, the program becomes
    opaque.

    Yet forthers have no problem with this. Take the SwiftForth source code.
    At best you'll get a general comment as to what a function does. How do
    they maintain it - the same way anyone proficient in C maintains C code. >Albert is correct. Familiarity is key to readability. That's not to say >code deserving documentation shouldn't have it. OTOH one shouldn't be >expecting documentation (including stack commentary) for what's an everyday >affair in Forth.


    The comment about fig-Forth is incorrect. All snippets of code are
    at most 10 lines long, and the function is documented in the glossary.
    So a minimal comprehension of 8086 code is sufficient.
    OTOH, a Debian developer pointed me to a github archive from him
    as shining example.
    I studied it. Not a single source file contains a header what it
    was about. Moreover a global description was missing. I had no clue
    what the purpose of the program was. I lost a lot of trust in Debian.

    Groetjes Albert
    --
    The Chinese government is satisfied with its military superiority over USA.
    The next 5 year plan has as primary goal to advance life expectancy
    over 80 years, like Western Europe.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Sun Jun 29 15:26:32 2025
    dxf <dxforth@gmail.com> writes:
    But aren't 'locals' actually PICK/ROLL in disguise?
    Do PICK/ROLL skim all the values off the stack and stuff them in
    variables to be later popped on and off the stack like a yo-yo?

    Locals can be (and I thought usually are) implemented with the
    equivalent of PICK and POST, on either the R stack or a separate L
    stack. ROLL is different, "n ROLL" actually shuffles n items around and
    in most situations seems kind of nuts.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From sean@conman.org@21:1/5 to It was thus on Mon Jun 30 01:43:24 2025
    It was thus said that the Great LIT <zbigniew2011@gmail.com> once stated:
    The more common complaint is that you use some feature they dislike
    (typically locals) when you would otherwise DUP ROT instead.

    But aren't 'locals' actually PICK/ROLL in disguise?

    In my implementation [1], it's a PICK off the return stack (technically,
    from a set point in the return stack) as locals aren't allowed to remain on
    the data stack per the ANS standard.

    -spc

    [1] <https://github.com/spc476/ANS-Forth>, specifically, forth.asm
    starting at line 7793.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Sun Jun 29 23:18:56 2025
    dxf <dxforth@gmail.com> writes:
    What is POST ?

    Opposite of PICK. Overwrites a slot in the middle of the stack. I saw
    that name in another clf post pretty recently, idk if it is commonly implemented. I think I've also seen it called POKE. I'd call it
    barbaric from a stack programming perspective if done in user code, but
    if the compiler does it in some specific implementation, I don't mind.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to LIT on Mon Jun 30 02:44:35 2025
    zbigniew2011@gmail.com (LIT) writes:
    "Pick and Roll are the generic operators which treat the data stack as
    an array. If you find you need to use them, you are probably doing it
    wrong. Look for ways to refactor your code to be simpler instead."

    What is the origin of that quote? PICK treats the stack like an array,
    but ROLL treats it more as a circular shift register.

    Most CPUs these days have a register file, which is essentially an array
    with only immediate-like addressing mode. Presumably that design
    evolved because programmers found it useful.

    PICK afaict is mostly used with literal offsets as well. Having a
    variable offset is suspicious.

    : 3DUP ( a b c -- a b c a b c ) 3 PICK 3 PICK 3 PICK ;

    Seems clearer than some mess of ROT and return stack temporaries.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to the.beez.speaks@gmail.com on Mon Jun 30 21:05:47 2025
    In article <nnd$7a5cfad1$76518ba7@2a4e6190d58511e2>,
    Hans Bezemer <the.beez.speaks@gmail.com> wrote:
    On 25-06-2025 09:21, Paul Rubin wrote:
    Hans Bezemer <the.beez.speaks@gmail.com> writes:
    Fundamentally. I explained the sensation at the end
    of "Why Choose Forth". I've been able to tackle things I would never
    have been to tackle with a C mindset. ( https://youtu.be/MXKZPGzlx14 )

    I just watched this video and enjoyed it, but I don't understand how a C
    mindset is different. In C you pass stuff as function parameters
    instead of on the stack: what's the big deal? And particularly, the
    video said nothing about the burning question of locals ;).

    It seems to me all the examples mentioned in the video (parsing CSV
    files or floating point numerals) are what someone called
    micro-problems. Today they much easier with languages like Python, and
    back in Forth's heyday there was Lisp, which occupied a mindspace like
    Python does now.

    I agree that Thinking Forth is a great book.

    It's hard to illustrate things with a multi-KLOC program IMHO. You can
    only illustrate principles by using examples that are "contained" in a way.

    But I'll try to illustrate a thing or two. Let's say you want to tackle
    a problem. And it doesn't go your way. You have to add this thing and
    that thing - and hold on to that value. You know what I mean.

    about to add. Take a look at getopt() - I think that's a good example.
    You can almost see how it grew almost organically by the authors hand.
    He never seemed to think "Hmm, maybe I'll make a separate function of it".

    getopt is a design error in Forth filosofy. You are writing an interpreter
    and Forth is the only interpreter, first commandment.

    EXAMPLE:

    : option? DROP C@ &- = ;
    : handle-arg 1 ARG[] 2DUP option? IF handle-option ELSE handle-file THEN ;
    : handle-args BEGIN ARGC 1 > WHILE handle-arg REPEAT intel-hex? ;

    \ Execute help directly. We don't want any interference.
    : -h help BYE ;

    : -c arg-number DROP DECIMAL 1000 * frequency ! 1 multiple !
    ARGC 1 <> ABORT" calculate requires 1 argument" ;

    \ Note the `arg-number word is no good for multiple arguments.
    : -m 1 ARG[] 2 <> ABORT" incorrect multiple args"
    SHIFT-ARGS \ rid of -m
    frequency DUP 4 CELLS + SWAP DO
    0. 1 ARG[] >NUMBER 0<> 107 ?ERROR 2DROP
    1000 * I ! SHIFT-ARGS
    1 CELLS +LOOP 4 multiple !
    ARGC 1 <> ABORT" multiple requires 4 arguments"
    ;

    : main
    defaults 0 multiple ! handle-args
    multiple @ 0= IF ." specify -h, -c or -m " CR BYE THEN
    init custom-action init-calibration-flash
    doit
    ;
    --
    The Chinese government is satisfied with its military superiority over USA.
    The next 5 year plan has as primary goal to advance life expectancy
    over 80 years, like Western Europe.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Mon Jun 30 13:43:09 2025
    dxf <dxforth@gmail.com> writes:
    The stack ops THEMSELVES may be, in a way, "canonical" — but not
    solving "each and every" programming task using them
    "no-matter-what", IMHO.

    But such would indicate a deficiency in Forth. Do C programmers reach a point at which they can't go forward?

    Assembly language programmers reach a point where they run out of
    machine registers and have to do clumsy things to swap stuff between
    registers and memory. C compilers automate that process. Every C
    compiler with register allocation has to deal with register spilling.
    The programmer doesn't have to deal with it, but it's similar clumsy
    assembly code coming out of the compiler.

    In Forth without using locals, "register allocation" (deciding what is
    in each stack slot) is manual and there are fewer "registers" to begin
    with (basically TOS, NOS, TOR, and the 3rd stack element that you can
    reach with ROT). Modern CPUs by comparison generally have 16 or more addressible registers. The PDP-11 and 8086 had 8 registers and
    programmers found that to be painful.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stephen Pelc@21:1/5 to All on Tue Jul 1 13:26:16 2025
    On 30 Jun 2025 at 15:57:28 CEST, "Hans Bezemer" <the.beez.speaks@gmail.com> wrote:

    On 24-06-2025 18:23, Anton Ertl wrote:
    Hans Bezemer <the.beez.speaks@gmail.com> writes:
    I'm also puzzled why there is always so emphasis on the "speed" issue. I >>> mean - if you want speed, do your program in C -O3 so to say. It'll blow >>> any Forth out of the water.

    One of our clients makes a construction estimating package
    https://www.rib-software.com/en/rib-candy

    When ported from MPE's last threaded-code Forth to the early VFX Forth,
    screen redraw for the plan of part of a very large building improved by a factor
    of ten. The client was very pleased - this was a visible change for their users.

    I have also found that fast code enables me not to use progrmming tricks, but to code for readability and the maintenance programmer. I'm still maintaining code I first saw 40 years ago - not much of it, but always a pain to maintain.

    Still, in general - GCC beats Forth. Although I have to admit I've got a renewed respect for VFX Forth! Kudos!

    Thanks ... blush.

    Compiler output performance depends very much on the amunt of time and
    money spent on developing it. The VFX code generator was part of the
    planned output of an EU ESPRIT project.

    Stephen

    --
    Stephen Pelc, stephen@vfxforth.com
    Wodni & Pelc GmbH
    Vienna, Austria
    Tel: +44 (0)7803 903612, +34 649 662 974 http://www.vfxforth.com/downloads/VfxCommunity/
    free VFX Forth downloads

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)