Skip to content

fix module scoping#5

Merged
lyninx merged 1 commit intomainfrom
module-scoping
Feb 8, 2026
Merged

fix module scoping#5
lyninx merged 1 commit intomainfrom
module-scoping

Conversation

@lyninx
Copy link
Copy Markdown
Owner

@lyninx lyninx commented Feb 8, 2026

No description provided.

Copilot AI review requested due to automatic review settings February 8, 2026 00:32
@lyninx lyninx merged commit 59bfede into main Feb 8, 2026
7 checks passed
@lyninx lyninx deleted the module-scoping branch February 8, 2026 00:32
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts Lunary’s module function-call scoping so that module-defined identifiers take precedence over caller-local identifiers, and adds a regression test to ensure module functions can share names with local variables.

Changes:

  • Fix scope merge order for module function access so module scope wins on key collisions.
  • Add a unit test covering module function name collision with a local identifier.
  • Remove a leftover commented @tag :skip line in a chain test.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
lib/lunary.ex Changes how scopes are merged during module function access to prioritize module scope.
test/unit/module_test.exs Adds regression coverage for calling a module function when a local variable has the same name.
test/unit/chain_test.exs Removes a stray commented skip tag.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/lunary.ex
Comment on lines 131 to 134
defp evaluate({:func_access, index, {:fn, {:identifier, fn_line, fn_id}, fn_args}}, scope, opts) do
{func_scope, _} = evaluate(index, scope, opts)
merged_scope = Map.merge(func_scope, scope)
merged_scope = Map.merge(scope, func_scope) # function scope takes priority
evaluate({:fn, {:identifier, fn_line, fn_id}, fn_args}, merged_scope, opts)
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scope precedence change here fixes direct module calls, but there is still a second code path for chained module calls ({:chain, ..., {:func_access, ...}} around lib/lunary.ex:396-403) that merges scopes in the old order (Map.merge(func_scope, scope)). That means val |> @mod.fn() can still resolve identifiers using the caller scope ahead of the module scope, making scoping behavior inconsistent and likely leaving the original bug unfixed for pipelines. Update that merge order as well (and consider adding a test that pipes into a module function while a conflicting local identifier exists).

Copilot uses AI. Check for mistakes.
Comment thread lib/lunary.ex
defp evaluate({:func_access, index, {:fn, {:identifier, fn_line, fn_id}, fn_args}}, scope, opts) do
{func_scope, _} = evaluate(index, scope, opts)
merged_scope = Map.merge(func_scope, scope)
merged_scope = Map.merge(scope, func_scope) # function scope takes priority
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: the inline comment says "function scope takes priority", but func_scope here is actually the evaluated module scope coming from index (e.g., @example). Consider rewording to avoid confusion when revisiting scoping rules later.

Suggested change
merged_scope = Map.merge(scope, func_scope) # function scope takes priority
merged_scope = Map.merge(scope, func_scope) # evaluated scope from `index` takes priority

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants