AFAICS the statement in Section 9.3.5
"A system choosing to execute THROW when detecting one of the ambiguous
conditions listed in table 9.2 shall use the throw code listed there."
effectively rules out the traditional use of ABORT" to convey the ambiguous >conditions listed in the table. Is that how others read it?
Early on DX-Forth it became apparent that maintaining a list of error >messages accessible by means of a THROW code was going to be messy and
worse - costly. I wanted CATCH THROW but could do without the vision
ANS appeared to have in mind for it. The consequence of retaining
ABORT" for classic ambiguous conditions means I can't individually
identify them at CATCH but I've yet to find this a problem.
I'm curious whether others found ANS' requirement above 'a step too far'?
dxf <dxforth@gmail.com> writes:
AFAICS the statement in Section 9.3.5
"A system choosing to execute THROW when detecting one of the ambiguous
conditions listed in table 9.2 shall use the throw code listed there."
effectively rules out the traditional use of ABORT" to convey the ambiguous >>conditions listed in the table. Is that how others read it?
Given that the standard states elsewhere that there is no guarantee of
any system behaviour at all in case of an ambiguous condition, this
statement and its use of "shall" is strange.
Let's see what the existing practice is. I try the following on
various Forth systems:
s" include xxxxxxxx.fs" ' evaluate catch .
s" include /tmp/x.fs" ' evaluate catch .
where xxxxxxxx.fs does not exist, and /tmp/x.fs exists but the
permissions are such that you cannot open it for reading.
What I get on various Forth systems running on Linux is:
xxxxxxxx.fs /tmp/x.fs
-514 -525 Gforth
-37 -37 iforth 5.1-mini
-261 -261 lxf 1.7-172-983
-199 -199 SwiftForth i386-Linux 3.11.0
-69 -69 SwiftForth x64-Linux 4.0.0-RC89
-258 -258 VFX Forth 64 5.43
So out of these five systems, only two use values from the table, and
these two use different throw codes. Only one uses a throw code from
the original 50 that Mitch Bradley had in mind when creating the
table.
It's unclear how these ambiguous conditions should be mapped to the
throw codes.
In any case, -38 is the best match for the xxxxxxxx.fs case, and among
the first 50, -37 is the best match for the /tmp/x.fs case; with the
addition of -69 in Forth-2012, -69 is also a contender; however, the
throw codes -59..-76 were intended for explicit throws of iors, not
for ambiguous conditions (neither the proponent of that addition nor
the committee ever discussed the chapter where the table is defined).
It probably is not a problem, but your claim of a high cost seems
curious. It seems to me that
open-file throw
is cheaper than
open-file abort" OPEN-FILE failed in INCLUDED"
I don't think that the resulting throw codes are checked in any
programs, but I expect that the users find the error messages (when
the system catches the exception) helpful; I certainly do.
- anton
In article <2025May31.080248@mips.complang.tuwien.ac.at>,
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
xxxxxxxx.fs /tmp/x.fs
-514 -525 Gforth
-37 -37 iforth 5.1-mini
-261 -261 lxf 1.7-172-983
-199 -199 SwiftForth i386-Linux 3.11.0
-69 -69 SwiftForth x64-Linux 4.0.0-RC89
-258 -258 VFX Forth 64 5.43
-2 -13 ciforth on (whatever) linux
-13 MESSAGE
: Permission denied
OK
-2 MESSAGE
: No such file or directory
OK
Am I the only to use the Unix error codes?
albert@spenarnc.xs4all.nl writes:
In article <2025May31.080248@mips.complang.tuwien.ac.at>,
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
xxxxxxxx.fs /tmp/x.fs
-514 -525 Gforth
-37 -37 iforth 5.1-mini
-261 -261 lxf 1.7-172-983
-199 -199 SwiftForth i386-Linux 3.11.0
-69 -69 SwiftForth x64-Linux 4.0.0-RC89
-258 -258 VFX Forth 64 5.43
-2 -13 ciforth on (whatever) linux
-13 MESSAGE
: Permission denied
OK
-2 MESSAGE
: No such file or directory
OK
Am I the only to use the Unix error codes?
You seem to be the only one who remaps them by just negating them.
This remaps them right into the range of throw codes that are
preassigned by the Forth standard in table 9.1.
If you look at the results above, you will find that Gforth remaps
errno into the ior -512-errno (e.g., -514 for "No such file or
directory, and -525 for "permission denied"), and INCLUDED THROWs that
ior.
For Unix signals, if Gforth does not translate them to one of the
predefined throw codes or handles the signal in some other way (e.g., >SIGWINCH just changes what FORM returns, and is otherwise
transparent), it throws -256-sig.
- anton
Actually, the error returns from system calls are negative
numbers. So I do approximately:
( open file ) DUP 0 MIN THROW \ Now the result is a file channel id.
So I was puzzled at the term remapping. Indeed the man 3 errno
reveals that positive numbers are intended.
This discussion proves that adhering to
the exact throw cause is of dubious value.
albert@spenarnc.xs4all.nl writes:
Actually, the error returns from system calls are negative
numbers. So I do approximately:
( open file ) DUP 0 MIN THROW \ Now the result is a file channel id. >>So I was puzzled at the term remapping. Indeed the man 3 errno
reveals that positive numbers are intended.
It depends on the architecture how an error from a system call is
indicated; on some architectures the result is only returned in one
register, on some it's a register and a flag (IIRC the carry flag).
In the latter case a set flag indicates that the register contains an
error code, while a clear flag indicates that there was no error and
the register contains the result.
If there is only one register, you have to find out it the result is a >success or an error. Many system calls are designed to produce a
positive result (e.g., write() or read()), and using the negative
number range for error results is the solution for that; that's why
you are seeing the negated errno.
It becomes tricky to do system calls like sbrk() and mmap() that
return addresses, because in principle any bit pattern can be an
address. But originally Unix and Linux reserved the high half of
address space for the system, so these system calls, which return
user-level addresses, could only return addresses where the MSB is
clear. Towards the end of the 32-bit era, user space could reach up
to 3GB, so just checking the sign was not enough, but there was still
1G of numbers that could be used as error returns.
This discussion proves that adhering to
the exact throw cause is of dubious value.
There is apparently little usage of catching specific throw codes.
E.g., I have never done that.
However, throwing specific codes is a different issue. I have done
so, and I have discussed with other people which existing throw codes
are appropriate for which error. An example is shown in ><2024Apr1.115659@mips.complang.tuwien.ac.at>:
: gen-mask3 ( n -- x )
\ throw if <n>=0
64 swap - dup 64 u< 0= -24 and throw -1 swap lshift ;
Will 0 GEN-MASK3 give the error message "Too many open files" or
"Invalid numeric argument" on ciforth?
- anton--
On 31-05-2025 03:10, dxf wrote:<SNIP>
not a "hard" code. I mean, even in their freshman years CS students are >taught to use enums and constants instead of literals.
Hans Bezemer--
In the early days of microcomputing memory was severely limited and
error codes were used to save space. But how much need today and
what's wrong with ABORT"?
I don't use forth for scripting which might require sending codes and
can't think of an app where I've used codes. Is the ANS list of
error codes aimed at special needs? Because FWIW I'm not feeling any.
In the early days of microcomputing memory was severely limited and error codes
were used to save space.
But how much need today and what's wrong with ABORT"?
I don't use forth for scripting which might require sending codes and can't think
of an app where I've used codes.
On 3/06/2025 5:20 am, Hans Bezemer wrote:BADADR THROW does?
On 02-06-2025 12:44, albert@spenarnc.xs4all.nl wrote:
In article <nnd$5d07338c$61b87fbd@d4d89ef8da41e19e>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
On 31-05-2025 03:10, dxf wrote:<SNIP>
not a "hard" code. I mean, even in their freshman years CS students are >>>> taught to use enums and constants instead of literals.
That is constants that are used more than once with the same meaning.
It is a deadly sin to use throw codes more than once, so this doesn't
apply.
Hans Bezemer
Wrong. It's a way to abstract a numerical literal - so if things happen to change, you don't have to change them everywhere. It's also a way to self-document a program. Any idea what -22 THROW does (without consulting the standard)? Any idea what E.
In the early days of microcomputing memory was severely limited and error codes
were used to save space. But how much need today and what's wrong with ABORT"?
I don't use forth for scripting which might require sending codes and can't think
of an app where I've used codes. Is the ANS list of error codes aimed at special
needs? Because FWIW I'm not feeling any.
On 02-06-2025 12:44, albert@spenarnc.xs4all.nl wrote:
In article <nnd$5d07338c$61b87fbd@d4d89ef8da41e19e>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
On 31-05-2025 03:10, dxf wrote:<SNIP>
not a "hard" code. I mean, even in their freshman years CS students are
taught to use enums and constants instead of literals.
That is constants that are used more than once with the same meaning.
It is a deadly sin to use throw codes more than once, so this doesn't
apply.
Hans Bezemer
Wrong. It's a way to abstract a numerical literal - so if things happen
to change, you don't have to change them everywhere. It's also a way to >self-document a program. Any idea what -22 THROW does (without
consulting the standard)? Any idea what E.BADADR THROW does?
Yesterday, while consulting the ANS error table, I found that with a
little imagination, I could standardize three more errors. Since there
is a table for the codes and one for the error messages, one set in
Forth and one set in C - I had to change four files. Since I'm quite a >disciplined programmer, always using the symbols, that's all I had to
change.
Hans Bezemer--
MS-DOS errors are mapped to 'ior' using $FExx (CHForth trick)
Perhaps the TC went along with Mitch. CATCH THROW was his idea and
here's a bunch of codes to go with it. The extent to which a tiny forth
is going to use ANS is dubious.
On 3/06/2025 4:10 pm, Anton Ertl wrote:
dxf <dxforth@gmail.com> writes:
...
But how much need today and what's wrong with ABORT"?
My guess at the thinking behind the Forth-94 committee's decisions
about that are:
1) ABORT" Undefined word" takes more space than -13 AND THROW. Of
course, if the system then has a table for translating throw codes
to messages, that probably eliminates the memory savings, but a
system that is really tight on memory can just output the error
code and leave it to the user to look the error up in the manual.
2) For CATCH, every ABORT" looks the same, so you cannot do something
for one kind of error and something else for other kinds. Of
course, the question is whether one can do that with the current
situation (apparently not portably for inaccessible or non-existent
files in INCLUDED), and whether that's something that Forth
programmers would make use of if the situation was otherwise.
Perhaps the TC went along with Mitch. CATCH THROW was his idea and
here's a bunch of codes to go with it. The extent to which a tiny forth
is going to use ANS is dubious. Having CATCH THROW just to pass compiler >errors is dubious. Compilers errors could be handled with ABORT" and two >characters (old-time BASIC users may remember).
It was thus said that the Great dxf <dxforth@gmail.com> once stated:
Perhaps the TC went along with Mitch. CATCH THROW was his idea and
here's a bunch of codes to go with it. The extent to which a tiny forth
is going to use ANS is dubious.
What constitutes a "tiny Forth"? Because I just implemented ANS Forth [1]
for the 6809 [2], and I included CATCH and THROW. It's almost 12K in size >and for the wordsets it implements, it passes the ANS Forth test suite. I >implemented the EXCEPTION wordset because it seems a 2017 update mandated >it's use. While I'm not a fan of exceptions, it wasn't hard to implement
and it seemed better thought out than SYNONYM [4].
-spc
[1] I implemented CORE, CORE-EXT, DOUBLE, DOUBLE-EXT, EXCEPTION,
EXCEPTION-EXT, LOCAL, LOCAL-EXT, TOOLS, some of TOOLS-EXT [3],
SEARCH, SEARCH-EXT, STRING and STRING-EXT.
[2] https://github.com/spc476/ANS-Forth
[3] Words implemented from TOOLS-EXT: AHEAD, BYE, CS-PICK, CS_ROLL, N>R,
NAME>COMPILE, NAME>INTERPRET, NAME>STRING, NR>, STATE,
TRAVERSE-WORDLIST, [DEFINED], [ELSE], [IF], [THEN], [UNDEFINED].
[4] When reading about it [5], I decided I didn't want anything to do
with that quagmire of a word.
[5] https://forth-standard.org/standard/tools/SYNONYM
Good work, 12K is justly considered tiny.
[1] I implemented CORE, CORE-EXT, DOUBLE, DOUBLE-EXT, EXCEPTION,
EXCEPTION-EXT, LOCAL, LOCAL-EXT, TOOLS, some of TOOLS-EXT [3],
SEARCH, SEARCH-EXT, STRING and STRING-EXT.
[2] https://github.com/spc476/ANS-Forth
[3] Words implemented from TOOLS-EXT: AHEAD, BYE, CS-PICK, CS_ROLL, N>R, >> NAME>COMPILE, NAME>INTERPRET, NAME>STRING, NR>, STATE,
TRAVERSE-WORDLIST, [DEFINED], [ELSE], [IF], [THEN], [UNDEFINED].
[4] When reading about it [5], I decided I didn't want anything to do
with that quagmire of a word.
[5] https://forth-standard.org/standard/tools/SYNONYM
You have included a lot of words that I considered not needed for
a tiny Forth.
The first time I will ever need CS-PICK I will add it to the library.
It is not eligible for a kernel word.
It was thus said that the Great albert@spenarnc.xs4all.nl once stated:
Good work, 12K is justly considered tiny.
Thank you.
[1] I implemented CORE, CORE-EXT, DOUBLE, DOUBLE-EXT, EXCEPTION,
EXCEPTION-EXT, LOCAL, LOCAL-EXT, TOOLS, some of TOOLS-EXT [3],
SEARCH, SEARCH-EXT, STRING and STRING-EXT.
[2] https://github.com/spc476/ANS-Forth
[3] Words implemented from TOOLS-EXT: AHEAD, BYE, CS-PICK, CS_ROLL, N>R, >>> NAME>COMPILE, NAME>INTERPRET, NAME>STRING, NR>, STATE,
TRAVERSE-WORDLIST, [DEFINED], [ELSE], [IF], [THEN], [UNDEFINED].
[4] When reading about it [5], I decided I didn't want anything to do
with that quagmire of a word.
[5] https://forth-standard.org/standard/tools/SYNONYM
You have included a lot of words that I considered not needed for
a tiny Forth.
Such as? One goal (which kind of went to the wayside as I was writing)
was to use as much of standard Forth as possible to write the code (and less >to implement in assembly), thus the inclusion of AHEAD, CS-ROLL, etc. But >once I past 8K with pretty much CORE, CORE-EXT, SEARCH, SEARCH-EXT and the >ones I was using from TOOLS-EXT, I had past 8K, so I decided I might as well >include DOUBLE, DOUBLE-EXT, STRING, STRING-EXT, LOCAL and LOCAL-EXT. At
that point, I might as well make a Forth that was useful for as many people >as possible, while not locking it into a particular system. That's why I >didn't bother with BLOCK, BLOCK-EXT, FACILITY or FACILITY-EXT (leaving that >for the others to write for their system).
The first time I will ever need CS-PICK I will add it to the library.
It is not eligible for a kernel word.
I wasn't sure if it was needed or not. It just falls pack to PICK anyway.
-spc
In article <101u12p$23a54$1@dont-email.me>, <sean@conman.org> wrote:
Such as? One goal (which kind of went to the wayside as I was writing)
was to use as much of standard Forth as possible to write the code (and less >to implement in assembly), thus the inclusion of AHEAD, CS-ROLL, etc. But >once I past 8K with pretty much CORE, CORE-EXT, SEARCH, SEARCH-EXT and the >ones I was using from TOOLS-EXT, I had past 8K, so I decided I might as well >include DOUBLE, DOUBLE-EXT, STRING, STRING-EXT, LOCAL and LOCAL-EXT. At >that point, I might as well make a Forth that was useful for as many people >as possible, while not locking it into a particular system. That's why I >didn't bother with BLOCK, BLOCK-EXT, FACILITY or FACILITY-EXT (leaving that >for the others to write for their system).
Adding more wordsets is not making it useful for as many people as possible. Leaving out the FACILTY wordset ( SEE DUMP WORDS LOCATE) make a system virtually unusable.
Using BLOCKS to store all words that belong in a library, that I found extremely
useful. ( WANT ).
Adding D2/ D2* D2> 2VARIABLE is in bad taste. They clutter up the output of WORDS. Try WORDS in gforth. Can you even check D2* is in there?
Of course traditional formatting words require certain DOUBLE words.
NUMBER >IN >BODY > = <# < ; : 2SWAP 2OVER 2DUP 2DROP 2@ 2/ 2* 2! 1- 1+ 0=0< /MOD / ." . - , +LOOP +! + */MOD */ * ( ' #S #> # !
I wasn't sure if it was needed or not. It just falls pack to PICK anyway.
You can be sure if you needs it, if you use your forth to program, not?
On 7/06/2025 7:06 am, sean@conman.org wrote:
...
A goal of my Forth system was to only have standard Forth words.
You trust the Standard. Why?
The Standard dates backs to 1977 starting out as
a list of words pulled from Kitt Peak Forth. If KPF didn't have (.) etc well that was just too bad. The point being nobody sat down and systematically designed the standard (or forth) ground up. It was adhoc. It's always been adhoc. Moore has changed his mind numerous times. What one sees in the Standard
is a snapshot of 1977.
Even small forths can do better than what the standard offers by simply factoring
out tools already present e.g.
(.) (D.) (U.) /CHAR >CHAR >DIGIT HELD MU* MU/MOD TRIM UNNEST
I'd rather have these than all the support for wordlists DEFER and other stuff
the standard and folks have obsessed over.
Why not? This was a learning experience for me, as this is my first
actual Forth implementation [1]. The ANS Forth 2012 standard gave me a >target to aim for. Guess I shouldn't have bothered then.
The Standard dates backs to 1977 starting out as
a list of words pulled from Kitt Peak Forth. If KPF didn't have (.) etc well
that was just too bad. The point being nobody sat down and systematically >> designed the standard (or forth) ground up. It was adhoc. It's always been >> adhoc. Moore has changed his mind numerous times. What one sees in the Standard
is a snapshot of 1977.
It seems to have concepts that have occured after 1977, or are you
speaking of some other Forth Standard, like 79 or 83?
Even small forths can do better than what the standard offers by simply factoring
out tools already present e.g.
(.) (D.) (U.) /CHAR >CHAR >DIGIT HELD MU* MU/MOD TRIM UNNEST
I'd rather have these than all the support for wordlists DEFER and other stuff
the standard and folks have obsessed over.
Can you not implement them with ANS Forth?
For (.) (D.) (U.) that's certainly not the case in Gforth.I said the Standard hadn't factored them out. Several forths of course
have factored them out.
As for /CHAR >CHAR >DIGIT HELD MU* MU/MOD TRIM UNNEST
dxf <dxforth@gmail.com> writes:
For (.) (D.) (U.) that's certainly not the case in Gforth.I said the Standard hadn't factored them out. Several forths of course
have factored them out.
Well I think you were saying the standard SHOULD have factored them out, >presumably because they are both useful to users, and reasonably
necessary parts of the underlying implementation that could have been >exported, as opposed to just giving more clutter for implementers to
supply.
So now I have to also wonder what they do and what they are good for.
As for /CHAR >CHAR >DIGIT HELD MU* MU/MOD TRIM UNNEST
Same for these. I can sort of guess at a few.
: (.) 0 <# #S #> ;
In article <87plff4938.fsf@nightsong.com>,
Paul Rubin <no.email@nospam.invalid> wrote:
dxf <dxforth@gmail.com> writes:
For (.) (D.) (U.) that's certainly not the case in Gforth.I said the Standard hadn't factored them out. Several forths of course
have factored them out.
Well I think you were saying the standard SHOULD have factored them out, >>presumably because they are both useful to users, and reasonably
necessary parts of the underlying implementation that could have been >>exported, as opposed to just giving more clutter for implementers to >>supply.
It is occasionally useful to have conversions to a string that
not immediately prints. Even figforth had a (D.R) that was a
D.R without the type.
But thanks to the #-set a conversion is very short :
: (.) 0 <# #S #> ;
I tend to define such word in the application , otherwise you end up
adding (.) (U.) (D.) (UD.) (D.R) to the standard.
I wonder if there's a standard or well known way to capture the output
of . and related words, like redirecting the input stream.
albert@spenarnc.xs4all.nl writes:
: (.) 0 <# #S #> ;
I see, it converts a number to a string. I guess if you have <# #S #>
then that is easy enough. Otherwise it depends on how . is implemented.
I wonder if there's a standard or well known way to capture the output
of . and related words, like redirecting the input stream.
albert@spenarnc.xs4all.nl writes:
It is occasionally useful to have conversions to a string that
not immediately prints. Even figforth had a (D.R) that was a
D.R without the type.
It's not in the fig-Forth Installation Manual / Glossary / Model Release !
http://wiki.yak.net/1089/fig-FORTH_Manuals_May79.pdf
nor in the source code.
https://raw.githubusercontent.com/ForthHub/FIG-Forth/refs/heads/master/fig.fth
- anton--
On 8/06/2025 9:51 pm, albert@spenarnc.xs4all.nl wrote:
In article <2025Jun8.095626@mips.complang.tuwien.ac.at>,
Anton Ertl <anton@mips.complang.tuwien.ac.at> wrote:
albert@spenarnc.xs4all.nl writes:
It is occasionally useful to have conversions to a string that
not immediately prints. Even figforth had a (D.R) that was a
D.R without the type.
It's not in the fig-Forth Installation Manual / Glossary / Model Release ! >>>
http://wiki.yak.net/1089/fig-FORTH_Manuals_May79.pdf
nor in the source code.
https://raw.githubusercontent.com/ForthHub/FIG-Forth/refs/heads/master/fig.fth
I should have known better.
https://home.hccnet.nl/a.w.m.van.der.horst/figdoc.zip
I remembered the way D. was reduced in the code to
D.R and confused the two mechanisms.
It's probably easier to justify (D.) than (D.R). If one needs to right-justify
numbers, chances are one will need to right-justify non-numeric strings as well.
For this reason I have S.R in the kernel and (S.R) as a library function.
Probably there is, revectoring EMIT and forcing the Forth to work
with single characters. Anton Ertl can show how it is done with
gforth.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 502 |
Nodes: | 16 (2 / 14) |
Uptime: | 218:28:18 |
Calls: | 9,878 |
Calls today: | 6 |
Files: | 13,791 |
Messages: | 6,205,847 |