ruv[133] Wording: declare undefined interpretation semantics for localsProposal2020-03-08 15:18:59
Problem
We have the "name Execution:" section for the locals, but don't have a "name Interpretation:" section. Hence, name has default interpretation semantics according to 3.4.3.2, that conflicts with an explicitly declared ambiguous condition in the "name Execution:" section.
Proposal
Add the following section:
name Interpretation:
Interpretation semantics for name are undefined.
Remove from the "name Execution:" section the following sentence:
An ambiguous condition exists when name is executed while in interpretation state.
The same proposal is applied to (LOCAL), taking into account that there another wording is used: "local Execution:". Perhaps we should also harmonize these specifications with each other.
In the general case, "name is executed while in interpretation state" can be achieved via : foo {: name :} name ; 1 foo — and nothing wrong with that. So the corresponding sentence is even incorrect by its own.
Before these changes the locals may be ticked and executed (but only in compilation state). It means, that they shall be implemented as immediate words.
Also, it seems the following code is standard (from a formal point of view):
: [e] execute ; immediate
variable local-x
: foo {: x :} [ ' x local-x ! ] x . ;
: bar [ local-x @ ] [e] . ;
1 foo bar
Obviously, this code is ambiguous. E.g., in some implementations the definition for x isn't available after creating foo, and trying to execute it can cause memory access violation.
After these changes the locals are not allowed to be ticked, and they may be implemented in any way.
I agree that the current wording is flawed and that your wording better reflects the intent.
As you point out in a later answer, there are several places where this would have to be fixed, so maybe the description of the local should be factored out and fixed there.
I think that instead of defining execution semantics for name, we should define compilation semantics that refers to run-time semantics; these run-time semantics would have the specification of the current "name execution". (This is just one instance of execution semantics without interpretation semantics; several of them should get this treatment, and the rest should get defined interpretation semantics).
Factoring out the description of the local is the right step, but it requires more labor. This case will be the first one when semantics for a word are described not in some glossary entry, but in some "Additional usage requirements" section (in this case, a subsection of 13.3).
Defining compilation semantics via run-time semantics is also a good step, although it isn't crucial (it just fixes some confusing). And it's more worthwhile to apply these changes for all such cases at once (i.e., also for EXIT, >R, etc).
So I would suggest the following roadmap:
Add "Interpretation" section in {: and (LOCAL) glossaries (as easy and quick solution).
Factor out description of locals, without changing the wording.
Change wording for all such words at once.
Regarding the repository with the source text — it's important to have each step as a separate commit.
You as proposer decide what and how you propose changes. However, my feeling is that it is better to propose this as one proposal rather than three. And make the changes to EXIT and friends another proposal that covers them all.
The editor decides how he deals with version control.
I think we should remove the execute of locals entirely, and state compilation semantics is to append this.
E.g. trying to tick a local and execute it fails, e.g. in Gforth:
: test { a b c } ['] a execute b + c * ;
*terminal*:1:22: warning: a is compile-only ok
1 2 3 test .
*the terminal*:2:7: error: Stack underflow
1 2 3 >>>test<<< .
Backtrace:
*terminal*:1:34 0 $7F4559C5A5E0 +
or Vfx:
: test {: a b c :} ['] a execute b + c * ; ok
1 2 3 test ok
. 6
Err# -4 ERR: Data stack underflow.