• Re: Numeric string output - conspicuously absent in Forth

    From Paul Rubin@21:1/5 to dxf on Mon Apr 29 09:22:54 2024
    dxf <dxforth@gmail.com> writes:
    For reasons one can only speculate Forth Standards have by and large ignored numeric string output.

    There is the <# ... #> machinery. Does that count?

    --- 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 Mon Apr 29 19:54:46 2024
    In article <87sez4m941.fsf@nightsong.com>,
    Paul Rubin <no.email@nospam.invalid> wrote:
    dxf <dxforth@gmail.com> writes:
    For reasons one can only speculate Forth Standards have by and large ignored >> numeric string output.

    There is the <# ... #> machinery. Does that count?

    Definitely.
    : (UD.) <# #S #> ;

    Actually this is a brilliant design. I was on the trail of something
    similar to floating point, but I lost it.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerry Jackson@21:1/5 to Paul Rubin on Mon Apr 29 20:47:10 2024
    On 29/04/2024 17:22, Paul Rubin wrote:
    dxf <dxforth@gmail.com> writes:
    For reasons one can only speculate Forth Standards have by and large ignored >> numeric string output.

    There is the <# ... #> machinery. Does that count?

    It's a nice idea but the restrictions around it and the specified implementation render it unsuitable for building upon it if you want to
    write portable software. Faults with it are:

    - the pictured output buffer (POB) may be transient, can be corrupted by
    the system e.g. being moved or overwritten
    - POB contents are built up from right to left, making concatenation
    user hostile
    - only one buffer available to the programmer
    - cannot set POB size
    - buffers not nestable
    - POB contents can only be accessed by #> which terminates things
    - system words such as .S may use the POB, thus hindering debugging
    - the system need not check the POB for overflow

    Some of these can be improved in a Forth system but software using the improvements may not be portable between systems.

    I've written my own version of <# etc, with the '#' replaced by '~',
    that does not have the above problems. It has:

    new-buffer ( "name" xt ca u ~buf-size -- ) create a new format buffer
    <~ ( -- ) open a format buffer
    ( -- ca u ) get contents of the current buffer, can be added to (has
    synonym ~@
    <~ ( -- ca u ) get contents of buffer, close it and open another
    ~hold ( ch -- ) with synonym ~c+
    ~holds ( ca u -- ) with synonym ~+
    ~fill ( n ch -- )

    ~w ( n -- ) set a field width
    ~r ( +n -- ) set field width and right justify next conversion
    ~l ( -n -- ) set field width and left justify next conversion
    ~uc ( -- ) set upper case
    ~lc ( -- ) set lower case
    ~d ( d -- ) convert signed double integer
    ~i ( n -- ) convert signed integer
    ~ud ( ud ) convert unsigned double integer
    ~ui ( u -- ) convert unsigned integer
    ~s ( ca u -- ) hold string subject to any justification etc
    ~c ( ch -- ) hold character subject to any justification etc

    I've used these as primitives for integer sprintf implementations
    intending (when I get time and interest) to extend it to a floating
    point sprintf

    --
    Gerry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From mhx@21:1/5 to albert@spenarnc.xs4all.nl on Mon Apr 29 19:40:10 2024
    albert@spenarnc.xs4all.nl wrote:
    [..]
    Definitely.
    : (UD.) <# #S #> ;

    Actually this is a brilliant design. I was on the trail of something
    similar to floating point, but I lost it.

    Can you look again? I have at least 40 different words to format
    floats and for some reason each application needs yet another one.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Gerry Jackson on Mon Apr 29 13:54:26 2024
    Gerry Jackson <do-not-use@swldwa.uk> writes:
    - the pictured output buffer (POB) may be transient, can be corrupted by
    the system e.g. being moved or overwritten

    Yeah that's a typical Forthy thing though. So after calling #> you have
    to copy the output away before doing anything else that could mess with
    the POB..

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to do-not-use@swldwa.uk on Tue Apr 30 10:38:57 2024
    In article <v0otfs$1t6r0$1@dont-email.me>,
    Gerry Jackson <do-not-use@swldwa.uk> wrote:
    On 29/04/2024 17:22, Paul Rubin wrote:
    dxf <dxforth@gmail.com> writes:
    For reasons one can only speculate Forth Standards have by and large ignored
    numeric string output.

    There is the <# ... #> machinery. Does that count?

    It's a nice idea but the restrictions around it and the specified >implementation render it unsuitable for building upon it if you want to
    write portable software. Faults with it are:

    - the pictured output buffer (POB) may be transient, can be corrupted by
    the system e.g. being moved or overwritten

    This is not a fault with <#. You can easily make it work with
    ALLOCATE.

    - POB contents are built up from right to left, making concatenation
    user hostile
    Make that a "minor inconvenience".

    - only one buffer available to the programmer
    See ALLOCATE.
    - cannot set POB size
    See ALlOCATE.
    - buffers not nestable
    See ALLOCATE.
    - POB contents can only be accessed by #> which terminates things
    ???
    - system words such as .S may use the POB, thus hindering debugging
    See nesting
    - the system need not check the POB for overflow
    See ALLOCATE

    Some of these can be improved in a Forth system but software using the >improvements may not be portable between systems.
    They need not be. Only the spec's have to be updated.
    It has been debunked numerous times, that adhering to a
    common specification doesn't require a portable implementation.

    I've written my own version of <# etc, with the '#' replaced by '~',
    that does not have the above problems. It has:

    new-buffer ( "name" xt ca u ~buf-size -- ) create a new format buffer
    <~ ( -- ) open a format buffer
    ( -- ca u ) get contents of the current buffer, can be added to (has
    synonym ~@
    <~ ( -- ca u ) get contents of buffer, close it and open another
    ~hold ( ch -- ) with synonym ~c+
    ~holds ( ca u -- ) with synonym ~+
    ~fill ( n ch -- )

    ~w ( n -- ) set a field width
    ~r ( +n -- ) set field width and right justify next conversion
    ~l ( -n -- ) set field width and left justify next conversion
    ~uc ( -- ) set upper case
    ~lc ( -- ) set lower case
    ~d ( d -- ) convert signed double integer
    ~i ( n -- ) convert signed integer
    ~ud ( ud ) convert unsigned double integer
    ~ui ( u -- ) convert unsigned integer
    ~s ( ca u -- ) hold string subject to any justification etc
    ~c ( ch -- ) hold character subject to any justification etc

    I've used these as primitives for integer sprintf implementations
    intending (when I get time and interest) to extend it to a floating
    point sprintf

    You have yet to convince that these cannot be upwards compatible.

    If you want printf compatibility, why not just import a c-library?

    --
    Gerry

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to mhx on Tue Apr 30 12:07:11 2024
    In article <230ab6567c871281dcdef56439d0ad81@www.novabbs.com>,
    mhx <mhx@iae.nl> wrote:
    dxf wrote:

    On 30/04/2024 2:22 am, Paul Rubin wrote:
    dxf <dxforth@gmail.com> writes:
    For reasons one can only speculate Forth Standards have by and large ignored
    numeric string output.

    There is the <# ... #> machinery. Does that count?

    Only as a missed opportunity. There's no cheaper way of adding string
    functions than the following and it was amiss of the Standard not to
    offer it.

    \ Print string right-justified in a field of width chars
    : S.R ( adr len width -- ) over - spaces type ; ( eForth)

    \ Numeric string output
    : (D.) ( d -- adr len ) tuck dabs <# #s rot sign #> ;
    : (U.) ( u -- adr len ) 0 (d.) ;
    : (.) ( n -- adr len ) s>d (d.) ;

    \ Forth-79/83/94
    : D. ( d -- ) (d.) type space ;
    : U. ( u -- ) 0 d. ;
    : . ( n -- ) s>d d. ;
    : D.R ( d w -- ) >r (d.) r> s.r ;
    : U.R ( u w -- ) 0 swap d.r ;
    : .R ( n w -- ) >r s>d r> d.r ;

    The only words that are necessary to define these on your own are
    <# # #> DABS and SIGN. There is a reason to define these in the
    Standard: the hardware details of a number need to be known if
    you want to do it yourself in a portable way. The other reason
    is probably that double precision is needed to implement this,
    but the Double-Number word set is optional.

    So far for speculation.

    I guess that is right.

    Moore hated double precision.
    (I kind of like them, it is convenient for euler project problems.)
    E.g.
    -1. <# #S #> TYPE
    340282366920938463463374607431768211455

    It can be argued that for a simple kernel doubles are not needed.
    I left it out for yourforth, 1) modifying #-words to %-words.
    yourforth is slightly over 200 words, including my hobby horses, like
    CFA >DFA .. and $! $@ .. and CLS .

    1) An ISO alternative for jonesforth.

    -marcel

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From mhx@21:1/5 to dxf on Tue Apr 30 09:40:23 2024
    dxf wrote:

    On 30/04/2024 2:22 am, Paul Rubin wrote:
    dxf <dxforth@gmail.com> writes:
    For reasons one can only speculate Forth Standards have by and large ignored
    numeric string output.

    There is the <# ... #> machinery. Does that count?

    Only as a missed opportunity. There's no cheaper way of adding string functions than the following and it was amiss of the Standard not to
    offer it.

    \ Print string right-justified in a field of width chars
    : S.R ( adr len width -- ) over - spaces type ; ( eForth)

    \ Numeric string output
    : (D.) ( d -- adr len ) tuck dabs <# #s rot sign #> ;
    : (U.) ( u -- adr len ) 0 (d.) ;
    : (.) ( n -- adr len ) s>d (d.) ;

    \ Forth-79/83/94
    : D. ( d -- ) (d.) type space ;
    : U. ( u -- ) 0 d. ;
    : . ( n -- ) s>d d. ;
    : D.R ( d w -- ) >r (d.) r> s.r ;
    : U.R ( u w -- ) 0 swap d.r ;
    : .R ( n w -- ) >r s>d r> d.r ;

    The only words that are necessary to define these on your own are
    <# # #> DABS and SIGN. There is a reason to define these in the
    Standard: the hardware details of a number need to be known if
    you want to do it yourself in a portable way. The other reason
    is probably that double precision is needed to implement this,
    but the Double-Number word set is optional.

    So far for speculation.

    -marcel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From sjack@21:1/5 to All on Tue Apr 30 10:16:41 2024
    Frog code (Fig not standard):
    [#] pno.d -- Pictured Numeric Output exploits
    --.
    [r] #>S ( -- s )
    -- Pictured numeric returning (counted) string
    : #>S #> HOLD 1- ;

    -- String, S , in Frog code is single address pointing to byte
    -- counted string.
    -- <# ... #> ( a u ) TYPE
    -- <# ... #>S ( a ) TELL
    --.
    [r] S<# ( n -- d ) Immediate
    -- Macro for Single-number pictured numeric
    : S<# "ZERO <#" EVAL ; IMM

    -- Frog leaves '<#' to work with double number and
    -- uses macro 'S<#' as indicament of working with single number.
    -- 666. <# ... #> TYPE
    -- 666 S<# ... #>S TELL
    --.
    [r] PNO buffer
    The PNO can be any buffer by pointing HLD to the buffer's end and
    using an alternative to '>#' :

    mpad 256 + tmp!
    tmp@ hld !
    "[m" holds
    27 hold
    "world" holds
    46 hold
    "[0;33;40mhello" holds
    27 hold
    i. hld @ tmp@ om type --> hello.world ( yellow on black )
    --.
    [r] Source input buffer
    -- Source input buffer is ring buffer for strings
    : <#IB 256 SIB + DUP HLD ! TMP! ;
    : IB#> 2DROP HLD @ TMP@ OM ;
    : SIB#>S HLD @ TMP@ OM HOLD 1- ;

    -- sib ( u -- u a )
    : <#IB 256 SIB + DUP HLD ! TMP! ;
    : IB#> 2DROP HLD @ TMP@ OM ;
    : SIB#>S HLD @ TMP @ OM hold 1- ;

    <#ib "[m" holds 27 hold SIB#>S
    <#ib "[0;33;40m" holds 27 hold SIB#>S
    2dup
    1 text Hello World!
    i. tell pad tell tell --> Hello World! ( yellow on black)
    1 text How are you?
    i. tell pad tell tell --> How are you? ( yellow on black)
    --.
    [s]
    OM ( a1 a2 -- a1 u ) over -
    tell ( a ) count type
    sib ( u -- u a ) \ a is buffer from ring of size u+2; last chr is null
    \ used for counted string, null terminated string or
    \ both.
    i. \ print ' --> '
    --.
    [#] //

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerry Jackson@21:1/5 to albert@spenarnc.xs4all.nl on Tue Apr 30 20:02:28 2024
    On 30/04/2024 09:38, albert@spenarnc.xs4all.nl wrote:
    In article <v0otfs$1t6r0$1@dont-email.me>,
    Gerry Jackson <do-not-use@swldwa.uk> wrote:
    On 29/04/2024 17:22, Paul Rubin wrote:
    dxf <dxforth@gmail.com> writes:
    For reasons one can only speculate Forth Standards have by and large ignored
    numeric string output.

    There is the <# ... #> machinery. Does that count?

    It's a nice idea but the restrictions around it and the specified
    implementation render it unsuitable for building upon it if you want to
    write portable software. Faults with it are:

    - the pictured output buffer (POB) may be transient, can be corrupted by
    the system e.g. being moved or overwritten

    This is not a fault with <#. You can easily make it work with
    ALLOCATE.

    So given a Forth system suppose I allocate a buffer for use with the <#
    family - how do I make the existing <# definitions use that buffer
    without re-defining <# etc?


    - POB contents are built up from right to left, making concatenation
    user hostile
    Make that a "minor inconvenience".

    I don't think so

    - only one buffer available to the programmer
    See ALLOCATE.

    So given a Forth system I allocate an additional buffer for use with the
    <# family - how do I make the existing <# definitions use that buffer
    without re-defining <# etc?

    - cannot set POB size
    See ALlOCATE.

    So given a Forth system I .... how do I ...

    - buffers not nestable
    See ALLOCATE.

    - POB contents can only be accessed by #> which terminates things

    ???

    How do you see what the buffer contains without using #> when you don't
    even know the starting address?

    - system words such as .S may use the POB, thus hindering debugging
    See nesting

    If a Forth system uses the POB for implementing .S how do I stop it
    doing so without redefining .S (easy to do I admit).

    - the system need not check the POB for overflow
    See ALLOCATE


    So given a Forth system I .... how do I ...


    Some of these can be improved in a Forth system but software using the
    improvements may not be portable between systems.

    Did you not read this bit before your knee-jerk reaction above? No I
    thought not

    They need not be. Only the spec's have to be updated.

    Yeah sure - listen to the howls of outrage when changes to the ANS
    standard are suggested particularly when they refer to things present
    from the original implementations of Forth.

    It has been debunked numerous times, that adhering to a
    common specification doesn't require a portable implementation.

    What has a portable implementation got to do with it, my comments were
    about the using an existing Forth system that implements the <# family
    doing nasty things that the standard permits such as moving the buffer
    without you knowing.


    I've written my own version of <# etc, with the '#' replaced by '~',
    that does not have the above problems. It has:

    new-buffer ( "name" xt ca u ~buf-size -- ) create a new format buffer
    <~ ( -- ) open a format buffer
    ( -- ca u ) get contents of the current buffer, can be added to (has
    synonym ~@
    <~ ( -- ca u ) get contents of buffer, close it and open another
    ~hold ( ch -- ) with synonym ~c+
    ~holds ( ca u -- ) with synonym ~+
    ~fill ( n ch -- )

    ~w ( n -- ) set a field width
    ~r ( +n -- ) set field width and right justify next conversion
    ~l ( -n -- ) set field width and left justify next conversion
    ~uc ( -- ) set upper case
    ~lc ( -- ) set lower case
    ~d ( d -- ) convert signed double integer
    ~i ( n -- ) convert signed integer
    ~ud ( ud ) convert unsigned double integer
    ~ui ( u -- ) convert unsigned integer
    ~s ( ca u -- ) hold string subject to any justification etc
    ~c ( ch -- ) hold character subject to any justification etc

    I've used these as primitives for integer sprintf implementations
    intending (when I get time and interest) to extend it to a floating
    point sprintf

    You have yet to convince that these cannot be upwards compatible.

    Upwards compatible with what? I wasn't intending them to be compatible
    with anything.


    If you want printf compatibility, why not just import a c-library?


    Where's the fun in that?

    --
    Gerry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerry Jackson@21:1/5 to Paul Rubin on Tue Apr 30 20:09:34 2024
    On 29/04/2024 21:54, Paul Rubin wrote:
    Gerry Jackson <do-not-use@swldwa.uk> writes:
    - the pictured output buffer (POB) may be transient, can be corrupted by
    the system e.g. being moved or overwritten

    Yeah that's a typical Forthy thing though. So after calling #> you have
    to copy the output away before doing anything else that could mess with
    the POB..

    Yes I know, but that shouldn't be necessary. I guess it's a hangover
    from the time 40 years ago when memory was a scarce and expensive
    commodity. Things like this should be weeded out of the standard.

    --
    Gerry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Tue Apr 30 20:37:50 2024
    dxf <dxforth@gmail.com> writes:
    Moore hated double precision.
    From his ANS exit speech?

    Yeah I'm puzzled too. I remember hearing someplace that m*/ was one of
    his prouder creations. It requires a triple precision intermediate
    product, so it is hard to implement in C.
    c

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to dxforth@gmail.com on Wed May 1 10:54:28 2024
    In article <6631b66c$1@news.ausics.net>, dxf <dxforth@gmail.com> wrote:
    On 30/04/2024 8:07 pm, albert@spenarnc.xs4all.nl wrote:
    ...
    Moore hated double precision.

    From his ANS exit speech? Perhaps he was looking for things to disagree >with. Whatever precipitated his leaving, it marked the end of his >involvement with Forth standards. I imagine it was a weight off his >shoulders. It was for me when I left.

    (I kind of like them, it is convenient for euler project problems.)
    E.g.
    -1. <# #S #> TYPE
    340282366920938463463374607431768211455

    It can be argued that for a simple kernel doubles are not needed.
    I left it out for yourforth, 1) modifying #-words to %-words.
    yourforth is slightly over 200 words, including my hobby horses, like
    CFA >DFA .. and $! $@ .. and CLS .

    1) An ISO alternative for jonesforth.

    It's hard to ignore mixed math especially when your processor supports it.

    It is certainly an advantage if you want to build multiple precision
    words. Certain implementations become cleaner, e.g. fixed point.

    It gives Forth an advantage over languages such as C .
    True, but not for many people, in yourforth is it out of place

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to dxforth@gmail.com on Wed May 1 11:25:49 2024
    In article <66319f99$1@news.ausics.net>, dxf <dxforth@gmail.com> wrote:
    On 1/05/2024 5:09 am, Gerry Jackson wrote:
    On 29/04/2024 21:54, Paul Rubin wrote:
    Gerry Jackson <do-not-use@swldwa.uk> writes:
    - the pictured output buffer (POB) may be transient, can be corrupted by >>>>    the system e.g. being  moved or overwritten

    Yeah that's a typical Forthy thing though.  So after calling #> you have >>> to copy the output away before doing anything else that could mess with
    the POB..

    Yes I know, but that shouldn't be necessary. I guess it's a hangover from the time 40 years ago when memory was a scarce and expensive commodity. Things like this should be weeded out of the standard.

    How is efficient use of a resource 'a hangover'? I've no particular allegiance
    to Standard Forth and will happily argue against things that were never properly
    considered e.g. the topic of this thread. Multiple HOLD buffers is like multiple
    S" buffers. For some folks one is never enough.

    Multiple buffers is a cludge, more so than a single buffer.
    The preferred enhancement is using ALLOCATE, enhanced with a string-save mechanism. ( $!a $@a )
    ALLOCATE packets with a SIZE (Aguilar's invention?) are especially nice.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gerry Jackson@21:1/5 to dxf on Wed May 1 11:05:32 2024
    On 01/05/2024 02:49, dxf wrote:
    On 1/05/2024 5:09 am, Gerry Jackson wrote:
    On 29/04/2024 21:54, Paul Rubin wrote:
    Gerry Jackson <do-not-use@swldwa.uk> writes:
    - the pictured output buffer (POB) may be transient, can be corrupted by >>>>    the system e.g. being  moved or overwritten

    Yeah that's a typical Forthy thing though.  So after calling #> you have >>> to copy the output away before doing anything else that could mess with
    the POB..

    Yes I know, but that shouldn't be necessary. I guess it's a hangover from the time 40 years ago when memory was a scarce and expensive commodity. Things like this should be weeded out of the standard.

    How is efficient use of a resource 'a hangover'?

    Perhaps a better term would have been 'a consequence of'. Calling
    sharing of memory between different buffers an 'efficient use of a
    resource' is making a virtue of necessity 40 years ago. It isn't needed
    these days. Anyway copying a string to avoid corruption of data is
    hardly efficient.

    I've no particular allegiance
    to Standard Forth and will happily argue against things that were never properly
    considered e.g. the topic of this thread. Multiple HOLD buffers is like multiple
    S" buffers. For some folks one is never enough.


    Like Block buffers you mean where, IIRC, more than 1 was the norm.

    --
    Gerry

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to do-not-use@swldwa.uk on Wed May 1 12:40:19 2024
    In article <v0rf84$2kkku$1@dont-email.me>,
    Gerry Jackson <do-not-use@swldwa.uk> wrote:
    <SNIP>
    What has a portable implementation got to do with it, my comments were
    about the using an existing Forth system that implements the <# family
    doing nasty things that the standard permits such as moving the buffer >without you knowing.

    That is the problem. I talk about modifying a Forth system.

    *** #> ***
    Description: Terminates numeric output conversion by dropping 'd',
    leaving the formatted string 'sc' .

    There is no reason, to not add:
    In a portable program you must assume that is the same
    buffer and can be overwritten by a subsequent use of <# # #>.
    In gerryforth however this 'sc' is permanent until it is
    garbage collected.
    [The negative implication that a standard system must overwrite
    this buffer is not correct.]

    Next step is that this is generally expected from a mature system and
    that in the documentation requirements it is to be stated that this is
    a static buffer or not.

    <SNIP>


    If you want printf compatibility, why not just import a c-library?


    Where's the fun in that?

    I had more fun in implementing the .FORMAT screen that does what
    c does, simpler and more flexible. Isn't that what Forth is all
    about?
    (It has a wordlist FORMAT-WID where you can add new formatting words,
    that were previously missing.)
    I can't resist the temptation to quote it here.
    (It builds on the tiny string abstraction $! $@ $/ )

    --------------------------8<-------------------------------
    ( FORMAT FORMAT&EVAL .FORMAT ) \ AH&CH C2feb15
    DATA CRS$ 4096 ALLOT \ ":2" WANTED
    NAMESPACE FORMAT-WID FORMAT-WID DEFINITIONS
    : c CRS$ $C+ ; : n ^J c ; : r ^M c ; \ Add single char's
    : d S>D 0 (D.R) CRS$ $+! ; \ Add INT as a string.
    : s CRS$ $+! ; \ Add a STRING as such.
    PREVIOUS DEFINITIONS
    \ Format the first part of STRING, up till %, leave REST.
    : _plain &% $/ CRS$ $+! ;
    \ Format X with first word of STRING, up till BL, leave REST.
    : _format BL $/ 2SWAP >R >R 'FORMAT-WID >WID (FIND) NIP NIP
    DUP 0= 51 ?ERROR EXECUTE R> R> ;
    \ Format X1 .. Xn using the format STRING.
    : FORMAT 0 CRS$ ! BEGIN DUP WHILE _plain DUP IF _format THEN
    REPEAT 2DROP CRS$ $@ ;
    : FORMAT&EVAL FORMAT EVALUATE ; : .FORMAT FORMAT TYPE ; --------------------------8<-------------------------------

    Now the class building screen can do things as
    BLD$ $@ NAME$ $@ ": BUILD-%s HERE >R %s R> ;" FORMAT&EVAL
    generating a definition for class POINT
    : BUILD-POINT HERE >R , , R> ;

    Gerry


    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to mhx on Wed May 1 17:12:02 2024
    mhx@iae.nl (mhx) writes:
    albert@spenarnc.xs4all.nl wrote:
    [..]
    Definitely.
    : (UD.) <# #S #> ;

    Actually this is a brilliant design. I was on the trail of something
    similar to floating point, but I lost it.

    Can you look again? I have at least 40 different words to format
    floats and for some reason each application needs yet another one.

    When I looked into FP formatting, I also wanted to do something like
    the # stuff, but did not find a way to extend it to FP. What I did
    instead is F.RDP (see <https://gforth.org/manual/Floating_002dpoint-output.html>), F>STR-RDP
    and F>BUF-RDP. Which of your 40 words is not covered by that? Why
    not?

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Wed May 1 17:57:31 2024
    dxf <dxforth@gmail.com> writes:
    So how have serious forth implementations handled the Standard's lack of >numeric string output functions? Many went ahead and provided (D.) (.)
    (F.) etc.

    Gforth does not, and does not have factors that correspond to (D.) or
    (.), and any such factors, if they existed, would put the onus on the
    user to release the memory for the string with #>>.

    The other approach seen is redirection which involves taking the
    existing standard functions D. . F. etc and sending the output to a
    buffer instead of the console.

    Yes, that's >STRING-EXECUTE in Gforth.

    String output allows transformation - adding thousands separators
    from (D.)

    Please demonstrate that that's less effort than using #, HOLD etc. for
    that purpose.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to mhx on Wed May 1 17:48:46 2024
    mhx@iae.nl (mhx) writes:
    The only words that are necessary to define these on your own are
    <# # #> DABS and SIGN. There is a reason to define these in the
    Standard: the hardware details of a number need to be known if
    you want to do it yourself in a portable way.

    All these words can be written with other standard words, in
    particular UM/MOD, DNEGATE, D0< (some of which are in the double
    wordset, however, but so is DABS).

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Gerry Jackson on Wed May 1 17:19:49 2024
    Gerry Jackson <do-not-use@swldwa.uk> writes:
    - the pictured output buffer (POB) may be transient, can be corrupted by
    the system e.g. being moved or overwritten

    It is invalidated by anything that ALLOTs or COMPILE,s. I have not
    found that to be a problem.

    However, with the same interface (less restrictions) one could
    implement a growable HOLD buffer that is not located relative to HERE
    and is therefore not destroyed by ALLOT and COMPILE,.

    - POB contents are built up from right to left, making concatenation
    user hostile

    It's designed for converting numbers to strings, that means it builds
    up the number from the least significant digit. If you want something
    for concatenating strings, use something else.

    - only one buffer available to the programmer

    Gforth supports nested generation of numbers in that single buffer:

    <<# starts a new (nested) number); use that instead of <#
    gives you the string, still holding it
    releases the memory for the string

    E.g.:

    : my-u. ( u -- )
    \ Simplest use of pns.. behaves like Standard u.
    0 \ convert to unsigned double
    <<# \ start conversion
    #s \ convert all digits
    #> \ complete conversion
    TYPE SPACE \ display, with trailing space
    #>> ; \ release hold area

    More docs at <https://gforth.org/manual/Formatted-numeric-output.html>

    I found that sufficient for my usage.

    - cannot set POB size

    If anything, the HOLD buffer should grow automatically.

    - buffers not nestable

    Fixed in Gforth, see above.

    - POB contents can only be accessed by #> which terminates things

    You can do

    ( ud ) 2DUP #> ( ud c-addr u )

    to get the string without destroying the number, but I have not
    found the need to do that. That's standard usage.

    - system words such as .S may use the POB, thus hindering debugging
    - the system need not check the POB for overflow

    In Gforth .S uses <<# ... #>> and thus avoids destroying the existing
    stuff in the HOLD buffer.

    Some of these can be improved in a Forth system but software using the >improvements may not be portable between systems.

    For debugging, this is not a big problem: Debug on Gforth, then run on
    a less capable system.

    I've written my own version of <# etc, with the '#' replaced by '~',
    that does not have the above problems. It has:

    In which way does it solve the compatibility problem? If that is done
    by loading the source code for these words, one could also reimplement
    the standard words, with enhancements like <<# #>> to address the
    issues.

    <~ ( -- ca u ) get contents of buffer, close it and open another

    What invalidates the string?

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Wed May 1 17:03:53 2024
    dxf <dxforth@gmail.com> writes:
    As a matter of curiosity how and where does C do numeric conversion?
    Does it use a temp buffer? If so, then it must do a copy to the
    destination.

    User-supplied buffer, like

    snprintf(buf, bufsize, "%d", n);

    for general printf-style formatting. There is a GNU extension
    asprintf(...) which allocates the string with malloc.

    C++ has its own stuff that is much different.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to dxf on Wed May 1 21:41:53 2024
    dxf <dxforth@gmail.com> writes:
    Perhaps implementations vary. Subsequent to my question I remembered
    I had the source for a 'small-C' for CP/M. Looking at the primitive for sprintf I found it uses a small static buffer. The numeric string is
    built there after which it's copied to the user-designated buffer.

    sprintf(buf, "%d", n) still works. It's like snprintf except the buffer
    size is not specified. The buffer is instead assumed to be large enough
    to hold the output. That can obviously be dangerous, especially
    considering %s for formatting strings, so snprintf is preferred.

    Using a static buffer creates obvious thread safety issues if two calls
    to sprintf are active at the same time. The Linux man page for sprintf
    and friends has the thread safety attribute "MT-Safe locale" for those functions. I don't know what that means exactly though. In CP/M this
    probably wasn't an issue.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stephen Pelc@21:1/5 to Paul Rubin on Thu May 2 14:00:28 2024
    On 1 May 2024 at 05:37:50 CEST, "Paul Rubin" <no.email@nospam.invalid> wrote:

    dxf <dxforth@gmail.com> writes:
    Moore hated double precision.
    From his ANS exit speech?

    Yeah I'm puzzled too. I remember hearing someplace that m*/ was one of
    his prouder creations. It requires a triple precision intermediate
    product, so it is hard to implement in C.
    c

    Neither Forth nor C give direct access to the carry and overflow flags, yet
    we and many others have written M*/ in high level Forth for decades.
    --
    Stephen Pelc, stephen@vfxforth.com
    MicroProcessor Engineering, Ltd. - More Real, Less Time
    133 Hill Lane, Southampton SO15 5AF, England
    tel: +44 (0)78 0390 3612, +34 649 662 974
    http://www.mpeforth.com
    MPE website
    http://www.vfxforth.com/downloads/VfxCommunity/
    downloads

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to Stephen Pelc on Thu May 2 14:37:03 2024
    Stephen Pelc wrote:
    Neither Forth nor C give direct access to the carry and overflow flags,
    yet
    we and many others have written M*/ in high level Forth for decades.

    Today most C compilers offer some intrinsics beyound classic limited arithmetic,
    eg for addition with carry.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to minforth on Fri May 3 16:33:17 2024
    minforth@gmx.net (minforth) writes:
    Today most C compilers offer some intrinsics beyound classic limited >arithmetic,
    eg for addition with carry.

    Yes. However, when I tried these, the code that came out was not as
    well as I would have liked; see
    <2016May24.093059@mips.complang.tuwien.ac.at> and <2021Mar15.104123@mips.complang.tuwien.ac.at>.

    Last I tried it, in a sequence of a few such intrinsics the compilers
    do ok between the intrinsics, but produce bad code at the start and
    the end of the sequence.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Fri May 3 16:49:08 2024
    dxf <dxforth@gmail.com> writes:
    If the plan is multiple tasks should do fp output then things
    such as REPRESENT's buffer would probably need protecting too.

    REPRESENT uses a buffer that the caller provides, so its interface is compatible with thread-safety. However, REPRESENT is obviously based
    on ecvt(), which is not thread-safe. But fortunately, if you use
    glibc, there is ecvt_r(), which is thread-safe.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Paul Rubin on Fri May 3 16:54:55 2024
    Paul Rubin <no.email@nospam.invalid> writes:
    The Linux man page for sprintf
    and friends has the thread safety attribute "MT-Safe locale" for those >functions. I don't know what that means exactly though.

    That's why the man page points you to attributes(7), and when I do

    man 7 attributes

    it tells me that MT-Safe means "thread-safe", i.e., "safe to call in
    the presence of other threads."

    About the "locale" remark it says:

    |Functions annotated with locale as an MT-Safety issue read from the
    |locale object without any form of synchronization. Functions
    |annotated with locale called concurrently with locale changes may
    |behave in ways that do not correspond to any of the locales active
    |during their execution, but an unpredictable mix thereof.

    But you are not supposed to change the locale in a multi-threaded
    program.

    Anyway, the locale thing shows a problem with the suggestion to use
    sprintf() instead of ecvt_r().

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Fri May 3 17:04:20 2024
    dxf <dxforth@gmail.com> writes:
    On 2/05/2024 3:57 am, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    So how have serious forth implementations handled the Standard's lack of >>> numeric string output functions? Many went ahead and provided (D.) (.)
    (F.) etc.

    Gforth does not, and does not have factors that correspond to (D.) or
    (.), and any such factors, if they existed, would put the onus on the
    user to release the memory for the string with #>>.

    What does that mean? Are you saying GForth users can't expect the following >standard code to function the same as in other forths?

    : (D.) ( d -- adr len ) tuck dabs <# #s rot sign #> ;

    No. What in the sentence above makes you think so?

    It means: Gforth does not provide (D.) and does not have factors that correspond to (D.) or (.). If it had such factors, you would have to
    use them in the following way:

    ( d ) (D.) ( do something with the string, and when you are done:) #>>

    String output allows transformation - adding thousands separators
    from (D.)

    Please demonstrate that that's less effort than using #, HOLD etc. for
    that purpose.

    I've demonstrated that it's cheaper and easier to provide string numerics >from the get-go than to provide them later. And yes, adding thousands >separators to an integer or floating-point string (works for both) requires >but a few string operators one likely already has. I posted the code just >recently. Perhaps you missed it.

    \ Add commas to integer/float numeric string. Uses HOLD buffer
    : +COMMA ( a1 u1 -- a2 u2 )
    <# [char] . split 2swap shold
    0 begin over while >r \char
    r> 2dup 3 = swap digit? and
    if [char] , hold drop 0 then
    swap hold 1+
    repeat drop #> ;

    : u._ ( u -- )
    0 <# begin
    3 0 do
    # 2dup 0. d= if
    #> type unloop exit then
    loop
    '_' hold
    again ;

    The latter looks simpler to me.

    Something that can be applied to any of the zoo of .-like words is a
    good idea, though.

    Let's see how +COMMA fares

    : +COMMA ( a1 u1 -- a2 u2 ) compiled
    <# [char] . split 2swap shold
    *the terminal*:12:16: error: Undefined word
    <# [char] . >>>split<<< 2swap shold

    So it needs additional complexity. Anyway, assuming that is fixed,
    you would +COMMA work with the (D.) you are advocating?

    An alternative approach to this kind of postprocessing is to be able
    to plug something into the # used in front of a decimal point (of
    course this would only work for words built with this pluggable #).
    The usage might be something like:

    1234567890 ' #3_ ' . #execute

    The implementation of #3_ might be something like:

    : #3_ ( u1 d1 -- u2 d2 )
    rot dup 0> if
    dup 3 mod 0= if
    '_' hold
    then
    then
    -rot basic-# ;

    Of course, . etc. would have to be adapted, too.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to dxf on Fri May 3 19:55:46 2024
    dxf wrote:
    That's been tried in forth e.g. MVP math and f/p extensions. IIRC the results were neither fast nor pretty. Trying to emulate machine code
    at this level appears to be of dubious benefit.

    Intrinsics ARE assembler code.
    Use gdb to inspect the result.
    If you can't in your DOS world, try godbolt.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to Anton Ertl on Fri May 3 20:16:31 2024
    Anton Ertl wrote:

    minforth@gmx.net (minforth) writes:
    Today most C compilers offer some intrinsics beyound classic limited >>arithmetic, eg for addition with carry.

    Yes. However, when I tried these, the code that came out was not as
    well as I would have liked; see
    <2016May24.093059@mips.complang.tuwien.ac.at> and <2021Mar15.104123@mips.complang.tuwien.ac.at>.

    Last I tried it, in a sequence of a few such intrinsics the compilers
    do ok between the intrinsics, but produce bad code at the start and
    the end of the sequence.

    I was also a little underwhelmed. But at least they are there and can
    help to avoid some awkward comparisons or extra operations. For high
    speed, there is always the option of using C's built-in assembler
    directly. The nice thing is that you have the freedom of choice.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to Anton Ertl on Fri May 3 20:19:40 2024
    Anton Ertl wrote:

    minforth@gmx.net (minforth) writes:
    Today most C compilers offer some intrinsics beyound classic limited >>arithmetic, eg for addition with carry.

    Last I tried it, in a sequence of a few such intrinsics the compilers
    do ok between the intrinsics, but produce bad code at the start and
    the end of the sequence.

    I was also a little underwhelmed. But at least they are there and can
    help to avoid some awkward comparisons or extra operations. For high
    speed, there is always the option of using C's built-in assembler
    directly. The nice thing is that you have the freedom of choice.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to minforth on Sat May 4 16:11:36 2024
    minforth@gmx.net (minforth) writes:
    Last I tried it, in a sequence of a few such intrinsics the compilers
    do ok between the intrinsics, but produce bad code at the start and
    the end of the sequence.

    I was also a little underwhelmed. But at least they are there and can
    help to avoid some awkward comparisons or extra operations.

    Yes, the carry-in support is not so great, but for checking overflow,
    these extensions are fine, and Bernd Paysan recently added code to
    Gforth that uses gcc's __builtin_add_overflow() (if present) to
    implement (+LOOP). As a consequence, (+LOOP) became a little shorter.
    E.g.:

    with without
    __builtin_add_overflow()
    add rbx,$10 add r13,$10
    mov rax,[r14] mov rax,[r10]
    add r13,$08 add r11,$08
    mov rsi,-$08[rbx] mov rsi,-$08[r13]
    lea rdx,[r8][rax] mov rdx,rax
    sub rax,$08[r14] sub rdx,$08[r10]
    btc rax,$3F add rax,rbx
    mov [r14],rdx lea rcx,[rbx][rdx]
    add rax,r8 mov [r10],rax
    mov r8,$00[r13] xor rcx,rdx
    jo x xor rdx,rbx
    mov rax,[rsi] mov rbx,[r11]
    mov rbx,rsi test rcx,rdx
    jmp eax js x
    x: mov rax,[rbx] mov rax,[rsi]
    jmp eax mov r13,rsi
    jmp eax
    x: mov rax,$00[r13]
    jmp eax

    However, it turns out that on RISC-V (which does not have an overflow
    flag) the code produced by gcc for our (+LOOP) with
    __builtin_add_overflow() is worse than for (+LOOP) without.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Anton Ertl on Sat May 4 13:35:04 2024
    anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
    man 7 attributes
    it tells me that MT-Safe means "thread-safe", i.e., "safe to call in
    the presence of other threads."

    Yes I saw that, but it isn't clear to me from that description that
    sprintf can safely be active in both threads at the same time.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to Paul Rubin on Sun May 5 14:31:38 2024
    Paul Rubin <no.email@nospam.invalid> writes:
    anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
    man 7 attributes
    it tells me that MT-Safe means "thread-safe", i.e., "safe to call in
    the presence of other threads."

    Yes I saw that, but it isn't clear to me from that description that
    sprintf can safely be active in both threads at the same time.

    What else would thread-safe or "multi-threading safe" mean?

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Sun May 5 15:07:09 2024
    dxf <dxforth@gmail.com> writes:
    On 4/05/2024 3:04 am, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    [...]
    It means: Gforth does not provide (D.) and does not have factors that
    correspond to (D.) or (.). If it had such factors, you would have to
    use them in the following way:

    ( d ) (D.) ( do something with the string, and when you are done:) #>>

    Standard Forth makes no such instruction.

    Of course not, because standard Forth has no word (D.).

    ...
    \ Add commas to integer/float numeric string. Uses HOLD buffer
    : +COMMA ( a1 u1 -- a2 u2 )
    <# [char] . split 2swap shold
    0 begin over while >r \char
    r> 2dup 3 = swap digit? and
    if [char] , hold drop 0 then
    swap hold 1+
    repeat drop #> ;

    : u._ ( u -- )
    0 <# begin
    3 0 do
    # 2dup 0. d= if
    #> type unloop exit then
    loop
    '_' hold
    again ;

    The latter looks simpler to me.

    Will you write another separator function for floats?
    +COMMA handles both and is economic:

    355000000 113 / (.) >pad +comma cr type
    3,141,592 ok

    Pi 1e6 f* -1 (f.) >pad +comma cr type
    3,141,592.6535897932 ok

    1e 0e f/ -1 (f.) >pad +comma cr type
    +INF ok

    ...
    Let's see how +COMMA fares

    : +COMMA ( a1 u1 -- a2 u2 ) compiled
    <# [char] . split 2swap shold
    *the terminal*:12:16: error: Undefined word
    <# [char] . >>>split<<< 2swap shold

    So it needs additional complexity. Anyway, assuming that is fixed,

    Requirements were: "a few string operators one likely already has"

    : SHOLD HOLDS ;

    : SPLIT ( a u c -- a2 u2 a3 u3 ) \ split at char
    r 2dup r> scan 2swap 2 pick - ;

    : \CHAR ( a u -- a2 u2 c ) \ extract char from end
    1- 2dup + c@ ;

    : DIGIT? ( char -- flag ) \ true if char is decimal digit
    [char] 0 - #10 u< ;

    Nothing there that forthers wouldn't have seen or used before.

    So your complete setup is

    : SHOLD HOLDS ;

    : SPLIT ( a u c -- a2 u2 a3 u3 ) \ split at char
    >r 2dup r> scan 2swap 2 pick - ;

    : \CHAR ( a u -- a2 u2 c ) \ extract char from end
    1- 2dup + c@ ;

    : DIGIT? ( char -- flag ) \ true if char is decimal digit
    [char] 0 - #10 u< ;

    \ Add commas to integer/float numeric string. Uses HOLD buffer
    : +COMMA ( a1 u1 -- a2 u2 )
    <# [char] . split 2swap shold
    0 begin over while >r \char
    r> 2dup 3 = swap digit? and
    if [char] , hold drop 0 then
    swap hold 1+
    repeat drop #> ;

    And it works fine. Of course, because it uses <#, it does not work
    with the nesting feature:

    #12345. <<# #s #67890. <<# #s #> cr type #>> #> cr type #>>

    prints

    67890
    12345

    but

    #12345. <<# #s #67890. <<# #s #> +comma cr type #>> #> cr type #>>

    prints

    67,890
    *the terminal*:30:49: error: Result out of range
    #12345. <<# #s #67890. <<# #s #> +comma cr type >>>#>><<< #> cr type #>> Backtrace:
    kernel/nio.fs:63:44: 0 $7FE0F9CB8690 throw

    But that could be fixed by using <<# in +COMMA.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From albert@spenarnc.xs4all.nl@21:1/5 to Anton Ertl on Mon May 6 01:01:25 2024
    In article <2024May5.170709@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    dxf <dxforth@gmail.com> writes:
    On 4/05/2024 3:04 am, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    [...]
    It means: Gforth does not provide (D.) and does not have factors that
    correspond to (D.) or (.). If it had such factors, you would have to
    use them in the following way:

    ( d ) (D.) ( do something with the string, and when you are done:) #>>

    Standard Forth makes no such instruction.

    Of course not, because standard Forth has no word (D.).

    Indeed, surprisingly, but every Forth made in the Netherlands
    apparently has at least (D.R) that was already present in figForth or
    an equivalent to (D.).
    In my experience those words that leave a string and doesnot TYPE immediately are pretty essential. The fact that #> may refer to a static buffer
    cannot be concealed anyway.

    - anton

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Mon May 6 17:58:08 2024
    dxf <dxforth@gmail.com> writes:
    On 6/05/2024 1:07 am, Anton Ertl wrote:
    ...
    So your complete setup is

    : SHOLD HOLDS ;

    : SPLIT ( a u c -- a2 u2 a3 u3 ) \ split at char
    >r 2dup r> scan 2swap 2 pick - ;

    : \CHAR ( a u -- a2 u2 c ) \ extract char from end
    1- 2dup + c@ ;

    : DIGIT? ( char -- flag ) \ true if char is decimal digit
    [char] 0 - #10 u< ;

    \ Add commas to integer/float numeric string. Uses HOLD buffer
    : +COMMA ( a1 u1 -- a2 u2 )
    <# [char] . split 2swap shold
    0 begin over while >r \char
    r> 2dup 3 = swap digit? and
    if [char] , hold drop 0 then
    swap hold 1+
    repeat drop #> ;

    And it works fine. Of course, because it uses <#, it does not work
    with the nesting feature:
    ...
    #12345. <<# #s #67890. <<# #s #> +comma cr type #>> #> cr type #>>

    prints

    67,890
    *the terminal*:30:49: error: Result out of range
    #12345. <<# #s #67890. <<# #s #> +comma cr type >>>#>><<< #> cr type #>>
    Backtrace:
    kernel/nio.fs:63:44: 0 $7FE0F9CB8690 throw

    But that could be fixed by using <<# in +COMMA.

    Have you documented that use of <## ##> can adversely impact standard forth >code and practices? It was news to me.

    I assume you mean <<# and #>>. If you use standard code, you do not
    use <<# nor #>>, and the code works as specified in the standard. In
    the example above, it's the standard word <# (inside the +COMMA) that
    adversely affects the usage of the HOLD buffer stack. You can read
    the documentation in
    <https://gforth.org/manual/Formatted-numeric-output.html>.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to albert@spenarnc.xs4all.nl on Mon May 6 17:50:34 2024
    albert@spenarnc.xs4all.nl writes:
    In article <2024May5.170709@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    dxf <dxforth@gmail.com> writes:
    On 4/05/2024 3:04 am, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    [...]
    It means: Gforth does not provide (D.) and does not have factors that
    correspond to (D.) or (.). If it had such factors, you would have to
    use them in the following way:

    ( d ) (D.) ( do something with the string, and when you are done:) #>> >>>
    Standard Forth makes no such instruction.

    Of course not, because standard Forth has no word (D.).

    Indeed, surprisingly, but every Forth made in the Netherlands
    apparently has at least (D.R) that was already present in figForth or
    an equivalent to (D.).

    What every Forth made in the Netherlands has is not relevant for the
    issue at hand. fig-Forth does not have (D.R); see, e.g., <http://www.stackosaurus.com/figforth/fig-FORTH_Glossary_2017.pdf>.

    In my experience those words that leave a string and doesnot TYPE immediately >are pretty essential.


    The fact that #> may refer to a static buffer
    cannot be concealed anyway.

    The HOLD buffer has not been static in traditional Forth, and some of
    the restrictions on its usage stem from there. Moreover, in Gforth #>
    refers to the top of a stack of HOLD buffers (managed with <<# and
    ).

    - 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: https://euro.theforth.net/2023

    --- 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 6 22:24:52 2024
    In article <66385218$1@news.ausics.net>, dxf <dxforth@gmail.com> wrote:
    On 6/05/2024 9:01 am, albert@spenarnc.xs4all.nl wrote:
    In article <2024May5.170709@mips.complang.tuwien.ac.at>,
    Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
    dxf <dxforth@gmail.com> writes:
    On 4/05/2024 3:04 am, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    [...]
    It means: Gforth does not provide (D.) and does not have factors that >>>>> correspond to (D.) or (.). If it had such factors, you would have to >>>>> use them in the following way:

    ( d ) (D.) ( do something with the string, and when you are done:) #>> >>>>
    Standard Forth makes no such instruction.

    Of course not, because standard Forth has no word (D.).

    Indeed, surprisingly, but every Forth made in the Netherlands
    apparently has at least (D.R) that was already present in figForth or
    an equivalent to (D.).
    In my experience those words that leave a string and doesnot TYPE immediately
    are pretty essential.

    Indeed - what this thread was intended to convey. It's a pity Forth Standards >just ignored it with the result too many implementations also ignore it.

    I remarked that all Forth in the Netherlands has such a word.
    According Anton Ertl this is "not relevant".
    Also that swiftforth has defined D. as
    : D. (D.) TYPE SPACE ;
    is not relevant.


    The fact that #> may refer to a static buffer
    cannot be concealed anyway.

    And with high-end forths offering circular buffers for temp string storage it >ought not to be a problem. VFX has >SYSPAD and SwiftForth something similar. >Thus far PAD has sufficed me. I'll add complexity when and if I need it.

    As discussed, the programmer interface need not change.

    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Tue May 7 16:07:11 2024
    dxf <dxforth@gmail.com> writes:
    On 7/05/2024 3:58 am, Anton Ertl wrote:
    I assume you mean <<# and #>>. If you use standard code, you do not
    use <<# nor #>>, and the code works as specified in the standard. In
    the example above, it's the standard word <# (inside the +COMMA) that
    adversely affects the usage of the HOLD buffer stack.

    And it's in support of this concept of a HOLD buffer stack (that doesn't >exist in Standard Forth or any other AFAIK) that Gforth won't provide (.)
    et al that's been present on virtually all desktop forths?

    It certainly is a reason why "(.)" with the meaning you seem have in
    mind is not a factor of "." in Gforth.

    ISTM Gforth has a choice to make. It can do it its own thing - or it can >adopt what has been common practice. For it's clear that when there's no >common practice, nor moves towards it, there can't be a Standard.

    According to you it is common practice already, and I think someone
    has also claimed that words like (.) are used often, not that I have
    missed them. If it is common practice, and you want to see it
    standardized, make a proposal; documenting the common practice in
    systems and programs would be useful to support such a proposal.

    I see that in SwiftForth 4.0.0-RC87 there are the following number of
    uses:

    6 (.)
    3 (U.)
    3 (D.)
    3 (DU.)
    0 (U.R)
    4 #S
    10 #>
    10 <#

    Not defined: (.R) (D.R) (DU.R)

    Mostly indepenently of this, I find figForth's factoring of .-related
    words (inherited by Gforth) more elegant than the SwiftForth ones:

    fig-Forth (reformatted to be more comparable to SwiftForth):

    : D.R
    >R SWAP OVER DABS <# #S SIGN #>
    R> OVER - SPACES TYPE ;
    : D. 0 D.R SPACE ;
    : .R >R S->D R> D.R ;
    : . S->D D. ;

    SwiftForth:

    : (D.) ( d -- addr len ) TUCK DABS <# #S ROT SIGN #> ;
    : (.) ( n -- addr len ) S>D (D.) ;
    : D. ( d -- ) (D.) TYPE SPACE ;
    : . ( n -- ) (.) TYPE SPACE ;
    : D.R ( d n -- ) >R (D.) R> OVER - SPACES TYPE ;
    : .R ( n n -- ) >R (.) R> OVER - SPACES TYPE ;

    In the fig-Forth variant you could factor out (D.), but it would be
    used only once. Likewise, with a fig-Forth-like factoring, the usage
    numbers for the (.)-like words would be somewhat lower.

    BTW, wouldn't you recommend that Gforth should do its own thing? At
    least that's how I read many of your messages over the years.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Wed May 8 07:06:24 2024
    dxf <dxforth@gmail.com> writes:
    On 8/05/2024 2:07 am, Anton Ertl wrote:
    If it is common practice, and you want to see it
    standardized, make a proposal; documenting the common practice in
    systems and programs would be useful to support such a proposal.

    It's my understanding the Technical Committee has responsibility for >maintaining Standard Forth and keeping it relevant.

    Apparently nobody inside the committee or outside thinks that "(.)"
    etc. are sufficiently important to be added to the standard, otherwise
    someone would have made a proposal for them, an option that is open to everyone.

    The committee is not a closed club, either, and we would love to have
    more participation there, but the bar is somewhat higher, because
    presence at two consecutive meetings is required (this requirement can
    be lowered at the discretion of the committee).

    That ignores the use of number strings in applications. SwiftForth did
    the right thing in providing them upfront. From one of my apps:

    \ Save settings to file
    : !SETTINGS ( -- )
    s" [options]" write
    s" -s" write send.s @ (.) write
    s" -c" write char.s @ (.) write
    s" -d" write wspace @ (.) write
    cspace @ dup 3 <> and ?dup if
    [char] , writechr (.) write
    then
    s" -t" write tone @ (.) write
    s" -o" compress @ 0= and write
    s" -p" write punct @ (.) write
    s" -l" lsignal @ 0<> and write
    s" -u" write volume @ (.) write
    writecr ;

    It seems to me that your system is missing a word like

    'outfile-execute' ( ... xt file-id -- ... ) gforth-0.7 "outfile-execute"
    execute xt with the output of 'type' etc. redirected to file-id.

    With that word you could write !SETTINGS as:

    \ Save settings to file
    : .SETTINGS ( -- )
    ." [options]"
    ." -s" send.s @ .
    ." -c" char.s @ .
    ." -d" wspace @ .
    cspace @ dup 3 <> and ?dup if
    [char] , emit .
    then
    ." -t" tone @ .
    ." -o" compress @ 0= and type
    ." -p" punct @ .
    ." -l" lsignal @ 0<> and type
    ." -u" volume @ .
    cr ;

    : !settings ( -- )
    ['] .settings dxf's-default-file @ outfile-execute ;

    This allows you to test .SETTINGS interactively and eliminates the
    need for words like WRITE, WRITECHR and WRITECR.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Thu May 9 14:57:36 2024
    dxf <dxforth@gmail.com> writes:
    With that word you could write !SETTINGS as:

    \ Save settings to file
    : .SETTINGS ( -- )
    ." [options]"
    ." -s" send.s @ .
    ." -c" char.s @ .
    ." -d" wspace @ .
    cspace @ dup 3 <> and ?dup if
    [char] , emit .
    then
    ." -t" tone @ .
    ." -o" compress @ 0= and type
    ." -p" punct @ .
    ." -l" lsignal @ 0<> and type
    ." -u" volume @ .
    cr ;

    : !settings ( -- )
    ['] .settings dxf's-default-file @ outfile-execute ;

    This allows you to test .SETTINGS interactively and eliminates the
    need for words like WRITE, WRITECHR and WRITECR.

    And have it disappear off the screen

    The output of .SETTINGS is a single line. You have a screen that
    cannot display that and your system does not support scrolling back?

    But even if you prefer to work in such a deprived environment, the
    advantage that you need just one additional word instead of a whole
    bunch is still there.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Anton Ertl@21:1/5 to dxf on Fri May 10 06:31:32 2024
    dxf <dxforth@gmail.com> writes:
    Gforth uses numeric
    primitives to build "." but won't make it available to users to send
    directly to disk.

    Which numeric primitives are you referring to? I expect that, because
    the reality is that all words that Gforth uses to implement "." are
    available to users, you will not answer the question, but do your
    usual thing and move the goalposts or make some other unsubstantiated
    claim to detract from you inability to support your claim.

    - 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: https://euro.theforth.net/2023

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to All on Fri May 10 08:34:10 2024
    Even me, as no regular user of gforth, can inspect the code for . :

    Gforth 0.7.9_20200709
    Authors: Anton Ertl, Bernd Paysan, Jens Wilke et al., for more type `authors' Copyright © 2019 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html> Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
    Type `help' for basic help
    see .
    : .
    s>d d. ; ok
    see d.
    : d. 0
    d.r space ; ok
    see d.r
    : d.r
    >r tuck dabs <<# #s rot sign #> r> over - spaces type #>> ; ok
    see <<#
    : <<#
    holdend @ holdptr @ - hold holdptr @ holdend ! ; ok
    see #>>
    : #>>
    holdend @ dup holdbuf-end u>= -11 and throw count bounds holdptr ! holdend ! ; ok
    et cetera

    Perhaps dxf's problem is only, that he uses DOS memory-mapped screens, perhaps controlled through BIOS interrupts. But only he could tell.

    --- 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 May 10 11:49:46 2024
    In article <663d66dd$1@news.ausics.net>, dxf <dxforth@gmail.com> wrote:
    On 10/05/2024 12:57 am, Anton Ertl wrote:
    dxf <dxforth@gmail.com> writes:
    With that word you could write !SETTINGS as:

    \ Save settings to file
    : .SETTINGS ( -- )
    ." [options]"
    ." -s" send.s @ .
    ." -c" char.s @ .
    ." -d" wspace @ .
    cspace @ dup 3 <> and ?dup if
    [char] , emit .
    then
    ." -t" tone @ .
    ." -o" compress @ 0= and type
    ." -p" punct @ .
    ." -l" lsignal @ 0<> and type
    ." -u" volume @ .
    cr ;

    : !settings ( -- )
    ['] .settings dxf's-default-file @ outfile-execute ;

    This allows you to test .SETTINGS interactively and eliminates the
    need for words like WRITE, WRITECHR and WRITECR.

    And have it disappear off the screen

    The output of .SETTINGS is a single line. You have a screen that
    cannot display that and your system does not support scrolling back?

    But even if you prefer to work in such a deprived environment, the
    advantage that you need just one additional word instead of a whole
    bunch is still there.

    All this assumes one needs to see on screen what goes to disk. That's >exceptional in my experience.

    The fact remains forth has separate words for console and disk output:
    TYPE and WRITE-FILE. These take adr/len strings as arguments. The
    numeric primitive for that is (.) and friends. Gforth uses numeric >primitives to build "." but won't make it available to users to send
    directly to disk. Standard Forth isn't much better.

    This may not be so separate (in a Forth I'm familiar with ..)

    : TYPE DUP OUT +! 1 WRITE-FILE THROW ;
    : ETYPE 2 WRITE-FILE THROW ;
    [ and : EMIT DSP@ 1 TYPE DROP ; ]

    The 1 and 2 refer to standardout and standarderror (unix).
    In windows version they are named STDOUT and STDERR.



    Groetjes Albert
    --
    Don't praise the day before the evening. One swallow doesn't make spring.
    You must not say "hey" before you have crossed the bridge. Don't sell the
    hide of the bear until you shot it. Better one bird in the hand than ten in
    the air. First gain is a cat purring. - the Wise from Antrim -

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From minforth@21:1/5 to dxf on Fri May 10 18:08:13 2024
    dxf wrote:

    On 10/05/2024 6:34 pm, minforth wrote:
    Even me, as no regular user of gforth, can inspect the code for . :
    ...

    You agree that underlying Gforth's "." there exists a numeric string.

    Perhaps dxf's problem is only, that he uses DOS memory-mapped screens, perhaps
    controlled through BIOS interrupts. But only he could tell.

    I don't have any problems. My interest is why forth implementations
    (not all) haven't provided numeric string functions. A quick glance
    suggests Minforth doesn't have them. Any comment about that?

    Yes. Look again. :-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David LaRue@21:1/5 to minforth on Fri May 10 21:54:34 2024
    minforth@gmx.net (minforth) wrote in news:3ba5f14da0bdee180f47d23a6387ac20@www.novabbs.com:

    dxf wrote:

    On 10/05/2024 6:34 pm, minforth wrote:
    Even me, as no regular user of gforth, can inspect the code for . :
    ...

    You agree that underlying Gforth's "." there exists a numeric string.

    Perhaps dxf's problem is only, that he uses DOS memory-mapped screens,
    perhaps controlled through BIOS interrupts. But only he could tell.

    I don't have any problems. My interest is why forth implementations
    (not all) haven't provided numeric string functions. A quick glance
    suggests Minforth doesn't have them. Any comment about that?

    Yes. Look again. :-)


    As a lifelong developer, I don't understand people that have heard of and
    been given a solution for a problem and yet seem to complain that it isn't available to them everywhere. If you are a developer you will never let what hasn't been provided to you to block what can be accomplished by your tools. Make up any missing tools you may need along the way and carry them proudly
    as you build more solutions. You are responsible for providing any 'tools' that your toolset needs to complete the projects that you take on. That is
    why someone, perhaps you, chose to call you a developer and task you with completing a given project.

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