Replies: 12 comments 23 replies
-
No, since : oops -1234 throw ;: foo oops ;: bar foo ;foo and bar don’t throw but executing them will get you a throw. Sent from my iPhoneOn 6 Sep 2024, at 17:36, Anthony Howe ***@***.***> wrote:
I'm curious what the convention is, should words document in some fashion that they THROW? Not necessarily every possible code, maybe just document the non-standard ones. Maybe a summary as part of the stack description, eg. WRITE-FILE ( caddr u fd -- ior T) or foo ( i*x -- j*x )(T: 1, 2, 3).
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
The standard stack notation says nothing about I think we could introduce a notation for cases where control is intentionally not transferred to the point just after the word. Personally, I already use such a notation. Bottom typeIn theory, there exists a notion of bottom type, as Wikipedia says:
Bottom type in the stack notationThe bottom type can be employed in the stack notation to describe a case when a Forth definition (or its some semantics) does not return control to the caller, or control is not transferred to a point just after the point where the corresponding semantics are performed. Note that under some conditions any Forth word might not return control. For example, if the user presses Ctrl+C, control may be transferred to the nearest Also, we should not describe behavior under ambiguous conditions. For example, if an input stack parameter for some word has an incorrect type — it's an ambiguous condition. If the system throws an exception and some caller will not get control back — we should not document this. We should describe only the cases when a Forth definition intentionally does not return control to the caller. For example:
A user-defined word: : ?exit ( run-time: 0 -- | S: x\0 -- ⊥ R: nest-sys -- )
postpone if postpone exit postpone then
; immediate NB: |
Beta Was this translation helpful? Give feedback.
-
Hmmm. Not a big fan of this proposal.
Never is related to time, not to an action. As in, it will never happen. He was never there. There is never a good reason to procrastinate.
I struggle to understand what noreturn means. A coroutine? And goodness knows what bottom might imply.
What value does this stack-based documentation bring?
—
Alex
From: ruv ***@***.***>
Sent: Wednesday, September 11, 2024 12:11 PM
To: ForthHub/discussion ***@***.***>
Cc: Alex McDonald ***@***.***>; Comment ***@***.***>
Subject: Re: [ForthHub/discussion] Should stack descriptions document `THROW`? (Discussion #170)
use of up tack ( ⊥ ) U+22A5 [...] is painful to type
Agreed. There can be an alternative name like bottom, noreturn, never. The variant noreturn is confusing for run-time semantics that cannot be called. I would prefer never.
\ DataType: nz = x\0
\ throw ( 0 -- | S: i*x nz -- never R: j*x -- )
\ while ( runtime: nz -- | 0 -- never )
\ exit ( runtime: S: -- never R: nest-sys -- )
The standard stack notation does not allow to indicate several stacks in one diagram. But this is required in some cases.
—
Reply to this email directly, view it on GitHub <#170 (reply in thread)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAOB6OWQX2PJJSVXF335R5LZWAQLTAVCNFSM6AAAAABNY5JNP6VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTANRRGMZDGMI> .
You are receiving this because you commented. <https://github.com/notifications/beacon/AAOB6OTMWCK5IBXPATHPSRLZWAQLTA5CNFSM6AAAAABNY5JNP6WGG33NNVSW45C7OR4XAZNRIRUXGY3VONZWS33OINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAUHY66.gif> Message ID: ***@***.*** ***@***.***> >
|
Beta Was this translation helpful? Give feedback.
-
I understand that. But the result of executing a THROW is not a type. The result is that “the stack depth is the same as it was just before CATCH <https://forth-standard.org/standard/exception/CATCH> began execution. The values of the i * x stack arguments could have been modified arbitrarily during the execution of xt.”
—
Alex
From: Anthony Howe ***@***.***>
Sent: Wednesday, September 11, 2024 5:37 PM
To: ForthHub/discussion ***@***.***>
Cc: Alex McDonald ***@***.***>; Comment ***@***.***>
Subject: Re: [ForthHub/discussion] Should stack descriptions document `THROW`? (Discussion #170)
Granted the word forms are no clearer than ⊥. Bottom type, other than the poor name, clearly has a purpose in Type Theory.
From Wikipedia Bottom Type <https://en.wikipedia.org/wiki/Bottom_type> :
In such a language, the bottom type may therefore be known as the zero, never or empty type <https://en.wikipedia.org/wiki/Empty_type> ...
—
Reply to this email directly, view it on GitHub <#170 (reply in thread)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAOB6ORTRUG2IFKHWKZJQGDZWBWT3AVCNFSM6AAAAABNY5JNP6VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTANRRGY3TINQ> .
You are receiving this because you commented. <https://github.com/notifications/beacon/AAOB6OUZHQO47BO7OHS2E7TZWBWT3A5CNFSM6AAAAABNY5JNP6WGG33NNVSW45C7OR4XAZNRIRUXGY3VONZWS33OINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAUH72U.gif> Message ID: ***@***.*** ***@***.***> >
|
Beta Was this translation helpful? Give feedback.
-
It may be that the top i*x entries may have arbitrarily been modified on execution of CATCH , and there may be other disturbances to the system’s total state, but the stack is not in an unknown state. The standard clearly states that the stack depth is deterministic, and is at the same depth as on execution of CATCH.It might be better to document (in a glossary entry?) the other effects to the system’s state if words may THROW. We understand exactly what happens to the stack on a THROW. Some year’s ago THROW was clarified (at least, modified) to address at least one of those changes of state issues by requiring the input sources to be restored to their pre-CATCH state.
Interestingly, iirc the only word that THROWs in the whole spec is ABORT. Not even 0 0 / does that.
—
Alex
From: Anthony Howe ***@***.***>
Sent: Wednesday, September 11, 2024 5:52 PM
To: ForthHub/discussion ***@***.***>
Cc: Alex McDonald ***@***.***>; Comment ***@***.***>
Subject: Re: [ForthHub/discussion] Should stack descriptions document `THROW`? (Discussion #170)
Bottom Type <https://en.wikipedia.org/wiki/Bottom_type> obviously the opposite of Top Type ( T ) for "all types". The list of used types in Table 3.1 Data Types has no represent for "no type" aka "bottom type". I see where @ruv <https://github.com/ruv> is going with this and it makes sense to describe the case when a word leaves the stack in some unknown state.
—
Reply to this email directly, view it on GitHub <#170 (reply in thread)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAOB6OWWWG5EP7UJY3KN22DZWBYJHAVCNFSM6AAAAABNY5JNP6VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTANRRGY4TGNY> .
You are receiving this because you commented. <https://github.com/notifications/beacon/AAOB6OWCBQNDOI73YTPQHD3ZWBYJHA5CNFSM6AAAAABNY5JNP6WGG33NNVSW45C7OR4XAZNRIRUXGY3VONZWS33OINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAUIAGS.gif> Message ID: ***@***.*** ***@***.***> >
|
Beta Was this translation helpful? Give feedback.
-
Because the program cannot check what is the stack depth after THROW on a nonzero parameter. The program only can check the stack depth after CATCH. Because THROW never returns control to the caller if its argument is a nonzero..
Then the program will eventually get to ABORT then QUIT, and we know what the stack looks like there.
I’m still unsure what problem you’re proposing to fix here. This is documentation (which is good) in the stack diagram (which is not the right place for it).
—
Alex
From: ruv ***@***.***>
Sent: Wednesday, September 11, 2024 6:05 PM
To: ForthHub/discussion ***@***.***>
Cc: Alex McDonald ***@***.***>; Mention ***@***.***>
Subject: Re: [ForthHub/discussion] Should stack descriptions document `THROW`? (Discussion #170)
@alextangent <https://github.com/alextangent> wrote:
But the result of executing a THROW is not a type.
Well, there is no a word at all whose execution result is a type.
The result is that “the stack depth is the same as it was just before CATCH began execution.
From a program point of view, this is the result of CATCH. Because the program cannot check what is the stack depth after THROW on a nonzero parameter. The program only can check the stack depth after CATCH. Because THROW never returns control to the caller if its argument is a nonzero.
—
Reply to this email directly, view it on GitHub <#170 (reply in thread)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAOB6OSN3KOLKSDBWRXWOLLZWBZ2XAVCNFSM6AAAAABNY5JNP6VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTANRRG4YDQMY> .
You are receiving this because you were mentioned. <https://github.com/notifications/beacon/AAOB6OU6DD2FRXL25UWHO53ZWBZ2XA5CNFSM6AAAAABNY5JNP6WGG33NNVSW45C7OR4XAZNRIRUXGY3VONZWS33OINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAUIAPW.gif> Message ID: ***@***.*** ***@***.***> >
|
Beta Was this translation helpful? Give feedback.
-
A slightly longer reply.
The stack documentation has always had a semi-formal status. Enclosed in a comment ( ) it is not required to be parsed. This is unlikely to change, since there are a significant body of existing programs where there are either no stack comments at all, or their contents are irregular and not amenable to consistent parsing. Much code has stack comments like ( a b | c ). Even so, over the years stack comments have become more widely accepted, and more regularly used. There are a number of formalisms that have also been adopted; notably an attempt at typing (n x xt nt and so on) and the use of | to indicate the state of the stack on entry to the left, and the state of the stack on exit to the right. Prefixes have been introduced; F: R: C: for example to indicate other than the data stack. These are all fine and noble attempts to document the system’s stack effects *in the standard* so that standard words can have their stack effects correctly described. Which they all do; and there have been discussions over the years to tighten up on those types to be more consistent and less ambiguous.
My objections are:
* This proposal is not about the stack. It’s about the expected execution or run time behaviour. This is most un-stack-like information.
* This will be a formal attempt to document the return action (not stack effect) of words *in the standard*
* There is exactly one word that would require this new documentation in the standard; THROW.
* THROW and CATCH already describe the state of the stack.
* You keep saying that the stack is in an unknown state. It’s not. The state of the stack is deterministic and well defined.
IMHO, no special word in the stack diagram is required to be documented in the standard. This is a word for a Forth best practices document.
—
Alex
From: ruv ***@***.***>
Sent: Wednesday, September 11, 2024 5:50 PM
To: ForthHub/discussion ***@***.***>
Cc: Alex McDonald ***@***.***>; Comment ***@***.***>
Subject: Re: [ForthHub/discussion] Should stack descriptions document `THROW`? (Discussion #170)
What value does this stack-based documentation bring?
It allows us to better understand the behavior of a word without its text description. Namely, the bottom data type in a stack diagram shows that on some input parameters control is never transferred to the point just after this word, or, the caller of the word never get control back.
For example:
\ ['] ( "<spaces>name" -- xt | ⊥ )
\ ['] ( "<spaces>name" -- xt | never )
The variants: "bottom", "never", "noreturn" — are examples from other programming languages.
See: https://en.wikipedia.org/wiki/Bottom_type#In_programming_languages
Perhaps you can suggest a better option.
—
Reply to this email directly, view it on GitHub <#170 (reply in thread)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAOB6OVJLTHWVDVQP53ZQGTZWBYDFAVCNFSM6AAAAABNY5JNP6VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTANRRGY4TAMQ> .
You are receiving this because you commented. <https://github.com/notifications/beacon/AAOB6OXNJY5ID7SMHHHXVZ3ZWBYDFA5CNFSM6AAAAABNY5JNP6WGG33NNVSW45C7OR4XAZNRIRUXGY3VONZWS33OINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAUIAEM.gif> Message ID: ***@***.*** ***@***.***> >
|
Beta Was this translation helpful? Give feedback.
-
Yes. Don’t do it. See my next email (which may take me a few days to write; thanks for your patience).
—
Alex
From: ruv ***@***.***>
Sent: Thursday, September 12, 2024 12:02 PM
To: ForthHub/discussion ***@***.***>
Cc: Alex McDonald ***@***.***>; Mention ***@***.***>
Subject: Re: [ForthHub/discussion] Should stack descriptions document `THROW`? (Discussion #170)
In general, "empty type <https://en.wikipedia.org/wiki/Empty_type> " is more appropriate to describe a case when a function does not return control. And the notion of bottom type may be used for that only as far as a bottom type is empty type.
So, from a terminological point of view, it is probably better to talk about an empty type.
In the same time, an empty type should not be confused with the empty tuple of parameters.
The empty tuple of parameters is not a member of an empty type. An empty type has no members at all, by definition (i.e., it is uninhabited).
…_____
I would like to choose a short name for an empty type in the Forth type system. The up tack ( ⊥ ) is good, but we need a synonym in ASCII that is easy to enter. I dislike ASCII-art glyph _|_ for this purpose, because it is close to "|" and "_" that are used (or can be used) separately in a stack diagram, producing worse readability, e.g.: ( 0 -- _|_ | -- nz ) .
The word "empty" does not fit because it is associated with the empty tuple.
The word "unreachable" is a possible variant. But I think "never" is better, because it's shorter.
Please let me know if you have some arguments or better options.
—
Reply to this email directly, view it on GitHub <#170 (reply in thread)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAOB6OSSJBWBG3KZPLAGBPDZWFYA5AVCNFSM6AAAAABNY5JNP6VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTANRSGQ4TIOA> .
You are receiving this because you were mentioned. <https://github.com/notifications/beacon/AAOB6OT73QMU6ZWHAUSLSE3ZWFYA5A5CNFSM6AAAAABNY5JNP6WGG33NNVSW45C7OR4XAZNRIRUXGY3VONZWS33OINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAUIP3I.gif> Message ID: ***@***.*** ***@***.***> >
|
Beta Was this translation helpful? Give feedback.
-
What I mean by “don’t do it” is don’t formally document it in the standard. Of course you can use whatever notation you see fit in your code; as we all know, anything between ( and ) is entirely there for the author and reader’s benefit.
: callback: ( n <name> -- ) \ generate callback head
My code makes extensive use of <brackets> to indicate parsing words. It documents that we’re expecting `1234 callback: mycallback` .
The standard suggests using quotes as in: : callback: ( n “name” -- ) \ generate callback head
It’s a shame (at least to me) that much of section 2 of the standard is normative.
—
Alex
From: ruv ***@***.***>
Sent: Thursday, September 12, 2024 3:35 PMTo: ForthHub/discussion ***@***.***>
Cc: Alex McDonald ***@***.***>; Mention ***@***.***>
Subject: Re: [ForthHub/discussion] Should stack descriptions document `THROW`? (Discussion)
***@***.*** wrote:
Don’t do it. See my next email (which may take me a few days to write; thanks for your patience).
Alex, thank you for your criticism. I'll be waiting for your next email.
Note that I already use this notation in my code, I find it useful, and I don't see why I shouldn't use it. If some people find it useful, they will use it too. But most people don't use data types in they stack diagrams at all.
|
Beta Was this translation helpful? Give feedback.
-
Why not? This does affect neither programs nor systems.
If it affects nothing, then why have it in the standard? Just leave it out and have the discussion here.
—
Alex
On 12 Sep 2024, at 20:59, ruv ***@***.***> wrote: @alextangent wrote:
What I mean by “don’t do it” is don’t formally document it in the standard.
Why not? This does affect neither programs nor systems.
Anyway, this can only be formally documented if every committee member agrees with it. There is a very small chance for that.
|
Beta Was this translation helpful? Give feedback.
-
Here’s a quick 2 cents on this one.
You want to use the most restrictive (or narrowest or smallest) type for the return value of abs. It’s defined in the standard as abs ( n -- u ). Bernd Paysan has given a reference implementation of abs ( n -- +n ). It could be written as abs ( n -- x ).
What the difference is between u or x or +n isn’t really the argument here; I think you’re attempting to define what abs does, but by using the stack diagram to do so. abs should always return the absolute value of n, but that is evident from the text (and the name, although I admit that’s not always guaranteed), and we really don’t need to describe the value that the word abs returns. If we were to be absolutist about this, then we ought to fix up MOD and NEGATE and other similar words, and invent a whole bunch of other symbols for other words with imprecise stack diagrams that seem to require more narrowly defined values.
The stack diagram’s usefulness isn’t that it describes the *values* of the stack entries, but that it describes the *depth of the stack* on entry and exit and the *use* of the stack cell or cells. So xt, nt, ior and so on; they are silent about the values but describe their use.
Having x or u or n as the stack on exit from abs isn’t in any way confusing or ambiguous, and as you can clearly see I’m not in the “should use the most restrictive type” camp because we’ll keep inventing types to describe (actually, proscribe) values when we don’t need to; there’s no extra information in them that can’t be had from other comments or the text in the standard.
A case in point; bye ( -- ⊥ ). The stack diagram in the standard is fine. It requires nothing on the stack, and guess what – after it has been executed, there aren’t any stacks to worry about, as the standard text makes abundantly clear. Run bye. Poof. They’re gone. But here we are inventing symbols for something that is self-evident.
The other suggestion that ⊥ indicates no return to the caller breaks for me the simplicity of the stack diagram. It’s no longer about the stack, but about the state of the system after execution and side effects that the word may have. We could define a whole host of symbols; how about indicating that after the execution of PARSE the parse area has moved forward n chars with ->+n?
(More general note. Document your words as you like, but please don’t make Forth look like APL. I consider my time decades ago using APL well spent, but the symbol set was always a nightmare. The up-tack is the dyadic function decode; A⊥B is the value of a polynomial whose coefficients are B at A. Great function, nightmare to type and read. No, I can’t remember what it does or how to use it.)
I think I’m all argued out. Have a nice day :)
—
Alex
From: ruv ***@***.***>
Sent: Friday, September 13, 2024 11:14 AM
To: ForthHub/discussion ***@***.***>
Cc: Alex McDonald ***@***.***>; Mention ***@***.***>
Subject: Re: [ForthHub/discussion] Should stack descriptions document `THROW`? (Discussion #170)
@alextangent <https://github.com/alextangent> wrote:
If it affects nothing, then why have it in the standard?
It makes specifications for some words more clear, also it makes explicit some things that are implicit at the moment.
Have a look at the word abs ( n -- +n ). Note that the stack diagram ( n -- x ) is also correct for abs, because +n is a subtype of x and any output parameter of abs is a member of x.
Why should not we use ( n -- x ), but ( n -- +n ) for abs?
We should use the smallest suitable data type to describe a stack parameter or a mapping of the input parameters to the output parameters. Where "smallest" data type means the one having the least number of members among suitable data types.
Obviously, +n has fewer members than x, and it includes all possible output parameters of abs. Therefore, we should use +n.
Now let's apply this logic to the word bye. The size of the type ( -- ⊥ ) is less than the size of the type ( -- ) (because ⊥ has fewer members than 0*x), and they both are suitable for bye. So, we should should prefer the former: bye ( -- ⊥ ).
The Forth type system already implies the empty type ( ⊥, "never"), the 0-tuple of parameters and the corresponding unit type (0*x, "nothing"), but it does not name them.
—
Reply to this email directly, view it on GitHub <#170 (reply in thread)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAOB6OVL725XPRNFUG3V74TZWK3FJAVCNFSM6AAAAABNY5JNP6VHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTANRTGYZDCNY> .
You are receiving this because you were mentioned. <https://github.com/notifications/beacon/AAOB6OQDU7TMBUQY7UKHDJDZWK3FJA5CNFSM6AAAAABNY5JNP6WGG33NNVSW45C7OR4XAZNRIRUXGY3VONZWS33OINXW23LFNZ2KUY3PNVWWK3TUL5UWJTQAUJF3S.gif> Message ID: ***@***.*** ***@***.***> >
|
Beta Was this translation helpful? Give feedback.
-
I'm curious what the convention is, should words document in some fashion that they
THROW
? Not necessarily every possible code, maybe just document the non-standard ones. Maybe a summary as part of the stack description, eg.WRITE-FILE ( caddr u fd -- ior T)
orfoo ( i*x -- j*x )(T: 1, 2, 3)
.Beta Was this translation helpful? Give feedback.
All reactions