kForth 32-bit Development Plans

386 views
Skip to first unread message

Krishna Myneni

unread,
Jan 21, 2023, 12:35:24 PMJan 21
to
While I have had a brief couple of months respite from actively
developing kForth, one of the reasons has been that I have been actively
using it successfully on computing tasks. Although Bernd Paysan has
expressed the opinion that 32-bit computing is retro computing, for me
it still remains useful and I don't plan to abandon continued
development of the 32-bit versions of kForth, which presently come in
two variants:

ver. 1.x -- mostly Forth-94 compatible, uses integrated fp/data stack.

ver. 2.x -- provides Forth-2012 functionality, but still uses integrated
fp/data stack.

ver. 3.x -- in progress (no releases yet); will provide integrated
fp/data stack.

Retirement of ver. 1.x, currently available for Linux and Win32, is
imminent. No further development beyond v1.8.x will occur.

Version 2.x will switch from development to maintenance mode after its
Win32 release. New 32-bit development will focus on ver 3.x.

Ver 3.x will be the 32-bit counterpart of kForth-64.

--
Krishna Myneni







Krishna Myneni

unread,
Jan 21, 2023, 12:37:14 PMJan 21
to
On 1/21/23 11:35, Krishna Myneni wrote:
...
> ver. 3.x -- in progress (no releases yet); will provide integrated
> fp/data stack.
>
...

should be "will provide separate fp stack".

--
KM


dxforth

unread,
Jan 22, 2023, 1:22:12 AMJan 22
to
That will give you access to a wealth of new f/p applications.
At least that's what I've been told :)

Speaking of f/p I've just ditched output functions G.R and G. and
subsumed the functionality into F.R and F. While this breaks the
ANS notion of what F. was intended to print*, I still retain (F.)
and (G.) which output fixed and mixed notation respectively.

*It's an open question what F. is exactly supposed to print because
the sole example ANS gave was ambiguous. So in making the changes
mentioned in the previous paragraph I don't consider I'm shooting
myself (or anyone) in the foot.


Marcel Hendrix

unread,
Jan 22, 2023, 5:09:16 AMJan 22
to
On Sunday, January 22, 2023 at 7:22:12 AM UTC+1, dxforth wrote:
[..]
> Speaking of f/p I've just ditched output functions G.R and G. and
> subsumed the functionality into F.R and F. While this breaks the
> ANS notion of what F. was intended to print*, I still retain (F.)
> and (G.) which output fixed and mixed notation respectively.

Probably worth a new thread, but... Over the years I have
needed dozens of variants of the basic floating-point
formatting words. There is always something
slightly different that is needed (sufficiently
different or useful to put in a new word). Is
this a commonly accepted fact, or does it
indicate that we don't have the proper
Forth way to factor the problem yet?

-marcel

Anton Ertl

unread,
Jan 22, 2023, 5:43:13 AMJan 22
to
Marcel Hendrix <m...@iae.nl> writes:
>Probably worth a new thread, but... Over the years I have
>needed dozens of variants of the basic floating-point
>formatting words. There is always something
>slightly different that is needed (sufficiently
>different or useful to put in a new word). Is
>this a commonly accepted fact, or does it
>indicate that we don't have the proper
>Forth way to factor the problem yet?

When I looked into the problem, I found no good way to apply the
flexible approach used for integers (with # HOLD etc.) for FP output.
I also inspected what C does with printf(), and eventually settled on
F.RDP. Here's the documentation:

|'f.rdp' ( rf +nr +nd +np -- ) gforth-0.6 "f.rdp"
| Print float rf formatted. The total width of the output is nr. For
|fixed-point notation, the number of digits after the decimal point is
|+nd and the minimum number of significant digits is np. 'Set-precision'
|has no effect on 'f.rdp'. Fixed-point notation is used if the number of
|siginicant digits would be at least np and if the number of digits
|before the decimal point would fit. If fixed-point notation is not
|used, exponential notation is used, and if that does not fit, asterisks
|are printed. We recommend using nr>=7 to avoid the risk of numbers not
|fitting at all. We recommend nr>=np+5 to avoid cases where 'f.rdp'
|switches to exponential notation because fixed-point notation would have
|too few significant digits, yet exponential notation offers fewer
|significant digits. We recommend nr>=nd+2, if you want to have
|fixed-point notation for some numbers; the smaller the value of np, the
|more cases are shown in fixed-point notation (cases where few or no
|significant digits remain in fixed-point notation). We recommend np>nr,
|if you want to have exponential notation for all numbers. the field
|width for f.s output. Other precision details are derived from that
|value.
|
| To give you a better intuition of how they influence the output, here
|are some examples of parameter combinations; in each line the same
|number is printed, in each column the same parameter combination is used
|for printing:
|
| 12 13 0 7 3 4 7 3 0 7 3 1 7 5 1 7 7 1 7 0 2 4 2 1
| |-1.234568E-6|-1.2E-6| -0.000|-1.2E-6|-1.2E-6|-1.2E-6|-1.2E-6|****|
| |-1.234568E-5|-1.2E-5| -0.000|-1.2E-5|-.00001|-1.2E-5|-1.2E-5|****|
| |-1.234568E-4|-1.2E-4| -0.000|-1.2E-4|-.00012|-1.2E-4|-1.2E-4|****|
| |-1.234568E-3|-1.2E-3| -0.001| -0.001|-.00123|-1.2E-3|-1.2E-3|****|
| |-1.234568E-2|-1.2E-2| -0.012| -0.012|-.01235|-1.2E-2|-1.2E-2|-.01|
| |-1.234568E-1|-1.2E-1| -0.123| -0.123|-.12346|-1.2E-1|-1.2E-1|-.12|
| |-1.2345679E0| -1.235| -1.235| -1.235|-1.23E0|-1.23E0|-1.23E0|-1E0|
| |-1.2345679E1|-12.346|-12.346|-12.346|-1.23E1|-1.23E1| -12.|-1E1|
| |-1.2345679E2|-1.23E2|-1.23E2|-1.23E2|-1.23E2|-1.23E2| -123.|-1E2|
| |-1.2345679E3|-1.23E3|-1.23E3|-1.23E3|-1.23E3|-1.23E3| -1235.|-1E3|
| |-1.2345679E4|-1.23E4|-1.23E4|-1.23E4|-1.23E4|-1.23E4|-12346.|-1E4|
| |-1.2345679E5|-1.23E5|-1.23E5|-1.23E5|-1.23E5|-1.23E5|-1.23E5|-1E5|

F.RDP has proved sufficient for my needs, but then I do not do as much
with FP numbers as you do.

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

none albert

unread,
Jan 22, 2023, 6:21:40 AMJan 22
to
In article <05d987fd-f21e-430d...@googlegroups.com>,
I once has the conviction that I was to define a wordset similar
to the #-set for floating point numbers. Then I lost the code or
interest, or both. It is doable, but not to you, expert
programmers. An expert designer will be needed.

>
>-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 spinning. - the Wise from Antrim -

minf...@arcor.de

unread,
Jan 22, 2023, 7:18:39 AMJan 22
to
none albert schrieb am Sonntag, 22. Januar 2023 um 12:21:40 UTC+1:
> In article <05d987fd-f21e-430d...@googlegroups.com>,
> Marcel Hendrix <m...@iae.nl> wrote:
> >On Sunday, January 22, 2023 at 7:22:12 AM UTC+1, dxforth wrote:
> >[..]
> >> Speaking of f/p I've just ditched output functions G.R and G. and
> >> subsumed the functionality into F.R and F. While this breaks the
> >> ANS notion of what F. was intended to print*, I still retain (F.)
> >> and (G.) which output fixed and mixed notation respectively.
> >
> >Probably worth a new thread, but... Over the years I have
> >needed dozens of variants of the basic floating-point
> >formatting words. There is always something
> >slightly different that is needed (sufficiently
> >different or useful to put in a new word). Is
> >this a commonly accepted fact, or does it
> >indicate that we don't have the proper
> >Forth way to factor the problem yet?
> I once has the conviction that I was to define a wordset similar
> to the #-set for floating point numbers. Then I lost the code or
> interest, or both. It is doable, but not to you, expert
> programmers. An expert designer will be needed.

IMO a simple format string will do for most Forth applications, similar to:
https://eml.berkeley.edu/sst/fmttop.html

Then there is the old head-scratcher caused by the differing formats between
>FLOAT REPRESENT and text interpreter ....

Marcel Hendrix

unread,
Jan 22, 2023, 8:05:08 AMJan 22
to
On Sunday, January 22, 2023 at 11:43:13 AM UTC+1, Anton Ertl wrote:
> Marcel Hendrix <m...@iae.nl> writes:
[..]
> When I looked into the problem, I found no good way to apply the
> flexible approach used for integers (with # HOLD etc.) for FP output.

Yes, I am still hoping somebody finds a nice way to let the same
approach work with FP.

Basic problems I have with # based printing is output
to be in HEX or DECIMAL without changing BASE, and safe
against THROWs. There is printing with and without a trailing
space (when appending '.' or ','), and left/right aligning of possibly
negative numbers (print BL where a '+' is expected). And o yeah, every
one of these words should give a string result that can be further processed
with other string words. ( BTW, I use I/O device redirection to memory for TYPE
and friends for that.)

> I also inspected what C does with printf(), and eventually settled on
> F.RDP. Here's the documentation:
>
> |'f.rdp' ( rf +nr +nd +np -- ) gforth-0.6 "f.rdp"

Yes... What to do if printing in HEX, ligning up decimal points in a column
of +/- numbers, +Infinity -NaN etc. in too short fields, interchange
',' and '.', interchange 'E', 'e', 'd', 'D', print with scaling ( 1.1k instead
of 1.100e3 ), suppressing/adding trailing space, etc.? Of course
it is not possible to catch all these (and more) in a single word,
but is there a collection of words that anticipates all possible
results?

-marcel

dxforth

unread,
Jan 22, 2023, 8:18:50 AMJan 22
to
I don't accept Forth has more problems to solve than C and FORTRAN.
If their users can get by with the functions provided them, why not
Forth?

Marcel Hendrix

unread,
Jan 22, 2023, 8:21:42 AMJan 22
to
On Sunday, January 22, 2023 at 1:18:39 PM UTC+1, minf...@arcor.de wrote:
[..]
> IMO a simple format string will do for most Forth applications, similar to:
> https://eml.berkeley.edu/sst/fmttop.html

That is for reading floating point as text, which is a lot easier than printing.
Also, there is normally a way to get the equivalent in binary.
But a (nested) FORMAT string may have some merit...

-marcel

none albert

unread,
Jan 22, 2023, 8:46:07 AMJan 22
to
In article <tqjd3j$iql$1...@gioia.aioe.org>, dxforth <dxf...@gmail.com> wrote:
<SNIP>
>
>I don't accept Forth has more problems to solve than C and FORTRAN.
>If their users can get by with the functions provided them, why not
>Forth?

Need to ask? C and FORTRAN programmers have their solutions forced
down their throat.

dxforth

unread,
Jan 22, 2023, 9:26:18 AMJan 22
to
On 23/01/2023 12:46 am, albert wrote:
> In article <tqjd3j$iql$1...@gioia.aioe.org>, dxforth <dxf...@gmail.com> wrote:
> <SNIP>
>>
>> I don't accept Forth has more problems to solve than C and FORTRAN.
>> If their users can get by with the functions provided them, why not
>> Forth?
>
> Need to ask? C and FORTRAN programmers have their solutions forced
> down their throat.

Yes, they have a standard that provides. Isn't that what forthers have
been asking for?

Krishna Myneni

unread,
Jan 22, 2023, 9:52:44 AMJan 22
to
On 1/22/23 00:22, dxforth wrote:
...
> Speaking of f/p I've just ditched output functions G.R and G. and
> subsumed the functionality into F.R and F.  While this breaks the
> ANS notion of what F. was intended to print*, I still retain (F.)
> and (G.) which output fixed and mixed notation respectively.
>
...

From kForth's strings.4th,

\ F>FPSTR ( n -- a u ) ( F: r -- ) | ( r n -- a u )
\ F.RD ( w n -- ) ( F: r -- ) | ( r w n -- )

\ Convert r to a formatted fixed point string with
\ n decimal places, 0 <= n <= 17.
\ WARNING: Requesting a number fixed point decimal places which
\ results in total number of digits > 17 will give
\ incorrect results, e.g. "65536.9921875e 15 f>fpstr type"
\ will output garbage (20 digits are being requested).
: f>fpstr ( n -- a u ) ( F: r -- ) \ ( r n -- a u )
0 max 17 min >r 10e r@ s>f f**
f* fround f>d dup -rot dabs
<# r> 0 ?DO # LOOP [char] . hold #s rot sign #> ;

\ Print an fp number as a fixed point string with
\ n decimal places, right-justified in a field of width, w
: f.rd ( w n -- ) ( F: r -- ) \ ( r w n -- )
swap >r f>fpstr dup 20 > IF
\ Too many digits requested in fixed point output
2drop r> 0 ?DO [char] * emit LOOP
ELSE
r> over -
dup 0> IF spaces ELSE drop THEN type
THEN ;

F.RD is my workhorse formatting output word for fixed point output of
floating point numbers with a specified number of decimal places. It
uses F>FPSTR which returns a string instead of performing console output.

Along with FS. and F. (which provides 6 significant digits output in
either fixed point or scientific notation depending on the number), and
the PRECISION control words appear to be sufficient for most of my
floating point output needs.

--
Krishna

Anton Ertl

unread,
Jan 22, 2023, 1:29:13 PMJan 22
to
Marcel Hendrix <m...@iae.nl> writes:
>On Sunday, January 22, 2023 at 11:43:13 AM UTC+1, Anton Ertl wrote:
>> Marcel Hendrix <m...@iae.nl> writes:
>[..]
>> When I looked into the problem, I found no good way to apply the
>> flexible approach used for integers (with # HOLD etc.) for FP output.
>
>Yes, I am still hoping somebody finds a nice way to let the same
>approach work with FP.

One problem is that with FP you have rounding, and a number that would
print as 9.99 if enough space is available will print as 10. if less
space is available.

Another problem is that a fixed format like COBOL-style ##.## is only
usefuk for numbers x where 0.01<=abs(x)<100.

>Basic problems I have with # based printing is output
>to be in HEX or DECIMAL without changing BASE, and safe
>against THROWs.

Gforth's BASE-EXECUTE wraps a BASE change in a word; even if there is
a throw inside, BASE is the same afterwards as before.

|'base-execute' ( i*x xt u -- j*x ) gforth-0.7 "base-execute"
| execute xt with the content of 'BASE' being u, and restoring the
|original 'BASE' afterwards.

>There is printing with and without a trailing
>space (when appending '.' or ','),

F.RDP vs. F.RDP SPACE

>and left/right aligning of possibly
>negative numbers (print BL where a '+' is expected).

F.RDP aligns the . for the fixed-point notation when it can satisfy
the requirements for that notation, and switches to exponential
notation otherwise. Positive numbers are printed without a leading
sign (this means that for some numbers x>0, x can be printed in
fixed-point notation, and it may have to switch to exponential
notation for -x.

>And o yeah, every
>one of these words should give a string result that can be further processed
>with other string words.

There is f>str-rdp (produces string in pictured numeric output buffer)
and f>bud-rdp (produces string in buffer provided by the caller).

>( BTW, I use I/O device redirection to memory for TYPE
>and friends for that.)

Yes, Gforth has >STRING-EXECUTE, which wraps the redirection and
produces a string that contains the output. It's useful for dealing
with words where we don't have non-printing equivalents, but it is
also useful for constructing strings.

>> |'f.rdp' ( rf +nr +nd +np -- ) gforth-0.6 "f.rdp"
>
>Yes... What to do if printing in HEX,

F.RDP is always decimal.

> ligning up decimal points in a column
>of +/- numbers

That's what f.rdp is designed for. You see it in all the examples where fixed-point notation is output.

>+Infinity -NaN etc.

0e 0e f/ 7 3 1 '|' emit f.rdp '|' emit \ |NaN | ok
1e 0e f/ 7 3 1 '|' emit f.rdp '|' emit \ |Inf | ok
-1e 0e f/ 7 3 1 '|' emit f.rdp '|' emit \ |-Inf | ok

>in too short fields

Too-short fields give you **** as output. Just use nr>=7 (for
binary64 FP numbers) to avoid that.

> interchange ',' and '.', interchange 'E', 'e', 'd', 'D',
> print with scaling ( 1.1k instead
>of 1.100e3 ),

All not supported, so you may need some enhancement of F.RDP.

For the decimal separator, have a context wrapper to which you pass it.
Likewise for the exponent separator.

For a different base, BASE-EXECUTE already provides a context wrapper,
but the implementation of F.RDP would have to be changed significantly.

>suppressing/adding trailing space,

(Don't) call SPACE afterwards.

>Of course
>it is not possible to catch all these (and more) in a single word,
>but is there a collection of words that anticipates all possible
>results?

For "print with scaling" maybe a different word is necessary.

Anton Ertl

unread,
Jan 22, 2023, 1:40:32 PMJan 22
to
"minf...@arcor.de" <minf...@arcor.de> writes:
>Then there is the old head-scratcher caused by the differing formats between
>>FLOAT REPRESENT and text interpreter ....

The text interpreter supports less than >FLOAT, because it also has to
recognize things other than floats.

REPRESENT is the other direction. Its interface is modeled on ecvt(),
with one important feature left away: output length; what is also
missing is the companion fcvt() (this caused quite a bit of
complication during the development of F.RDP). In the meantime, the C
guys decided that ecvt()/fcvt() is not the way to go, and they leave
it all to sprintf().

dxforth

unread,
Jan 22, 2023, 7:50:16 PMJan 22
to
On 23/01/2023 12:05 am, Marcel Hendrix wrote:
> On Sunday, January 22, 2023 at 11:43:13 AM UTC+1, Anton Ertl wrote:
>> Marcel Hendrix <m...@iae.nl> writes:
> [..]
>> When I looked into the problem, I found no good way to apply the
>> flexible approach used for integers (with # HOLD etc.) for FP output.
>
> Yes, I am still hoping somebody finds a nice way to let the same
> approach work with FP.

In fact SwiftForth included the rudiments of such a system. It goes
something like this:

: <#. ( F: r1 -- r2 ) FROUND <# ;
: #. ( F: r1 -- r2 ) 10.E F/ FDUP FLOOR FSWAP FOVER F-
10.E F* FROUND F>S [CHAR] 0 + HOLD ;
: #S. ( F: r1 -- r2 ) BEGIN #. FDUP F0= UNTIL ;
: #>. ( F: r -- ) ( c-addr u ) FDROP 0 0 #> ;

Turning it into something useful is another thing. I would rather have
string versions of F. FS. FE. with a decimal places parameter and go
from there. Which is what I did.

>
> Basic problems I have with # based printing is output
> to be in HEX or DECIMAL without changing BASE, and safe
> against THROWs. There is printing with and without a trailing
> space (when appending '.' or ','), and left/right aligning of possibly
> negative numbers (print BL where a '+' is expected). And o yeah, every
> one of these words should give a string result that can be further processed
> with other string words. ( BTW, I use I/O device redirection to memory for TYPE
> and friends for that.)
>
>> I also inspected what C does with printf(), and eventually settled on
>> F.RDP. Here's the documentation:
>>
>> |'f.rdp' ( rf +nr +nd +np -- ) gforth-0.6 "f.rdp"
>
> Yes... What to do if printing in HEX, ligning up decimal points in a column
> of +/- numbers, +Infinity -NaN etc. in too short fields, interchange
> ',' and '.', interchange 'E', 'e', 'd', 'D', print with scaling ( 1.1k instead
> of 1.100e3 ), suppressing/adding trailing space, etc.? Of course
> it is not possible to catch all these (and more) in a single word,
> but is there a collection of words that anticipates all possible
> results?

Most of these things are accomplished with string manipulation. I assume
that's how the C and FORTRAN folks do it. Code for a decimal point aligner
is trivial and has already been posted on this forum.

Marcel Hendrix

unread,
Jan 23, 2023, 6:33:24 AMJan 23
to
On Monday, January 23, 2023 at 1:50:16 AM UTC+1, dxforth wrote:
> On 23/01/2023 12:05 am, Marcel Hendrix wrote:
> > On Sunday, January 22, 2023 at 11:43:13 AM UTC+1, Anton Ertl wrote:
> >> Marcel Hendrix <m...@iae.nl> writes:
> > [..]
> >> When I looked into the problem, I found no good way to apply the
> >> flexible approach used for integers (with # HOLD etc.) for FP output.
[..]
> In fact SwiftForth included the rudiments of such a system. It goes
> something like this:
[..]
> : #. ( F: r1 -- r2 ) 10.E F/ FDUP FLOOR FSWAP FOVER F-
[..]

That is not going to work for extended precision (and maybe not even for double precision).

-marcel

dxforth

unread,
Jan 23, 2023, 7:44:24 AMJan 23
to
Seems to work for me

DX-Forth 4.53 2023-01-01

80387 18-digit floating point (common stack)

Using FORTH.SCR

include sfpout FDP is redefined (FS.) is redefined FS.R is redefined
(FE.) is redefined FE.R is redefined (F.) is redefined F.R is redefined
F. is redefined FS. is redefined FE. is redefined ok
17 places ok
pi cr f.
3.14159265358979324 ok

You can test it for yourself:

http://dxforth.mirrors.minimaltype.com/sfpout.html

Gerry Jackson

unread,
Jan 23, 2023, 10:10:02 AMJan 23
to
On 22/01/2023 18:36, Anton Ertl wrote:
> "minf...@arcor.de" <minf...@arcor.de> writes:
>> Then there is the old head-scratcher caused by the differing formats between
>>> FLOAT REPRESENT and text interpreter ....
>
> The text interpreter supports less than >FLOAT, because it also has to
> recognize things other than floats.
>
> REPRESENT is the other direction. Its interface is modeled on ecvt(),
> with one important feature left away: output length; what is also
> missing is the companion fcvt() (this caused quite a bit of
> complication during the development of F.RDP). In the meantime, the C
> guys decided that ecvt()/fcvt() is not the way to go, and they leave
> it all to sprintf().
>

What's wrong with Forth using sprintf apart from its C provenance and
taking quite a lot of Forth code for FP which is irrelevant to those
using a desktop PC and who lack a visceral hatred of C. I can see it
wouldn't be attractive to the embedded community but do they use FP much?

--
Gerry

dxforth

unread,
Jan 23, 2023, 10:54:04 AMJan 23
to
Visceral hatred of bloat. C likes to roll everything into one function;
whereas Forth opts to separate them. See Starting FORTH 1st ed. p.312



Gerry Jackson

unread,
Jan 23, 2023, 12:59:09 PMJan 23
to
That book was written 42 years ago in 1981 when there were severe
hardware limitations such as:
- slow processors
- tiny amount of RAM
- expensive floppy & hard disks with sod-all capacity
- unaffordable hard disks with
- ...

Surely what constitutes bloat has changed since then.

Anyway that cartoon is a silly comparison - sprintf is one tool for
formatting text, not several totally different tools.

--
Gerry

Anton Ertl

unread,
Jan 23, 2023, 5:07:59 PMJan 23
to
Gerry Jackson <do-no...@swldwa.uk> writes:
>What's wrong with Forth using sprintf apart from its C provenance and
>taking quite a lot of Forth code for FP which is irrelevant to those
>using a desktop PC

Not for those who would have to write that code.

And even using it poses problems:

* It consumes a variable number of arguments, something relatively
unusual in Forth; and these arguments are a mix of integer and FP
numbers in arbitrary order, which exacerbates the problem.

* It has a very complicated and not very intuitive interface (e.g.,
see https://pubs.opengroup.org/onlinepubs/7908799/xsh/fprintf.html),
so it's not particularly attractive to use.

* And it still cannot do all the things that Marcel Hendrix asked for.

dxforth

unread,
Jan 23, 2023, 8:00:12 PMJan 23
to
sprintf is but an API to a range of functions. Forth believes it can dispense
with API's, program the functions directly and save code in the process. I'm
sure sprintf would be nostalgia for some. To me it just looks complicated.



dxforth

unread,
Jan 23, 2023, 8:33:28 PMJan 23
to
On 24/01/2023 8:57 am, Anton Ertl wrote:
> Gerry Jackson <do-no...@swldwa.uk> writes:
>> What's wrong with Forth using sprintf apart from its C provenance and
>> taking quite a lot of Forth code for FP which is irrelevant to those
>> using a desktop PC
>
> Not for those who would have to write that code.
>
> And even using it poses problems:
>
> * It consumes a variable number of arguments, something relatively
> unusual in Forth; and these arguments are a mix of integer and FP
> numbers in arbitrary order, which exacerbates the problem.
>
> * It has a very complicated and not very intuitive interface (e.g.,
> see https://pubs.opengroup.org/onlinepubs/7908799/xsh/fprintf.html),
> so it's not particularly attractive to use.
>
> * And it still cannot do all the things that Marcel Hendrix asked for.

A forther believes only he can do something justice. So even when
one demonstrates to Marcel there are other - perhaps better - ways
of approaching the problem, it is water off a duck's back. We can
do this in Forth because we know the world is not looking on and
consequently no pressure to change.

Gerry Jackson

unread,
Jan 24, 2023, 7:23:35 AMJan 24
to
On 23/01/2023 21:57, Anton Ertl wrote:
> Gerry Jackson <do-no...@swldwa.uk> writes:
>> What's wrong with Forth using sprintf apart from its C provenance and
>> taking quite a lot of Forth code for FP which is irrelevant to those
>> using a desktop PC
>
> Not for those who would have to write that code.

Once written, which it has been, it can be used by all were it not that
Forthers, in general, don't like using code written by others!

BTW thanks for a factual reply. Much better than snarky responses from
others.

>
> And even using it poses problems:

I don't why it need pose a problem for users. All that has to be
provided to sprintf is:
( arg1 arg2 ... argn caddr u -- caddr2 u2 ) where (caddr u) is the
format control string and (caddr2 u2) is the result in the current
output buffer. Args1 to n are any mix of integers, FP, strings and
characters in the left to right order they occur in the control string.

>
> * It consumes a variable number of arguments, something relatively
> unusual in Forth;

That presents a challenge to an implementer and makes it more
interesting. The number of arguments and their type is calculated when
the format string is processed. The order in which they appear can be
handled either by using a deep PICK sanitised by using DEPTH or, as
SwiftForth does, by recursion.

> and these arguments are a mix of integer and FP
> numbers in arbitrary order, which exacerbates the problem.

Makes it even more interesting. Don't forget double integers and the
fact that FP numbers can be on the data stack or a separate stack. On
the data stack that would be handled during control string processing.
On a separate stack is more difficult as standard Forth lacks FPICK,
FDEPTH, F>R etc but can be handled by copying the number of FP numbers
into a FP array and accessing that array.

>
> * It has a very complicated and not very intuitive interface (e.g.,
> see https://pubs.opengroup.org/onlinepubs/7908799/xsh/fprintf.html),
> so it's not particularly attractive to use.

People seem to manage and other languages have adopted the approach.

>
> * And it still cannot do all the things that Marcel Hendrix asked for.

Forth is distributed as source code and someone with Marcel's skills
could, if he thought it worth the effort, add the extra functionality.

Loooking at Marcel's list:

<Marcel>
Basic problems I have with # based printing is output
to be in HEX or DECIMAL without changing BASE, and safe
against THROWs. There is printing with and without a trailing
space (when appending '.' or ','), and left/right aligning of possibly
negative numbers (print BL where a '+' is expected). And o yeah, every
one of these words should give a string result that can be further processed
with other string words. ( BTW, I use I/O device redirection to memory
for TYPE
and friends for that.)

Yes... What to do if printing in HEX, ligning up decimal points in a column
of ± numbers, +Infinity -NaN etc. in too short fields, interchange
',' and '.', interchange 'E', 'e', 'd', 'D', print with scaling ( 1.1k
instead
of 1.100e3 ), suppressing/adding trailing space, etc.? Of course
it is not possible to catch all these (and more) in a single word,
but is there a collection of words that anticipates all possible
results?
</Marcel>

- Hex & Decimal - Can be done with sprintf without changing BASE.
- THROW safe - execute sprintf via CATCH
- trailing spaces with commas etc - OK with sprintf
- left/right aligning with negative numbers - OK
- BL for a + sign - OK
- string result - OK
- lining up decimal points in too short fields - not in sprintf, but
surely a user problem
- 'E' or 'e' etc - OK
- print with scaling - No
- adding trailing space - OK, either left justified or include spaces in
the control string

Not much there that can't be done with sprintf.

It's worth noting that after starting to tidy up my sprintf I thought
that there must be a better way to do it and came up with a layered scheme.

Layer 0; a buffer providing basic saving of strings with full buffer
overflow checking, multiple buffers. A greatly extended
equivalent of Forth's <# etc. I've used <~ etc instead of <#

Layer 1: uses layer 0, basic operators to format numbers and text e.g.
~i ~u ~id ~ud etc for signed and unsigned (double) integer
conversions
~w for field width. Positive/negative argument for right/left
alignment
~uc ~lc for upper/lower case
~s ~c for strings, characters

Layer 2: basic integer sprintf, calls lower layers. Provides layer 1
functionality with a sprintf control string. Layer 1 operators
can be mixed with sprintf. An addition is that the code
generated by sprintf can be compiled as a colon definition.

Layer 3: full functionality of integer sprintf. Uses lower layers.

Layers 4 and 5 (proposed but not yet implemented), basic and full
sprintf functionality respepctively. Floating point conversions
will probably be done by treating the components of a floating
point numbers as a series of integer and character fields and
calling layer 1 operators.

Layers 0 to 3 are complete, the rest is on the back burner at present.
With such a scheme it should be easy to add extra functionality such as
that on Marcel's list.

With such a scheme a user can compile the as much functionality as
needed, reducung unnecessary bloat.

--
Gerry

none albert

unread,
Jan 24, 2023, 7:27:27 AMJan 24
to
In article <2023Jan2...@mips.complang.tuwien.ac.at>,
Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
>Gerry Jackson <do-no...@swldwa.uk> writes:
>>What's wrong with Forth using sprintf apart from its C provenance and
>>taking quite a lot of Forth code for FP which is irrelevant to those
>>using a desktop PC
>
>Not for those who would have to write that code.
>
>And even using it poses problems:
>
>* It consumes a variable number of arguments, something relatively
>unusual in Forth; and these arguments are a mix of integer and FP
>numbers in arbitrary order, which exacerbates the problem.
>
>* It has a very complicated and not very intuitive interface (e.g.,
> see https://pubs.opengroup.org/onlinepubs/7908799/xsh/fprintf.html),
> so it's not particularly attractive to use.
>
>* And it still cannot do all the things that Marcel Hendrix asked for.

We can do much better than sprintf seen all the facilities the
Forth interpreter delivers. It will be easier and more flexible.

1. have a wordlist with formatting words.
2. In formatting copy the first characters up till % to the output
3. Separate a word after the % till a blank, look it up in the formatting
wordlist and execute it, presumably adding output to the buffer.
4. rinse, repeat till the formatting string is exhausted.

We will collect the output in a buffer CR$
In the wordlist we will have e.g.
: s ( sc -- ) CR$ $+! ;
: d ( d -- ) S>D 0 (D.R) CR$ $+! ;
..

And analysing the string is trivial:
\ Format the first part of STRING, up till %, leave REST.
\ Another glorious usage of $/ ("string-split")
: _plain &% $/ CRS$ $+! ;

Example of usage
x @ "x" "The value of %s is %d" FORMAT TYPE
Useful additions .FORMAT FORMAT&EVAL

MPE has a similar type of mechanism.

The source of class / endclass in ciforth is down to one screen thanks
to 4 uses of FORMAT&EVAL . Moreover it is much easier to understand.

I haven't done so, but it is easy to add some
floating point format's, in as far needed.
Add the fp format's that c lacks!
(because they forgot to add the kitchen sink.)

>- anton

Marcel Hendrix

unread,
Jan 24, 2023, 10:12:01 AMJan 24
to
On Tuesday, January 24, 2023 at 1:27:27 PM UTC+1, none albert wrote:
> In article <2023Jan2...@mips.complang.tuwien.ac.at>,
> Anton Ertl <an...@mips.complang.tuwien.ac.at> wrote:
> >Gerry Jackson <do-no...@swldwa.uk> writes:
[..]
> Example of usage
> x @ "x" "The value of %s is %d" FORMAT TYPE

x @ S" x" .( The value of ) TYPE .( is ) .

It does not (yet) solve the basic problem of ".".
Gerry's approach looks much better.

I think "printf" adds an interpreter to a compiler. That is not
necessary in Forth, we already have (a much more capable) one.

-marcel

Paul Rubin

unread,
Jan 24, 2023, 6:23:02 PMJan 24
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> And even using [sprintf] poses problems: ...

I don't remember how Fortran numeric formatting worked, but it was/is
used extensively for scientific computing, so I'd like to hope that it
had the issues ironed out after all these years. Is it worth examining
for this thread?

dxforth

unread,
Jan 25, 2023, 12:34:51 AMJan 25
to
On 24/01/2023 11:27 pm, albert wrote:
>
> I haven't done so, but it is easy to add some
> floating point format's, in as far needed.
> Add the fp format's that c lacks!
> (because they forgot to add the kitchen sink.)

Classic forth response :)


dxforth

unread,
Jan 25, 2023, 12:41:42 AMJan 25
to
On 25/01/2023 2:12 am, Marcel Hendrix wrote:
>
> It does not (yet) solve the basic problem of ".".

What problem was that exactly?


dxforth

unread,
Jan 25, 2023, 1:33:38 AMJan 25
to
What's wrong with the format Forth has used in the past? I refer to Forth
Vendors Group F/P Standard and the floating point output package used in
Amiga J-Forth. These may not have been the last word on the subject but
they pointed the way and were 'forth friendly'. In fact an early draft of
ANS included the words (F.) (E.) PLACES before the devil whispered in the
TC's ear.

minf...@arcor.de

unread,
Jan 25, 2023, 4:58:39 AMJan 25
to