whsv26/functional
Functional programming primitives for PHP: Option, Either, Pair, and immutable collections with map, filter, fold, and pattern matching. Handle nulls and errors without exceptions, chain transformations safely, and write expressive, side-effect-free code that works with Laravel and static analysis.
Result/Either type is ~100 lines to write in-house; a type-safe generic collection with working PHPStan/Psalm annotations is not. The package bundles both, so the buy decision should be split: buy the collection and monad vocabulary, build nothing, but budget a half-day to verify static-analysis behaviour against your own PHPStan level before committing.Result and Option types convert implicit failure modes (null returns, swallowed exceptions, mixed collections) into compile-time-visible contracts. That gives you a defensible roadmap item measured in defect rate and static-analysis findings, not in "code cleanliness."Result/Option makes it cheap to model partial-success and multi-failure flows (batch imports, webhook processing), which often unlocks product features that were previously deferred as "too messy to handle errors for."Consider adoption when:
mixed from Laravel's untyped Collection. Type-safe generics are the single strongest justification here.Look elsewhere (or build a 150-line Result instead) when:
ModelNotFoundException, the validation exception flow, and Laravel's central exception handler are the idiomatic, well-documented error path; wrapping them in Result creates impedance mismatch at every boundary and buys little.Illuminate\Support\Collection / LazyCollection and the mental-model overlap would cause confusion rather than clarity.Adjacent alternatives worth benchmarking before deciding: native PHP 8 nullsafe/union types plus enums for simple cases, Laravel's Pipeline for composition, and a hand-rolled Result for the narrow error-handling use case.
To executives — one paragraph: This is a small, MIT-licensed PHP library that makes failure and absence explicit in code rather than implicit. We are evaluating it for a limited, high-value area — [payments / integrations / data import] — not as a platform-wide rewrite. It carries no licence cost and no vendor lock-in; the realistic downside is engineering time, capped at [X days] for a spike plus [Y days] if we adopt. The upside is a measurable reduction in the class of bugs that come from unhandled nulls and swallowed exceptions, plus stronger automated checking of our code. Recommendation: fund a timeboxed spike in one bounded context, with a go/no-go decision at the end.
To engineering — the substance: The differentiated value is not the monads, it's the generic collections with proper static-analysis annotations, which close a real gap in Laravel's Collection. Result/Option give us explicit error paths in domain code where exceptions are the wrong tool. The costs are honest: a learning curve, a boundary layer where we convert framework exceptions into Result and back, and the fact that this is a ~200-star package — mitigated by MIT licensing and a small surface area we could fork. Ask engineering to answer three questions in the spike: does it hold up at our PHPStan level, what does the Eloquent/HTTP boundary conversion actually look like, and will a non-FP-enthusiast on the team be productive in it after a week.
To the team — the framing: We are trying this in one place, with a named owner, and we will stop if it doesn't pay for itself. Nobody is being asked to rewrite working code.
How can I help you explore Laravel packages today?