E08278: cannot be the target of '>' because '>' replaces the target with a fresh value and this type cannot make one (it must be concrete, have an accessible constructor with no arguments and have a ':=:' operator); use '>>' to add to it instead, or give the type those
What went wrong
A '>' at the end of a stream REPLACES its target: the stream is poured into a fresh value of the target's type and, only when the stream has finished, that value is swapped in with ':='. That is the Unix meaning of '>' and it is the same for a List, a Set, an Integer, a String or a type you wrote - the old value takes no part in the result, and a stream that fails part-way leaves the target as it was. To do that the target's type has to be able to make a fresh value: it must be a concrete type, with a constructor that takes no arguments and that is not private, and it must have a ':=:'. Here the target's type cannot, so '>' has nothing to start from. Rather than quietly add to the target, which is what '>>' says, the compiler stops and names '>>':
cat [1, 2, 3] > tally
The built-in output channels are different and are never reported: Stdout, Stderr, a file output, a UDP or TCP connection and anything else that is an IO. '>' into one of them clears it first (it empties a file, and does nothing where there is nothing to clear) and '>>' leaves what is there.
Worked examples
Each of these is fine:
- //'>>' adds to the Tally that is there: 10 + 1 + 2 + 3.
- cat [1, 2, 3] >> tally
- //'>' makes a fresh Tally with the constructor with no arguments and swaps it in with ':=:': 1 + 2 + 3.
- cat [1, 2, 3] > tally
How to fix it
- If you meant to add the stream's items to what the target already holds, write '>>'.
- If you meant to replace it, give the type 'default operator :=:' (or your own ':='), and keep a constructor with no arguments that is not private, so a fresh value can be made and swapped in.
- A target that is a trait or an abstract type can never make a fresh value: use '>>', or a variable of a concrete type.
Common causes
- A class that collects what is piped into it ('operator |') being the target of '>' rather than '>>'
- A target declared as a trait or an abstract class
- A type that declares its no-argument constructor 'private'
- A type with no ':=:' (neither written nor 'default operator :=:')
See also
- E08277: another stream-sink check, a stream that appends to the very variable it reads
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E08278: cannot be the target of '>' because '>' replaces the target with a fresh value and this type cannot make one (it must be concrete, have an accessible constructor with no arguments and have a ':=:' operator); use '>>' to add to it instead, or give the type those
#!ek9 defines module error.e08278.bad defines class Tally count as Integer: 0 Tally() -> start as Integer count :=: start default operator ? operator $ as pure <- rtn as String: `Tally(${count})` operator | -> item as Integer if item? count += item defines function addUp() stdout <- Stdout() tally <- Tally(10) cat [1, 2, 3] > tally stdout.println($tally)
Fixed: Give the Tally a constructor with no arguments and a ':=:', or add to it with '>>'
#!ek9 defines module error.e08278.good defines class Tally count as Integer: 0 Tally() count :=: 0 Tally() -> start as Integer count :=: start default operator ? operator $ as pure <- rtn as String: `Tally(${count})` default operator :=: operator | -> item as Integer if item? count += item defines function addUp() stdout <- Stdout() tally <- Tally(10) //'>>' adds to the Tally that is there: 10 + 1 + 2 + 3. cat [1, 2, 3] >> tally //'>' makes a fresh Tally with the constructor with no arguments and swaps it in with ':=:': 1 + 2 + 3. cat [1, 2, 3] > tally stdout.println($tally)
Fixed: Use '>>' to add to the Tally that is there
#!ek9 defines module error.e08278.good.fix defines class Tally count as Integer: 0 Tally() -> start as Integer count :=: start default operator ? operator $ as pure <- rtn as String: `Tally(${count})` operator | -> item as Integer if item? count += item defines function addUp() stdout <- Stdout() tally <- Tally(10) cat [1, 2, 3] >> tally stdout.println($tally)