Repository navigation
Implement Function::Parameters compatibility using native signatures and parser support #1361
Description
Summary
Implement a PerlOnJava-compatible Function::Parameters provider that uses
PerlOnJava's parser/compiler infrastructure and modern Perl signatures/class
semantics where they match the module's behavior.
This is a focused consumer/port issue for the parser extension capability
proposed in #1292. It should not attempt to reproduce the Perl 5 parser ABI or
compile the module's native XS code.
Motivation and evidence
Function::Parameters is currently blocked because its latest CPAN release,
v2.002006 (2025-08-16), loads an XS implementation. The XS code installs a
Perl keyword plugin, parses declarations such as fun and method, creates
lexical parameter bindings, emits default and validation logic, and exposes
signature metadata through Function::Parameters::Info.
The CPAN reverse-dependency lookup reports 53 unique dependant distributions,
including 8 released within the last three years. Examples include
exact-fun, Data-Frame, WebService-OpenStates,
Net-Google-CivicInformation, App-Wax, HTML-Blitz, Klonk, and
Function-Return.
The CPAN compatibility run 20260910-101908-8428 showed
Mojolicious::Plugin::GraphQL failing before its own behavior was tested:
Function::Parameters could not load because no Java XS implementation was
available. Other dependency paths have the same underlying limitation.
Feasibility
A normal pure-Perl replacement is not sufficient. Function::Parameters adds
custom declaration keywords and relies on compile-time parser/optree behavior;
ordinary import, AUTOLOAD, or runtime wrappers cannot reliably make syntax
such as this work:
use Function::Parameters;
fun add($x, $y = 1) { $x + $y }
method render($self: :$format = 'html') { ... }Source filters could rewrite a subset, but would be fragile around eval,
lexical pragma scope, nested declarations, heredocs, diagnostics, and generated
closures. They would also make JVM/interpreter behavior depend on a second
parser.
Modern Perl provides useful semantics but not a drop-in replacement:
- Stable core signatures (enabled by
use v5.36) cover positional parameters,
defaults, slurpy arrays/hashes, and argument-count checking. - The experimental
classfeature providesclass,field,method,
ADJUST, and field:paramconstructor arguments. - Core signatures do not provide the complete
Function::Parameterskeyword
model, arbitrary configured invocants,fun, named:$xparameters with
the same rules, custom type constraints/coercions, method modifiers, or the
Function::Parameters::InfoAPI.
References:
- Function::Parameters v2.002006
- Function::Parameters documentation
- Perl 5.42 signatures
- Perl 5.42 class syntax
Conclusion: a mostly-Perl compatibility layer is feasible, but it requires
PerlOnJava parser/compiler support. It is not feasible as a standalone pure
Perl module with no engine changes.
Proposed architecture
- Use Design a parser keyword-plugin API for PerlOnJava #1292's lexical parser keyword-plugin API to register
fun,method,
configured aliases, and later modifiers. - Parse declarations directly into the shared AST used by both execution
backends. Do not generate backend-specific implementations. - Normalize supported signatures into existing subroutine nodes, including
lexical bindings, invocants, defaults, slurpy parameters, and call-time
validation. - Represent signature metadata in a stable compiler/runtime structure so
Function::Parameters::infocan expose it without inspecting backend
internals. - Implement the compatibility module as a small Perl provider/pragma that
requests parser registration. Its API should degrade with a clear
diagnostic for unsupported syntax rather than silently treatingfunor
methodas ordinary barewords.
Suggested implementation phases
Phase 1: core signature subset
funnamed and anonymous declarations;- ordinary required and optional positional parameters;
- default expressions, including
//=and||=forms; - ignored parameters and slurpy
@/%parameters; - exact argument-count diagnostics;
- lexical pragma scope for
use/noand nestedeval.
Where semantics are identical, reuse the existing core-signature AST/runtime
representation rather than creating a parallel implementation.
Phase 2: methods and metadata
methoddeclarations;- implicit, named, and configured invocants;
- class-method and multi-invocant configurations where needed;
Function::Parameters::Infoobjects and parameter categorization;- prototypes and relevant subroutine attributes.
Phase 3: extended behavior
- named
:$parameterarguments and named-parameter slurping; - custom type constraints, inline checks, custom error messages, and coercion;
before,after,around,augment, andoverridemethod modifiers;- closure/lifetime behavior and debugger/source-location parity.
Compatibility boundaries
The first implementation should document any behavior that cannot be matched
exactly. In particular, do not claim complete compatibility until the following
are covered or explicitly rejected:
- compile-time syntax errors and line/column locations;
- indirect calls and prototype interactions;
- recursion and anonymous functions;
- default expressions evaluated at call time;
- aliases and mutation behavior through
@_; - typed parameters and custom type objects;
- modifier composition and method cache invalidation;
eval STRING, nested lexical scopes, andrequire-time registration;info()introspection and generated parameter metadata;- JVM/interpreter parity.
Testing and acceptance criteria
Add project-owned tests without modifying upstream tests. Validate each
Perl-level behavior with system Perl first, then require both PerlOnJava
backends to pass.
Acceptance should include:
- parser-plugin registration and lexical removal;
- named and anonymous
fundeclarations; - methods with invocants and defaults;
- positional, named, ignored, and slurpy parameters;
- malformed declarations and stable source locations;
- nested blocks, strings, comments, heredocs, and
eval; - default-expression side effects and recursive calls;
Function::Parameters::Infocompatibility for the supported subset;- identical JVM/interpreter results;
- a minimal
Mojolicious::Plugin::GraphQLor GraphQL dependency reproducer; - progress toward the blocked CPAN dependants, with unsupported XS-only cases
kept separately classified.
The issue is complete only when the provider can execute a documented useful
subset on both backends, the parser API is documented, and remaining upstream
failures have an explicit compatibility classification.
Related: #1292 (parser keyword-plugin API).
Activity
fglock commentedon Sep 28, 2026
Additional CPAN verification (run
20260928-091741-26386):Role::MethodReturnsv0.04 passes its complete upstream test under system Perl (t/00_use_ok.t, 1 test).Role::MethodReturnsimportsFunction::Parametersv2.002006, whoseXSLoader::loadcannot find a Java XS implementation.Function::Parameterscompatibility gap, not aRole::MethodReturns-specific runtime failure.Function::Parameters; 8 were released within the project’s three-year recent-dependant window. The list includesRole::MethodReturns,Function::Return,exact-fun,Data-Frame,WebService-OpenStates,Net-Google-CivicInformation,App-Wax, andHTML-Blitz.Recommendation: retain
Role::MethodReturnsas post-fix verification coverage for this issue; no separate issue is needed.fglock commentedon Oct 26, 2026
Follow-up for PR #1883:
Function::Parameterssubset on both backends, includingFunction::Parameters::info()metadata and typed parameter metadata.makegate passed with that fix.elsewhere.tandlineno-torture.t, and a warning-category difference instringy_h.t. Two GraphQL WebSocket ordering assertions also remain timing-sensitive on the busy host.This issue remains open until those compatibility gaps are either fixed or explicitly bounded and the PR is reviewed and merged. The current PR head still needs a fresh CI run.
fglock commentedon Oct 26, 2026
PR #1883 has now merged as 9ce6897. It adds the documented Function::Parameters subset, including typed metadata and introspection, and its Linux and Windows CI checks passed. This issue remains open because the upstream compatibility run is still incomplete: 45/56 files passed, with 4 errors and 7 incomplete files. Remaining cases include composite auto type expressions, errors in elsewhere.t and lineno-torture.t, a warning-category difference in stringy_h.t, and timing-sensitive GraphQL WebSocket ordering assertions. The PR body and prior comments retain the current scope and evidence; follow-up work should target these cases.