Skip to content

Imported Language::Functional break subroutine is parsed as an operator #1430

Description

@fglock

Summary

Language::Functional 0.05 fails under PerlOnJava because its exported break function is parsed as a built-in operator instead of being resolved as the imported Perl subroutine.

Reproduction

The upstream test t/simple.t imports all functions from Language::Functional and calls:

use Language::Functional ':all';

ok(eval {show(break { shift() >= 4 } [1..6])},
   '[[1, 2, 3], [4, 5, 6]]');

Language::Functional defines and exports break as a normal Perl subroutine with prototype (&$).

Expected result

System Perl passes the complete upstream suite:

  • 2 test files
  • 97 tests
  • t/simple.t passes all 96 tests

Actual result

The archived CPAN run fails during compilation at t/simple.t line 77, before the planned assertions execute:

JVM backend:

Operator "break" doesn't have a defined JVM descriptor at t/simple.t line 77, near ""

Interpreter backend:

Unsupported operator: break at t/simple.t line 77, near ""

The focused test reproduces this failure on both backends. The failure is recorded under target label InfiniteList, but the failing distribution is Language::Functional 0.05.

Likely root cause

PerlOnJava reserves or dispatches break as an operator before considering the imported subroutine installed by use Language::Functional ':all'. Standard Perl resolves this source form to the imported function, including its (&$) prototype and block argument.

This is a parser/symbol-resolution compatibility defect involving imported subroutines whose names overlap with built-in or feature-related operators. It is pure Perl and does not involve XS code, native libraries, or external services.

Acceptance criteria

  • An imported subroutine named break can be called in the upstream form break { ... } $list on both JVM and interpreter backends.
  • Language::Functional 0.05 passes all 97 upstream tests without modifying its tests.
  • Add focused project-owned regression coverage for an imported subroutine shadowing or overriding a built-in/feature-related operator name.
  • Preserve genuine operator behavior when no overriding subroutine is imported.
  • Preserve prototype-aware parsing of the block argument.

Evidence

  • CPAN run: 20260918-141920-96054
  • Distribution: Language-Functional-0.05
  • Failing test: t/simple.t line 77, break { shift() >= 4 } [1..6]
  • System Perl: PASS, 2 files / 97 tests
  • PerlOnJava: FAIL before assertions in t/simple.t
  • JVM and interpreter: focused failure reproduced

Related issues

  • #19 tracks imported Time::HiRes::time failing to override the built-in time operator. It is closed and concerns a different operator, but the import-vs-core-operator resolution problem is related.
  • #1257 tracks symbol-resolution collisions between imported constants and lexical declarations. It is open and related to preserving Perl namespaces and imported symbol identity, but it does not cover operator-shaped subroutine calls.

This issue should be coordinated with those efforts while retaining Language::Functional as independent regression coverage.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:cpan-portCPAN compatibility ports and providersarea:parserParsing compilation AST and eval behaviorbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions