Why can't a variable, parameter or named capture have the same name as a function or type?
← Variable Naming Rules and Conventions · Ref: Q1392
In EK9 a name has one meaning in a scope. A variable - a local, a parameter, a property, a loop variable, a returning variable or a NAMED capture - may not reuse the name of a function (E01030) or a type, your own or a built-in one (E01040), or of anything the module imports with 'references' (E03010). Rename the variable; the function or type keeps its name.
NAMED CAPTURES
A dynamic function or class captures values in parentheses. '(price)' captures the local 'price' under its own name - that name was already checked where 'price' was declared. '(seasonalRate: 0.25)' introduces a NEW variable: it becomes a property of the dynamic function or class, so it obeys exactly the same rule. With a module function 'discount()' in scope, '(discount: 0.25)' is E01030 on the capture: inside the body a bare 'discount' would have two meanings, and a reader - or an AI - cannot tell whether the body calls the function or reads the capture.
WHAT IS ALLOWED
A named capture may reuse the name of an enclosing LOCAL: '(price: price * 2.0)'. Once captured, the enclosing local is not visible inside the body at all, so there is only one 'price' there.
Within one set of parentheses either every capture is named or none is (E06240). This program captures a rate and the price under descriptive names that do not clash with the discount() function, then re-captures 'price' with a new value.
Example
defines module qa.naming.captures //Referenced explicitly - so no variable here may be named Stdout (E03010). references org.ek9.lang::Stdout defines function discount() as pure <- rtn as Float: 0.1 defines program CaptureNamingDemo() stdout <- Stdout() price <- 200.0 withSeasonalRate <- (seasonalRate: 0.25, basePrice: price) is Supplier of Float as pure function r: basePrice * (1.0 - seasonalRate) stdout.println($ withSeasonalRate()) withStandardRate <- (price: price * 2.0) is Supplier of Float as pure function r: price * (1.0 - discount()) stdout.println($ withStandardRate())
Common mistakes
E01030 — discount() is a function in this module, so a capture named 'discount' would give the name two meanings inside the body. Rename the capture. See ek9 -h E01030.
Incorrect:
(discount: 0.25, basePrice: price) is Supplier of Float as pure function r: basePrice * (1.0 - discount)
Correct:
(seasonalRate: 0.25, basePrice: price) is Supplier of Float as pure function r: basePrice * (1.0 - seasonalRate)
E01030 — A local variable may not reuse the name of a function either - the same rule as for a capture. See ek9 -h E01030.
Incorrect:
discount <- 200.0
Correct:
price <- 200.0
E01040 — String is a built-in type, so a variable - here a named capture - may not be called String. The same applies to your own types. See ek9 -h E01040.
Incorrect:
String: price)
Correct:
basePrice: price)
E03010 — This module imports Stdout with 'references', so no variable - including a named capture - may take that name. See ek9 -h E03010.
Incorrect:
Stdout: 0.25,
Correct:
seasonalRate: 0.25,
Other ways to ask this
- Why does '(discount: 0.25)' in a dynamic function give E01030?
- Can a closure capture have the same name as a function?
- Why is my captured variable name rejected in a dynamic function or class?
- What is E01030 when naming a variable or capture in EK9?
Coming from another language?
Java lambdas cannot rename a captured variable at all, and a local may shadow a method name freely. Kotlin, Swift and JavaScript closures capture by name and allow a local to shadow a function of the same name. EK9 allows neither shadowing: a variable - including a named capture - may not reuse a function or type name.
Keywords: closure, shadow, dynamic class, E03010, E01030, naming, dynamic function, capture, named capture, E01040