Skip to content

Date-unit names (year/month/day/hour/minute/second) as action-local vars are a fatal "already defined in an outer scope" error inside included files #557

Description

@logbie

Summary

After #553 (thanks — include from now works for stdlib-heavy libraries!), one more sharp edge: the bare date-unit words year, month, day, hour, minute, second appear to be pre-registered as outer-scope globals. Using any of them as an action-local variable inside an included file is a fatal semantic error:

error[ERROR]: Semantic error in included file 'mod.wfl': Semantic error at line 2, column 5:
Variable 'year' has already been defined in an outer scope. Use 'change year to <value>' to modify it.

The same code in the main file only emits a non-fatal "Could not infer type" warning and runs fine — so the behavior is inconsistent between main and included files.

Environment

  • WFL 26.7.4 (main @ b1acf38), Linux release build

Minimal reproduction

mod.wfl:

define action called mk with parameters n:
    store year as n plus 1
    return year
end action

main.wfl:

include from "mod.wfl"
store a as call mk with 1
store b as call mk with 2
display a with "," with b

wfl main.wfl → fatal "Variable 'year' has already been defined in an outer scope."

Scope of the collision

Tested one name at a time as an action-local store inside an included file:

Names Result
year, month, day, hour, minute, second ❌ fatal "already defined in an outer scope"
id, key, plan, path, basis, total, counter, value, date, time, … everything else I tried ✅ fine

So it's exactly the six singular date-unit words. They're presumably globals backing the date/time API, but they shadow ordinary user variable names, and only fatally so inside includes.

Two things that seem wrong

  1. Inconsistency: main-file store year as … is a non-fatal warning and runs; included-file store year as … is fatal. Include and main should behave the same.
  2. Surprising reservation: year/day/minute are natural variable names. If they must stay reserved, a clearer message ("year is a reserved date-unit name") would help; ideally an action-local store shadows them like any other local.

Workaround

Rename the local (e.g. yearyear_ms). That's what I did in my project, so this isn't blocking me — just reporting the trap and the main-vs-include inconsistency.

Minor adjacent note (not blocking)

expect <expr> to contain "…" prints error[ERROR]: contain assertion requires List or Text type when <expr> is an action's return value, even though the value is Text and the test passes. Happens in both main-file and included-file test suites — looks like the type checker doesn't infer an action's return type for the contain assertion. Non-fatal (tests still pass), just noisy. Happy to file separately if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions