Differences from Perl 5
PetaPerl targets near-complete compatibility with Perl 5.42, but intentionally diverges in several areas. This document catalogs both intentional differences and current limitations.
Intentional Differences
Always-On Modern Features
PetaPerl enables all modern Perl features by default. No use feature or version declaration is needed:
say— print with newlinestate— persistent lexical variables//— defined-or operatorfc— Unicode case folding- Subroutine signatures
use v5.XX declarations are parsed but have no effect. PetaPerl always behaves like 5.42.
No XS Support
PetaPerl does not load XS (C extension) modules. Instead:
- Native implementations: Performance-critical modules (List::Util, Scalar::Util, Digest::MD5, etc.) are reimplemented in Rust as native functions
- Pure Perl fallback: Modules with Pure Perl implementations work automatically
- JIT compensation: The JIT compiler closes the performance gap that historically justified XS
This is a strategic decision: XS ties Perl to a C calling convention and prevents JIT optimization. PetaPerl’s JIT + auto-parallelization makes Pure Perl competitive with XS.
Linux Only
PetaPerl runs on Linux exclusively (any architecture supported by Cranelift: x86-64, AArch64, RISC-V, s390x). No Windows, macOS, BSD, or other platforms.
$^O always returns "linux".
p5 Runtime
PetaPerl includes an experimental --p5 flag that uses a self-contained Perl 5 compatible runtime. This is an alternative execution mode, not the default.
Version Reporting
$] reports 5.042000 and $^V reports v5.42.0. Code that checks these values will see PetaPerl as a perl 5.42 interpreter.
Unimplemented Features
tie/tied/untie
The tie mechanism is parsed and the functions exist, but they are stubs that return undef. Tied variables do not dispatch to the tie class methods.
Modules that depend on tie (e.g., Tie::File, Tie::Hash::NamedCapture internals) will not function correctly.
Formats
format/write/formline are parsed but the format output system is not implemented. write and formline are stubs. Use printf/sprintf instead.
Lvalue Subroutines
The :lvalue attribute is parsed but not enforced. Subroutines declared with :lvalue behave like normal subroutines.
Internals::SvREADONLY
Not implemented. This affects modules that rely on marking scalars read-only (charnames, unicore).
Some Pragmas
| Pragma | Status |
|---|---|
strict | Parsed, partially enforced |
warnings | Parsed, partial warning categories |
utf8 | Parsed, strings are always UTF-8 internally |
constant | Fully working |
base/parent | Fully working |
Carp | Fully working |
overload | Partially working |
re | Partially working |
Command-Line Flags
These perl5 flags are not supported:
| Flag | Description |
|---|---|
-I | Add include path (use PERL5LIB instead) |
-M / -m | Load module from command line |
-n / -p | Implicit input loop |
-l | Automatic line-ending processing |
-a / -F | Autosplit mode |
-i | In-place edit |
-x | Extract script from message |
-T | Taint mode |
Known Limitations
Regex Engine
PetaPerl’s regex engine passes 99.3% of perl5’s re_tests (1959/1972). Known gaps:
- Self-referential captures (e.g.,
(a\1)) — 3 tests localin(?{code})blocks — 2 tests- Multi-character Unicode case folding — 2 tests
- Branch reset group backreferences — 5 tests
- String interpolation edge cases — 1 test
Module Compatibility
| Module | Issue |
|---|---|
| Test2::API | use Module(\$lexical) loses compile-time lexical side effects |
| Module::CoreList | Timeout (>20s) due to enormous hash literals |
| charnames/unicore | Depends on Internals::SvREADONLY |
| Pod::Simple::RTF | Flip-flop operator edge case |
Flip-Flop Operator
The .. and ... operators in scalar context (flip-flop) have edge cases where pperl’s behavior differs from perl5. Most common uses work, but complex chaining may trigger errors.
Filehandle Heuristics
print $x, "\n" interprets $x as a potential filehandle (matching perl5 behavior). For variables that hold filehandle references, use the block form: print {$fh} "data\n".
Compile-Time Module Effects
use Module(args) runs at compile time in perl5. Modules that produce lexical side effects at compile time (e.g., use Instance(\$INST)) may not work because pperl’s runtime doesn’t replay those effects. Package-variable side effects work correctly.