• Re: Back & Forth - 4tH I/O and You

    From albert@spenarnc.xs4all.nl@21:1/5 to the.beez.speaks@gmail.com on Sun May 18 20:55:27 2025
    In article <nnd$68843db9$0f3297b6@f356aed0e515fe8b>,
    Hans Bezemer <the.beez.speaks@gmail.com> wrote:
    <SNIP>
    Note: this isn't Python or PHP like "easy to use" - where the magician
    hides the rabbit behind his back. The effect is perfectly predictable -
    and quite intuitive (if I may say so myself).

    Note in C, printf() isn't capable of redirection (unless from OS level). >fprintf() is - but how many people use it in combination with stdout
    (present company excepted)?

    I sold my soul to the c people, and embraced single bytes characters
    and redirection.
    : EMIT
    DSP@ 1 TYPE DROP
    ;

    : TYPE
    1 WRITE-FILE THROW
    ;

    (Windows: replace 1 with STDOUT)

    What I like is that I can test all errors/exceptions in my Forth
    bye 2>&1 .

    The integration with the OS-es makes for useful applications. ~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: cat printhex.frt
    : doit 1 ARG[] EVALUATE HEX . ;
    ~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: printhex 1024;echo
    400

    [lina -c printhex.frt]


    Hans Bezemer



    --
    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 mhx@21:1/5 to albert@spenarnc.xs4all.nl on Sun May 18 19:10:34 2025
    On Sun, 18 May 2025 18:55:27 +0000, albert@spenarnc.xs4all.nl wrote:

    In article <nnd$68843db9$0f3297b6@f356aed0e515fe8b>,

    The integration with the OS-es makes for useful applications. ~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: cat printhex.frt
    : doit 1 ARG[] EVALUATE HEX . ;
    ~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: printhex 1024;echo
    400

    [lina -c printhex.frt]

    In iForth we can redirect to a string:

    : ngspice-POSTLUDE ( -- c-addr u )
    DRY-RUN ( using TASK-DATA setup by SP>NGSPICE )
    |head .paramdata LOCAL mem
    <$$ ." * Generated by iSPICE on " .TIME$ ." -- do not edit"
    CR
    CR ." .control"
    CR ." unset ltspice"
    CR ." unset dotstep"
    CR ." set numthreads=1
    CR ." set ispice = " #|params 0<> 1 AND .
    CR ." "
    ." let spiceidx = $SPICEIDX ; "
    ." let ntasks=" #|tasks ."#"
    ." let ncpus=" #|cpus ."#"
    ." let nparams=" #|params ."#"
    ." let nresults=" #|results ."#"
    #|params
    IF CR ." compose p values "
    #|tasks 0 ?DO CR ." + "
    #|params 0 ?DO mem DF@+ TO mem
    F.N2+_
    LOOP
    LOOP
    CR #|params 1 > IF ." reshape p[" #|tasks
    0DEC.R ." ][" #|params
    0DEC.R ." ]"
    ENDIF
    ENDIF
    CR ." let ignore = 0"
    CR ." let buf = 0"
    CR ." let done = 0"
    CR ." let ix = spiceidx"
    CR ." compose arg values " #|tasks #|results * .
    #|results 0DEC.R ." ix 0 0.0"
    CR ." compose status values ncpus spiceidx"

    CR ." dowhile ix < ntasks"
    #|params 0 ?DO CR #|params 1 > IF ." let buf = p[ix][" I
    0DEC.R ." ]"
    ELSE ." let buf = p[ix]"
    ENDIF
    CR ." alterparam " |head .pnames I CSTR[] .$
    ." = $&buf"
    LOOP
    #|params IF CR ." mc_source" ENDIF
    CR ." " $SIM @+ 1 /STRING TYPE
    #|results 0 ?DO CR ." let arg[3] = " I ."#"
    CR ." " I (meashead) TYPE
    ." arg[4] " I (measbody) TYPE
    CR ." let ignore=setresult(arg) "
    LOOP
    CR ." let ix = ix + ncpus"
    CR ." let arg[2] = ix"
    CR ." write " RAWDATA-NAME
    NO-EXTENSION
    S" _{$spiceidx}{.raw}"
    $+ TYPE
    #|tasks IF CR ." set appendwrite" ENDIF
    CR ." end"
    CR ." let done = setfinish(status)"
    CR ." quit"
    CR ." .endc"

    SCRIPTFILE-NAME DUMP-TO-FILE
    CR ." Please manually add the following lines to `" cktfile .$ ." .sp`"
    CR
    CR ." .LIBRARY basic.lib basicstuff"
    CR ." .OPTION savecurrents"
    CR ." .INC " cktfile .$ ." .iscript"
    CR ; PRIVATE

    ( This mixes Forth with the SPICE shell script language )

    Result:

    * Generated by iSPICE on 23:19:11, December 9, 2024 -- do not edit

    control
    unset ltspice
    unset dotstep
    set numthreads=1 $ make sure spinit has this too; we can't overrule spinit!
    set ispice = 0
    let spiceidx = $SPICEIDX ; let ntasks=1; let ncpus=8;
    let nparams=0; let nresults=2;
    let ignore = 0
    let buf = 0
    let done = 0
    let ix = spiceidx
    compose arg values 2 2 ix 0 0.0
    compose status values ncpus spiceidx
    dowhile ix < ntasks
    TRAN 30u 30ms 0 30u
    let arg[3] = 0;
    meas tran arg[4] AVG @i1[current]
    let ignore=setresult(arg)
    let arg[3] = 1;
    meas tran arg[4] AVG @i2[current]
    let ignore=setresult(arg)
    let ix = ix + ncpus
    let arg[2] = ix
    write f:/2jsource_test_{$spiceidx}{.raw}
    set appendwrite
    end
    let done = setfinish(status)
    quit
    endc

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to mhx on Mon May 19 00:51:36 2025
    In article <fce9942b8d6e52702b330d5edcde5b4f@www.novabbs.com>,
    mhx <mhx@iae.nl> wrote:
    Mime-Version: 1.0
    User-Agent: Rocksolid Light
    Path: not-for-mail
    From: mhx@iae.nl (mhx)
    Newsgroups: comp.lang.forth
    Organization: novaBBS
    Injection-Info: i2pn2.org; logging-data="921598"; mail-complaints-to="usenet@i2pn2.org"; posting-account="J+nubxJRM7ncpF4l6KLO+OONWmFAYJHVJegfwQXJ8vc";
    Subject: Re: Back & Forth - 4tH I/O and You
    References: <nnd$306ecdcd$714b9ebb@8c19de68479dc08d> <b2a4690cc4cdcb9e39310166d37070ab2a16d8b2@i2pn2.org> <nnd$68843db9$0f3297b6@f356aed0e515fe8b> <nnd$0346461b$62171617@be8ddde8960df4cb>
    Content-Transfer-Encoding: 8bit
    X-Rslight-Site: $2y$10$OOQsNDELF5uNo3A3Uv7gJOwfOwKYrncFKKKX4OxnyyB9YDRoHEGxG >X-Rslight-Posting-User: 4e0dc1fdad1ead10b39e7eb5db19bf73d73e3ab3
    Date: Sun, 18 May 2025 19:10:34 +0000
    Message-Id: <fce9942b8d6e52702b330d5edcde5b4f@www.novabbs.com>
    Content-Type: text/plain; charset=utf-8; format=flowed >X-Spam-Checker-Version: SpamAssassin 4.0.0

    On Sun, 18 May 2025 18:55:27 +0000, albert@spenarnc.xs4all.nl wrote:

    In article <nnd$68843db9$0f3297b6@f356aed0e515fe8b>,

    The integration with the OS-es makes for useful applications.
    ~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: cat printhex.frt
    : doit 1 ARG[] EVALUATE HEX . ;
    ~/PROJECT/ciforths/ciforth/TOOLS/ALLOCATE: printhex 1024;echo
    400

    [lina -c printhex.frt]

    In iForth we can redirect to a string:

    : ngspice-POSTLUDE ( -- c-addr u )
    DRY-RUN ( using TASK-DATA setup by SP>NGSPICE )
    |head .paramdata LOCAL mem
    <$$ ." * Generated by iSPICE on " .TIME$ ." -- do not edit"
    CR
    CR ." .control"
    CR ." unset ltspice"
    CR ." unset dotstep"
    CR ." set numthreads=1
    CR ." set ispice = " #|params 0<> 1 AND .
    CR ." "
    ." let spiceidx = $SPICEIDX ; "
    ." let ntasks=" #|tasks ."#"
    ." let ncpus=" #|cpus ."#"
    ." let nparams=" #|params ."#"
    ." let nresults=" #|results ."#"
    #|params
    IF CR ." compose p values "
    #|tasks 0 ?DO CR ." + "
    #|params 0 ?DO mem DF@+ TO mem
    F.N2+_
    LOOP
    LOOP
    CR #|params 1 > IF ." reshape p[" #|tasks
    0DEC.R ." ][" #|params
    0DEC.R ." ]"
    ENDIF
    ENDIF
    CR ." let ignore = 0"
    CR ." let buf = 0"
    CR ." let done = 0"
    CR ." let ix = spiceidx"
    CR ." compose arg values " #|tasks #|results * .
    #|results 0DEC.R ." ix 0 0.0"
    CR ." compose status values ncpus spiceidx"

    CR ." dowhile ix < ntasks"
    #|params 0 ?DO CR #|params 1 > IF ." let buf = p[ix][" I
    0DEC.R ." ]"
    ELSE ." let buf = p[ix]"
    ENDIF
    CR ." alterparam " |head .pnames I CSTR[] .$
    ." = $&buf"
    LOOP
    #|params IF CR ." mc_source" ENDIF
    CR ." " $SIM @+ 1 /STRING TYPE
    #|results 0 ?DO CR ." let arg[3] = " I ."#"
    CR ." " I (meashead) TYPE
    ." arg[4] " I (measbody) TYPE
    CR ." let ignore=setresult(arg) "
    LOOP
    CR ." let ix = ix + ncpus"
    CR ." let arg[2] = ix"
    CR ." write " RAWDATA-NAME
    NO-EXTENSION
    S" _{$spiceidx}{.raw}"
    $+ TYPE
    #|tasks IF CR ." set appendwrite" ENDIF
    CR ." end"
    CR ." let done = setfinish(status)"
    CR ." quit"
    CR ." .endc"
    $$>
    SCRIPTFILE-NAME DUMP-TO-FILE
    CR ." Please manually add the following lines to `" cktfile .$ ." .sp`"
    CR
    CR ." .LIBRARY basic.lib basicstuff"
    CR ." .OPTION savecurrents"
    CR ." .INC " cktfile .$ ." .iscript"
    CR ; PRIVATE

    ( This mixes Forth with the SPICE shell script language )

    Result:

    * Generated by iSPICE on 23:19:11, December 9, 2024 -- do not edit

    control
    unset ltspice
    unset dotstep
    set numthreads=1 $ make sure spinit has this too; we can't overrule
    spinit!
    set ispice = 0
    let spiceidx = $SPICEIDX ; let ntasks=1; let ncpus=8;
    let nparams=0; let nresults=2;
    let ignore = 0
    let buf = 0
    let done = 0
    let ix = spiceidx
    compose arg values 2 2 ix 0 0.0
    compose status values ncpus spiceidx
    dowhile ix < ntasks
    TRAN 30u 30ms 0 30u
    let arg[3] = 0;
    meas tran arg[4] AVG @i1[current]
    let ignore=setresult(arg)
    let arg[3] = 1;
    meas tran arg[4] AVG @i2[current]
    let ignore=setresult(arg)
    let ix = ix + ncpus
    let arg[2] = ix
    write f:/2jsource_test_{$spiceidx}{.raw}
    set appendwrite
    end
    let done = setfinish(status)
    quit
    endc

    That doesn't convince I could do this myself.


    -marcel
    --
    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 mhx@21:1/5 to albert@spenarnc.xs4all.nl on Mon May 19 00:05:56 2025
    On Sun, 18 May 2025 22:51:36 +0000, albert@spenarnc.xs4all.nl wrote:

    In article <fce9942b8d6e52702b330d5edcde5b4f@www.novabbs.com>,
    mhx <mhx@iae.nl> wrote:
    [..]
    That doesn't convince I could do this myself.

    In Forth we can do everything ourselves.

    ngspice-postlude is a word from the netlist converter that translates
    a standard SPICE netlist to the iSPICE dialect. The control constructs
    tailor the script so that it coordinates parallel execution on a 44
    core HPZ840. Each core runs ngspice inside an iForth instance. After
    the simulations finish, each copy runs it own set of measurements
    on its own rawfile. The data is written to shared memory so that
    2.5-D plots can be generated.

    -marcel

    --- 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 May 19 11:55:32 2025
    In article <078ff0e4ae28526fe1c04fef6474326237ad928d@i2pn2.org>,
    dxf <dxforth@gmail.com> wrote:
    On 19/05/2025 2:49 am, Hans Bezemer wrote:
    ...
    Second - I've consulted my script, and nowhere do I use the word "redirection". I *do* state, however: "That means I have to *reuse* as many tokens as possible."

    What I mean is: why should I change my source to:

    D <# #S ROT SIGN #> fid WRITE-FILE

    When I can continue to use a perfectly capable: .

    In my case that would be: (.) WRITE

    where (.) is a kernel function and WRITE is a library function with >appropriate error handling:

    123 (.) write invalid handle error ... aborting

    Using that library I could define DISK as mentioned previously and do:

    DISK 123 . CONSOLE

    but as any exception msg would go to the file, redirection seems more
    trouble than worth.


    Huh? Redirection is not what you do in your program. It is outside
    in the OS. It requires only avoiding silly design choices in
    your Forth such as channeling all output through a one character
    at a time function as a revectorable EMIT.
    If you try to redirect via revectoring EMIT, you have already lost.

    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 albert@spenarnc.xs4all.nl@21:1/5 to the.beez.speaks@gmail.com on Mon May 19 12:26:58 2025
    In article <nnd$460c410a$64092378@222354ccf17f511d>,
    Hans Bezemer <the.beez.speaks@gmail.com> wrote:
    <SNIP>
    However, the FILE wordset isn't simple. It's an entirely new API you
    have to get familiar with. It might be easy to map when your underlying >implementation relies on C, it might be easy to map if you have your
    own, internal API that happens to fit nicely on that idea (or simply be
    very versatile) - but I doubt it's trivial to map if you have to build
    it up from the ground.

    It is old and actually very simple. Instead of having one channel
    (terminaL) you have channels given a small number as identification.
    I have replaced KEY with (ACCEPT) . Instead of streaming one key
    at a time you get a string, and you don't bother where it is stored.
    All hosted OS's do a better job of letting you correcting input
    instead of laboriously programming it into you Forth.
    One channel is special, aptly called "standard input".
    So you get
    : QUIT 1 STATE ! BEGIN (ACCEPT) SET-SRC INTERPRET AGAIN ;
    (ACCEPT) is getting an edited string via channel 0 (standard in).

    You can open channels to various files. A disk operating system
    with named files is enormous progress over blocks.
    OPEN-FILE READ/WRITE CLOSE-FILE is a compelling interface since
    half a century or longer, and there is no proposal in sight to
    replace it.

    An still then - since it has virtually no relationship with console I/O
    (like TYPE, ACCEPT, ., .", etc.) you have to learn like a completely >different language to use it. So IMHO it fails on the "simplicity" >qualification.
    So, no. A little ingenuity solves that to great benefit.


    I don't think it's too hard to map the Forth FILE word set on the C file
    API. I may do that later if I feel like it. Now - and here we curve back
    to my idea of the Forth philosophy - C is not Forth. An idea derived
    from the C philosophy is inherently un-Forth-like. Local variables are
    part of the stack frame concept - and hence inherently un-Forth-like.

    You are wrong to call FILE's c-like. It is operating system like.
    You can program your Unix in Haskell and the system calls are the
    same.
    Local Forth-variables are c-like, and are junk. Real program
    languages have functions, that have local variables and local functions
    that can have local variables and local functions etc.
    Compare the functions for numerical integrating function for
    "numerical recipees in C" against "numerical recipees in Pascal".

    The argument you can "bolt on" all kinds of C facilities is not an
    argument for bolting them on, it's merely an example of and a tribute to >Forth's extensibility.
    Agreed. Now bolt on a driver to access a modern disk drive.

    <SNIP>


    Hans Bezemer

    BTW, I have no idea what an inch is - let alone seven of them.
    Last time a heard it was a measure of distance.
    It is not related to the distance of the equator to the north pole,
    but inspired on the human thump.

    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 albert@spenarnc.xs4all.nl@21:1/5 to dxforth@gmail.com on Tue May 20 13:28:50 2025
    In article <a3c8d55396e1a48344a236bec05207ef64d14a72@i2pn2.org>,
    dxf <dxforth@gmail.com> wrote:
    On 20/05/2025 2:13 am, Hans Bezemer wrote:
    On 19-05-2025 15:22, dxf wrote:
    Those are console functions which traditionally went to serial ports and bear little
    resemblance to disk file I/O.  For implementer it's not simpler - it's a layer on top
    of DOS functions.  Even as an end-user I'm not sure I'd like it.  How does one handle
    seeks, read and writing to the same file etc?  The ANS functions were designed to
    handle random access.  Console functions were not.

    Originally, yeah - that was all. And then we enter the wondrous world of "feature requests". So a few more calls were added, like delete-file, reposition-file and the likes.

    If you read the documentation you will see that some I/O devices are out of bounds. So we devised tiny little macros for that:

    #define UDEV(a)    if(((a)<=COUT)||((a)>=MAXDEVS))throw(M4BADDEV)

    That's how we handle things around here.

    I think we both felt some simplification of file-handling at the application >programmer level was desirable. For me it's been quite a while since I've >used e.g. READ-FILE directly. The ubiquitous 'filecopy' application for me >would look like this:

    : OPENFILES ( -- )
    cr .ifile ." -> " .ofile
    r/o openin r/w makeout cr
    ;

    : (RUN) ( -- )
    openfiles
    begin pad 128 read dup while write repeat 2drop
    closefiles
    ;

    Or in presence of GET-FILE (sc --sc)

    ( sc1 sc2 --)
    : copy-file 2>R GET-FILE 2R> PUT-FILE ;


    I believe the 4tH manual illustrates something similar.

    I don't have to worry about overwrite checks, user interrupt, error messages >and so on as it's handled under the hood. Was it all necessary? Is it >'anti-Forth'? Folks can decide for themselves.


    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 albert@spenarnc.xs4all.nl@21:1/5 to the.beez.speaks@gmail.com on Thu May 22 12:52:11 2025
    In article <nnd$677b4eee$3815c1d3@f69c6d707a0f7f81>,
    Hans Bezemer <the.beez.speaks@gmail.com> wrote:
    On 20-05-2025 04:45, dxf wrote:
    I think we both felt some simplification of file-handling at the application >> programmer level was desirable. For me it's been quite a while since I've >> used e.g. READ-FILE directly. <SNIP>
    I believe the 4tH manual illustrates something similar.

    As I stated before, there were several requirements coming together in
    this design. First, the desire to minimize the number of tokens required
    for an I/O system. Second, to design an API which fitted (my idea of)
    Forth better. Third, one that made a transition from the previous 4tH
    I/O system as painless as possible.

    So - yes, you got that right: as simple and as intuitive possible. I
    must compliment you on your concise analysis - this is almost exactly as
    I tend to write 4tH: you open your files, put the handles on the stack,
    do your I/O and use those same handles to close the files. It's
    literally coded like that in the "CONVERT" template (See YT: >https://youtu.be/73fDmCh9Mio).

    I don't have to worry about overwrite checks, user interrupt, error messages >> and so on as it's handled under the hood. Was it all necessary? Is it
    'anti-Forth'? Folks can decide for themselves.

    In a way, yeah. Opening a files returns an error code - but the rest of
    the API - especially the output words, don't. The reason for that is
    I've rarely seen errors in that regard. If you can open a file
    successfully, you normally can write to it - at least, that's my
    experience. Also, closing files very rarely results in an error. That's
    why these parts of the API don't return error codes. Note - I'm not
    saying it can't happen. I'm just saying I've only seen it happen very
    rarely. So why bug the programmer with endlessly checking error codes?

    This is Pascal style, endlessly passing error codes down the command
    chain.
    GET-FILE ( sc -- sc) doesn't fail normally. It is sufficient to
    put a THROW after each XXX-FILE word. No error codes in sight.

    If you make a mistake you get
    S[ ] OK "poepie" GET-FILE
    ? ciforth ERROR # -2 : No such file or directory

    If you allocate 128 Gbyte for dynamic strings, you don't run out
    of memory, normally.
    Only if you forget to initialize the pool:

    S[ ] OK 10 ALLOCATE THROW
    10 ALLOCATE ? ciforth ERROR # 50 : NOT ENOUGH MEMORY FOR ALLOCATE

    Thank god for the THROW instead of DROP .


    That doesn't mean no error detection is performed. It is - but it THROWs
    an error when things go wrong. If you wanna catch it, fine. If not, fine
    too. The system will take care of matters anyway. As you state - it's up
    to the user to decide.

    Just my idea. But then you better be consistent and allow error
    codes everywhere. The burden to remember which words needs a throw
    and what not makes no sense.


    <SNIP>

    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)