• READ-LINE when u1=0

    From dxf@dxforth@gmail.com to comp.lang.forth on Sat Jul 26 00:58:08 2025
    From Newsgroup: comp.lang.forth

    Ambiguous condition? If not, what should be the result and what is it good for?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Fri Jul 25 15:06:41 2025
    From Newsgroup: comp.lang.forth

    dxf <dxforth@gmail.com> writes:
    Ambiguous condition? If not, what should be the result

    AFAICS u1=0 is not specified as ambiguous condition, and I don't see
    a reason that would make it ambiguous.

    The results depend on the state of the file.

    1) Either a non-zero ior, or
    2) ior=0, u2=0, and
    a) flag=false under the specified condition
    b) flag=true otherwise

    and what is it good for?

    If you ever meet programmers that call READ-LINE with u1=0, ask them.

    The last time I asked about a usage that appeared pointless to me (an
    empty DOES> clause), the author had no satisfying explanation.

    - 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 2025 CFP: http://www.euroforth.org/ef25/cfp.html
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sat Jul 26 11:50:33 2025
    From Newsgroup: comp.lang.forth

    On 26/07/2025 1:06 am, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    Ambiguous condition? If not, what should be the result

    AFAICS u1=0 is not specified as ambiguous condition, and I don't see
    a reason that would make it ambiguous.

    The results depend on the state of the file.

    1) Either a non-zero ior, or
    2) ior=0, u2=0, and
    a) flag=false under the specified condition
    b) flag=true otherwise

    and what is it good for?

    If you ever meet programmers that call READ-LINE with u1=0, ask them.

    The last time I asked about a usage that appeared pointless to me (an
    empty DOES> clause), the author had no satisfying explanation.

    If not ambiguous then the result should be exactly predictable.
    If the result differs but with no harmful effect then what would
    you call that?

    0 value fid

    : print cr rot 2 .r ." ->" swap 2 .r 3 .r ;

    : test
    s" foo.txt" r/w create-file throw to fid
    s" foobar" fid write-file throw
    fid close-file drop

    s" foo.txt" r/o open-file throw to fid
    page
    0 pad over fid read-line throw print
    10 pad over fid read-line throw print
    0 pad over fid read-line throw print
    1 pad over fid read-line throw print
    fid close-file drop cr
    ;

    test

    \\

    SwiftForth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 0
    1 -> 0 0

    VFX
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    Gforth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    NTF
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    Win32Forth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 0
    1 -> 0 0


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sat Jul 26 06:29:03 2025
    From Newsgroup: comp.lang.forth

    dxf <dxforth@gmail.com> writes:
    If the result differs but with no harmful effect then what would
    you call that?

    If the the behaviour of an implementation differs from what is
    specified, I call that a bug.

    0 value fid

    : print cr rot 2 .r ." ->" swap 2 .r 3 .r ;

    : test
    s" foo.txt" r/w create-file throw to fid
    s" foobar" fid write-file throw
    fid close-file drop

    s" foo.txt" r/o open-file throw to fid
    page
    0 pad over fid read-line throw print
    10 pad over fid read-line throw print
    0 pad over fid read-line throw print
    1 pad over fid read-line throw print
    fid close-file drop cr
    ;

    test

    \\

    SwiftForth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 0
    1 -> 0 0

    VFX
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    Gforth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    NTF
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    Win32Forth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 0
    1 -> 0 0

    The specification requires:

    |If the operation succeeded, flag is true and ior is zero.
    [...]
    |If the operation is initiated when the value returned by FILE-POSITION
    |is equal to the value returned by FILE-SIZE for the file identified by |fileid, flag is false, ior is zero, and u2 is zero.

    In the case of u1=0, both conditions can be true, and the
    specification is contradictory. VFX, Gforth, and NTF apparently give
    priority to the first statement, SwiftForth and Win32Forth to the
    second.

    The specification should not be contradictory. It should specify for
    this case whether flag should be true or false, or, if no consensus is
    reached, it should explicitly state that both results are acceptable.

    READ-LINE seems to be a particularly problematic word, with many
    discussions about its specification over the years. Maybe the quality
    of the specification is not up to the quality of the rest of the
    standard, but I believe that the root cause of the problem is that
    this word has to satisfy too many requirements:

    It should not ALLOCATE (because small Forth systems are not expected
    to provide ALLOCATE, so it was designed to work with a given buffer.
    But it should also be able to use it to read lines longer than this
    buffer.

    Does anyone programming for a system without ALLOCATE actually read
    and process longer lines with READ-LINE? Or do they just use
    READ-LINE with a certain buffer, and specify that the input must not
    have lines longer than the buffer?

    In the latter case it would have been better to have two words: A word
    for reading lines of up to u1 characters into a given buffer (mostly
    like READ-LINE, but with some provisions for reading extended lines
    simplified away (maybe resulting in an ior<>0). And a word that reads
    and ALLOCATEs an arbitrarily long line.

    Of course, that's water down the river. As it is, we should revise
    the specification of READ-LINE to address the ambiguities.

    - 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 2025 CFP: http://www.euroforth.org/ef25/cfp.html
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From minforth@minforth@gmx.net to comp.lang.forth on Sat Jul 26 09:43:26 2025
    From Newsgroup: comp.lang.forth

    Am 26.07.2025 um 08:29 schrieb Anton Ertl:
    dxf <dxforth@gmail.com> writes:
    If the result differs but with no harmful effect then what would
    you call that?

    If the the behaviour of an implementation differs from what is
    specified, I call that a bug.

    0 value fid

    : print cr rot 2 .r ." ->" swap 2 .r 3 .r ;

    : test
    s" foo.txt" r/w create-file throw to fid
    s" foobar" fid write-file throw
    fid close-file drop

    s" foo.txt" r/o open-file throw to fid
    page
    0 pad over fid read-line throw print
    10 pad over fid read-line throw print
    0 pad over fid read-line throw print
    1 pad over fid read-line throw print
    fid close-file drop cr
    ;

    test

    \\

    SwiftForth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 0
    1 -> 0 0

    VFX
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    Gforth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    NTF
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    Win32Forth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 0
    1 -> 0 0

    The specification requires:

    |If the operation succeeded, flag is true and ior is zero.
    [...]
    |If the operation is initiated when the value returned by FILE-POSITION
    |is equal to the value returned by FILE-SIZE for the file identified by |fileid, flag is false, ior is zero, and u2 is zero.

    In the case of u1=0, both conditions can be true, and the
    specification is contradictory. VFX, Gforth, and NTF apparently give priority to the first statement, SwiftForth and Win32Forth to the
    second.

    The specification should not be contradictory. It should specify for
    this case whether flag should be true or false, or, if no consensus is reached, it should explicitly state that both results are acceptable.

    Simply specify to perform the EOF check before reading.
    if EOF true, exit.
    Afterwards, u2=0 indicates an empty line.
    Contradiction solved.


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sat Jul 26 19:09:06 2025
    From Newsgroup: comp.lang.forth

    On 26/07/2025 4:29 pm, Anton Ertl wrote:
    ...
    The specification requires:

    |If the operation succeeded, flag is true and ior is zero.
    [...]
    |If the operation is initiated when the value returned by FILE-POSITION
    |is equal to the value returned by FILE-SIZE for the file identified by |fileid, flag is false, ior is zero, and u2 is zero.

    In the case of u1=0, both conditions can be true, and the
    specification is contradictory. VFX, Gforth, and NTF apparently give priority to the first statement, SwiftForth and Win32Forth to the
    second.

    The specification should not be contradictory. It should specify for
    this case whether flag should be true or false, or, if no consensus is reached, it should explicitly state that both results are acceptable.

    READ-LINE seems to be a particularly problematic word, with many
    discussions about its specification over the years. Maybe the quality
    of the specification is not up to the quality of the rest of the
    standard, but I believe that the root cause of the problem is that
    this word has to satisfy too many requirements:

    It should not ALLOCATE (because small Forth systems are not expected
    to provide ALLOCATE, so it was designed to work with a given buffer.
    But it should also be able to use it to read lines longer than this
    buffer.

    Does anyone programming for a system without ALLOCATE actually read
    and process longer lines with READ-LINE? Or do they just use
    READ-LINE with a certain buffer, and specify that the input must not
    have lines longer than the buffer?

    In the latter case it would have been better to have two words: A word
    for reading lines of up to u1 characters into a given buffer (mostly
    like READ-LINE, but with some provisions for reading extended lines simplified away (maybe resulting in an ior<>0). And a word that reads
    and ALLOCATEs an arbitrarily long line.

    READ-LINE is a compromise for small systems. More efficient would be
    a buffered system which reads large chunks of the file and parses out
    a line (not unlike PARSE).

    Of course, that's water down the river. As it is, we should revise
    the specification of READ-LINE to address the ambiguities.

    Revision in the absence of practice may do more harm than good. I've
    dealt with several implementations of READ-LINE. All give subtly
    different results. ANS seems pedantic on EOF returning both u2=0 and
    flag=0. The TC reiterated this in response to an RFI. But why? Who
    checks u2 for EOF?

    Omitted from the ANS spec is any mention of EOF characters for systems
    that employ it e.g. CP/M and MS-DOS. And if READ-LINE encounters such
    there should be a way to report it. I've had to write custom routines
    to do just that.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From anton@anton@mips.complang.tuwien.ac.at (Anton Ertl) to comp.lang.forth on Sat Jul 26 10:41:26 2025
    From Newsgroup: comp.lang.forth

    dxf <dxforth@gmail.com> writes:
    ANS seems pedantic on EOF returning both u2=0 and
    flag=0. The TC reiterated this in response to an RFI. But why? Who
    checks u2 for EOF?

    Reporting EOF only when the input has been exhausted before READ-LINE
    means that there is no special handling needed for the last line
    (assuming you want to process it the same way as the other lines).

    Omitted from the ANS spec is any mention of EOF characters for systems
    that employ it e.g. CP/M and MS-DOS.

    That's in line with the way that the standard deals with different
    newline representations: It does not mention them in the normative
    part, exactly because they are different and therefore problematic to standardize.

    For EOF it's the same. There's a way to report EOF no matter how EOF
    is represented in the OS, but no standard way to find out anything
    about the representation.

    And if READ-LINE encounters such
    there should be a way to report it.

    If you think that the existing EOF handling is insufficient, make a
    proposal. And make a good case why you consider the existing EOF
    handling insufficient. It has been sufficient for me up to now.

    - 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 2025 CFP: http://www.euroforth.org/ef25/cfp.html
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Hans Bezemer@the.beez.speaks@gmail.com to comp.lang.forth on Sat Jul 26 15:46:32 2025
    From Newsgroup: comp.lang.forth

    On 26-07-2025 03:50, dxf wrote:

    4tH
    0 -> 0 1
    10 -> 6 1
    0 -> 0 1
    1 -> 0 0

    Note "TRUE" in 4tH is simply "1", not "-1". Obviously 4tH prioritizes
    the first statement of the specification as well.

    Changes to the program:
    - Inclusion of the ANS FILE wordset;
    - : page 27 emit ." [2J" ;

    Hans Bezemer


    0 value fid

    : print cr rot 2 .r ." ->" swap 2 .r 3 .r ;

    : test
    s" foo.txt" r/w create-file throw to fid
    s" foobar" fid write-file throw
    fid close-file drop

    s" foo.txt" r/o open-file throw to fid
    page
    0 pad over fid read-line throw print
    10 pad over fid read-line throw print
    0 pad over fid read-line throw print
    1 pad over fid read-line throw print
    fid close-file drop cr
    ;

    test

    \\

    SwiftForth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 0
    1 -> 0 0

    VFX
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    Gforth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    NTF
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 -1
    1 -> 0 0

    Win32Forth
    0 -> 0 -1
    10 -> 6 -1
    0 -> 0 0
    1 -> 0 0



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sun Jul 27 00:30:18 2025
    From Newsgroup: comp.lang.forth

    On 26/07/2025 8:41 pm, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    ANS seems pedantic on EOF returning both u2=0 and
    flag=0. The TC reiterated this in response to an RFI. But why? Who
    checks u2 for EOF?

    Reporting EOF only when the input has been exhausted before READ-LINE
    means that there is no special handling needed for the last line
    (assuming you want to process it the same way as the other lines).

    EOF is reported by flag = false. There was no need to return u2 = 0.
    There's no function for it AFAIK.

    Omitted from the ANS spec is any mention of EOF characters for systems
    that employ it e.g. CP/M and MS-DOS.

    That's in line with the way that the standard deals with different
    newline representations: It does not mention them in the normative
    part, exactly because they are different and therefore problematic to standardize.

    For EOF it's the same. There's a way to report EOF no matter how EOF
    is represented in the OS, but no standard way to find out anything
    about the representation.

    That's fine if the argument is users don't need to know.

    And if READ-LINE encounters such
    there should be a way to report it.

    If you think that the existing EOF handling is insufficient, make a
    proposal. And make a good case why you consider the existing EOF
    handling insufficient. It has been sufficient for me up to now.

    I've resolved it by adding a variable CPMEOF and having READ-LINE set
    it when it finds one.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From dxf@dxforth@gmail.com to comp.lang.forth on Sun Jul 27 11:13:53 2025
    From Newsgroup: comp.lang.forth

    On 26/07/2025 11:46 pm, Hans Bezemer wrote:

    4tH
     0 -> 0  1
    10 -> 6  1
     0 -> 0  1
     1 -> 0  0

    In my case it's ...

    0 -> 0 0
    10 -> 6 1
    0 -> 0 0
    1 -> 0 0

    for two implementations and

    0 -> 0 1
    10 -> 6 1
    0 -> 0 0
    1 -> 0 0

    for a third.

    The reason it's a '1' is because my implementations return a ternary
    that indicates EOL received, not received, or EOF.

    Am I worried about the u1 = 0 result above? Not until someone can
    show u1 = 0 can happen or is meaningful. I don't want to add code
    for something I'll never use. Was the ternary feature useful?
    I'm still in the process of evaluating that. OTOH it definitely
    scratched an itch :)

    --- Synchronet 3.21a-Linux NewsLink 1.2