How do I use Supplier and Producer to create values?
← Generics · Ref: Q708
Supplier and Producer are the no-parameter function types that return a value. They differ only in purity.
SUPPLIER IS PURE
Supplier of T takes no parameters and returns 'r' of type T. Being pure, it always returns the same value:
factory <- () is Supplier of String as pure function r: "Default"
A pure Supplier is a constant factory — deterministic and safe.
PRODUCER IS IMPURE
Producer of T has the same signature but is NOT pure, so it can read external state:
generator <- () is Producer of String as function r: "Generated"
Producer allows side effects in value creation.
FACTORY PATTERN
Use Supplier for deterministic factories and Producer for stateful ones:
obtainValue()
-> factory as Supplier of String
<- result as String: factory()
See Q54 for pure vs impure concepts. See Q649 for generic function implementation rules.
Example
defines module qa.genericsdeep.supplierproducer defines function <?- Helper that uses a Supplier to get a value. Pure context — only pure Suppliers can be passed. -?> obtainValue() as pure -> factory as Supplier of String <- result as String: factory() <?- Helper that uses a Producer to get a value. Impure context — Producer can have side effects. -?> generateValue() -> factory as Producer of String <- result as String: factory() defines program SupplierProducerDemo() stdout <- Stdout() //Supplier: pure, deterministic factory //Body sets 'r' — the return variable from Supplier's signature nameFactory <- () is Supplier of String as pure function r: "DefaultName" name <- obtainValue(nameFactory) stdout.println(`Supplier result: ${name}`) //Producer: impure, can access external state greetingFactory <- () is Producer of String as function r: "Hello from Producer" greeting <- generateValue(greetingFactory) stdout.println(`Producer result: ${greeting}`) //Direct call on dynamic function variable directResult <- nameFactory() stdout.println(`Direct Supplier: ${directResult}`)
Common mistakes
E05150 — Supplier is pure — dynamic functions extending Supplier must use 'as pure function', not just 'as function'. The compiler requires the purity of the implementation to match its pure super type. See ek9 -h E05150 for details.
Incorrect:
() is Supplier of String as function
Correct:
() is Supplier of String as pure function
Other ways to ask this
- What is the difference between Supplier and Producer in EK9?
- How do I create a factory function with Supplier of T?
- When should I use Producer instead of Supplier?
Coming from another language?
Java: java.util.function.Supplier<T> — no purity distinction, can have side effects. Kotlin: () -> T — no pure/impure variants. Rust: Fn() -> T (pure) vs FnMut() -> T (stateful) — structural distinction. Go: func() T — no purity enforcement. C#: Func<T> — no purity concept. EK9: Supplier (pure, deterministic) vs Producer (impure, can be stateful) — compile-time enforced.
Keywords: no-parameter, pure, factory, return, create, function-type, supplier, side-effect, producer, generic, impure