E07340: without a control, failed to find subject of flow
What went wrong
A flow construct has no control, and its pre-flow cannot stand in for one. A 'switch' without a control switches on its pre-flow variable, so a pre-flow like 'counter.value += 5' has no single subject. An 'if' (or 'else if'/'when') without a control decides on its pre-flow's isSet check, which only a guard ('<-', ':=?') performs; a blind assignment (':=', '=', ':', '+=', a typed declaration) checks nothing, so 'if item := findItem()' has no condition.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 836 (Why can't I use compound assignment like '+=' in a switch...)
- ek9 -q 1980 (What do <-, :=? and := each do in the head of an if, switch...)
How to fix it
- Keep the assignment and add the set-check as the control: 'if item := findItem() then item?'
- Or use a guard: '<-' for a new variable ('if item <- findItem()'), ':=?' to fill an unset one
- In a 'switch', assign to a simple variable first, then switch on it
Common causes
- Reading ':=' as a guard - it is a blind assignment with no isSet check
- Compound or property assignment used as a switch subject
See also
- E07340: pre-flow without a usable subject (this error)
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E07340: without a control, failed to find subject of flow
#!ek9 defines module error.e07340.bad defines function findItem() <- rtn as String: "found" blindAssignmentWithNoControl() <- rtn as String: String() selectedItem <- String() if selectedItem := findItem() rtn: selectedItem blindAssignmentInElseIfWithNoControl() -> flag as Boolean <- rtn as String: String() selectedItem <- String() if flag rtn: "flag" else if selectedItem := findItem() rtn: selectedItem typedDeclarationWithNoControl() <- rtn as String: String() if selectedItem as String: findItem() rtn: selectedItem compoundAssignmentWithNoControl() <- rtn as String: String() counter <- 1 when counter += 2 rtn: $counter blindAssignmentWithControlIsValid() <- rtn as String: String() selectedItem <- String() if selectedItem := findItem() with selectedItem? rtn: selectedItem guardsWithNoControlAreValid() <- rtn as String: String() existing <- String() if fresh <- findItem() rtn: fresh if existing := findItem() then existing? rtn: existing if existing :=? findItem() rtn: existing
Fixed: Use a guard, or say what to test
#!ek9 defines module error.e07340.good defines function findItem() <- rtn as String: "found" //A declaration guard: the body runs only when found is set withAGuard() <- rtn as String: String() if found <- findItem() rtn: found //An assignment needs a control saying what to test withAControl() <- rtn as String: String() selectedItem <- String() if selectedItem := findItem() then selectedItem? rtn: selectedItem
Questions and answers
These Q&A entries show E07340 and its fix:
- Q836: Why can't I use compound assignment like '+=' in a switch pre-flow in EK9?
- Q1962: How do I run a block only when an EXISTING variable gets a set value?
- Q1980: What do <-, :=? and := each do in the head of an if, switch, for, while or try?
- Q1982: Which ways of combining the guard operators does the compiler reject, and what should I write instead?
- Q2001: Does 'if allowed <- permitted()' run its body when permitted() returns false?
- Q2004: What are the names of EK9's '?' operators - '?', '<-', ':=', ':=?', '?:' and '<?'?