Summary
A container action cannot call another action of the same container. There is no self/this/me, a bare call does not resolve, and the enclosing instance is not in scope inside its own methods — so container actions can only touch their own properties, never cooperate.
Reproduction
create container M:
property buf: Text
action emit needs ch: Text:
store buf as buf with ch
end
action step:
emit("x")
end
end
create new M as m:
buf is ""
end
m.step()
display "buf=[" with m.buf with "]"
Command:
wfl g1_container_sibling_call.wfl
Expected
buf=[x].
No documentation citation exists — this is filed as a capability gap, not as a
broken runtime. Docs/04-advanced-features/containers-oop.md:118-165 documents
actions as "functions that belong to containers" and shows them reading and
writing sibling properties (change value to value + amount), but no example
anywhere in Docs/ or in TestPrograms/ calls one action from another, and no
receiver keyword is documented. The gap is that there is no documented way to
express one method of a container calling another.
Actual
error[ANALYZE-SEMANTIC]: Variable 'emit' is not defined
Exit code: 3.
All spellings fail, each with its own message:
form inside action step: |
result |
emit("x") |
error[ANALYZE-SEMANTIC]: Variable 'emit' is not defined |
call emit with "x" |
error[ANALYZE-SEMANTIC]: Undefined action 'emit' |
self.emit("x") |
error[ANALYZE-SEMANTIC]: Variable 'self' is not defined |
this.emit("x") |
error[ANALYZE-SEMANTIC]: Variable 'this' is not defined |
me.emit("x") |
error[ANALYZE-SEMANTIC]: Variable 'me' is not defined |
parent.emit("x") |
Parse errors: error[ERROR]: Expected identifier for method name, found Dot |
Referring to the module-level instance from inside its own method does not work
either — m.emit("x") inside action step: gives
error[ANALYZE-SEMANTIC]: Variable 'm' is not defined (exit 3). There is no
workaround inside the container.
For contrast, everything around this works: calling actions from outside
(m.step()), property mutation from inside an action, and inheritance are all
fine (TestPrograms/test_container_property_mutation.wfl and
TestPrograms/containers_comprehensive.wfl both exit 0 on 26.8.4).
Related known limitation, already noted in closed umbrella issue #578: external
property mutation (change obj.prop to x / store obj.prop as x) also does not
parse. Together these mean a container today is effectively a bag of properties
with independent, non-cooperating methods.
Environment
- wfl --version:
WebFirst Language (WFL) version 26.8.4
- binary: system install
C:\Program Files\wfl\bin\wfl.exe
- commit: c277d8f
- OS: Windows 11 Pro 10.0.26200
- build: release
Also reproduces on the repo build (26.8.2) — not a regression.
No .wflcfg in scope.
Context
Found while porting G:/repos/JShrink/src/JShrink/Minifier.php (a 738-line PHP
JavaScript minifier) to WFL.
This is the one that dictated the port's architecture. JShrink is a single PHP
class whose twelve methods mutate ten shared fields and call each other constantly
(loop() → echo()/saveString()/getReal(); getReal() → getChar()/
processOneLineComments(); saveString() → getChar()/echo()). The obvious
1:1 mapping is a WFL container. That is not expressible today, so the port was
written with module-level variables mutated through change from top-level
actions instead — which works well and is documented
(Docs/03-language-basics/actions-functions.md:423), but it is a different shape
from the source, and the reviewer should know the divergence was forced rather
than chosen. No stub was left; the port is complete on the alternative shape.
Worth noting against the No-Unlearning Invariant: a beginner who learns containers
from containers-oop.md will hit this wall the first time one method needs
another, with no documented path forward.
Summary
A container action cannot call another action of the same container. There is no
self/this/me, a bare call does not resolve, and the enclosing instance is not in scope inside its own methods — so container actions can only touch their own properties, never cooperate.Reproduction
Command:
Expected
buf=[x].No documentation citation exists — this is filed as a capability gap, not as a
broken runtime.
Docs/04-advanced-features/containers-oop.md:118-165documentsactions as "functions that belong to containers" and shows them reading and
writing sibling properties (
change value to value + amount), but no exampleanywhere in
Docs/or inTestPrograms/calls one action from another, and noreceiver keyword is documented. The gap is that there is no documented way to
express one method of a container calling another.
Actual
Exit code: 3.
All spellings fail, each with its own message:
action step:emit("x")error[ANALYZE-SEMANTIC]: Variable 'emit' is not definedcall emit with "x"error[ANALYZE-SEMANTIC]: Undefined action 'emit'self.emit("x")error[ANALYZE-SEMANTIC]: Variable 'self' is not definedthis.emit("x")error[ANALYZE-SEMANTIC]: Variable 'this' is not definedme.emit("x")error[ANALYZE-SEMANTIC]: Variable 'me' is not definedparent.emit("x")Parse errors: error[ERROR]: Expected identifier for method name, found DotReferring to the module-level instance from inside its own method does not work
either —
m.emit("x")insideaction step:giveserror[ANALYZE-SEMANTIC]: Variable 'm' is not defined(exit 3). There is noworkaround inside the container.
For contrast, everything around this works: calling actions from outside
(
m.step()), property mutation from inside an action, and inheritance are allfine (
TestPrograms/test_container_property_mutation.wflandTestPrograms/containers_comprehensive.wflboth exit 0 on 26.8.4).Related known limitation, already noted in closed umbrella issue #578: external
property mutation (
change obj.prop to x/store obj.prop as x) also does notparse. Together these mean a container today is effectively a bag of properties
with independent, non-cooperating methods.
Environment
WebFirst Language (WFL) version 26.8.4C:\Program Files\wfl\bin\wfl.exeAlso reproduces on the repo build (26.8.2) — not a regression.
No
.wflcfgin scope.Context
Found while porting
G:/repos/JShrink/src/JShrink/Minifier.php(a 738-line PHPJavaScript minifier) to WFL.
This is the one that dictated the port's architecture. JShrink is a single PHP
class whose twelve methods mutate ten shared fields and call each other constantly
(
loop()→echo()/saveString()/getReal();getReal()→getChar()/processOneLineComments();saveString()→getChar()/echo()). The obvious1:1 mapping is a WFL container. That is not expressible today, so the port was
written with module-level variables mutated through
changefrom top-levelactions instead — which works well and is documented
(
Docs/03-language-basics/actions-functions.md:423), but it is a different shapefrom the source, and the reviewer should know the divergence was forced rather
than chosen. No stub was left; the port is complete on the alternative shape.
Worth noting against the No-Unlearning Invariant: a beginner who learns containers
from
containers-oop.mdwill hit this wall the first time one method needsanother, with no documented path forward.