Releases: abitofhelp/functional
Release 4.1.0
Deprecated
Result-based Try functions (procedural Map_Exception pattern)
Try_To_Result- UseFunctional.Try.Map_To_ResultTry_To_Any_Result_With_Param- UseFunctional.Try.Map_To_Result_With_ParamTry_To_Functional_Result- UseFunctional.Try.Map_To_ResultTry_To_Result_With_Param- UseFunctional.Try.Map_To_Result_With_Param
Rationale: Declarative exception mappings (data) are clearer and more
maintainable than procedural Map_Exception functions (code). The Map
versions use a mapping array that is self-documenting and allows multiple
exception-to-error-kind discriminations without if/elsif chains.
Note: Option-based Try functions (Try_To_Functional_Option,
Try_To_Option_With_Param) are NOT deprecated. They serve valid use cases
for "probe" operations with sensible defaults where error details don't matter.
Changed
Functional.Try.To_Result- Reimplemented with inline exception handling
instead of delegating to deprecatedTry_To_Functional_Result. This eliminates
deprecation warnings when building the functional library itself.Functional.Try.To_Option- Reimplemented with inline exception handling
instead of delegating toTry_To_Functional_Option(consistency).- Added "When to Use Option" documentation section to
functional-try.ads
Fixed
- Suppress expected warnings in test suite:
test_try.adb: obsolescent warnings (testing deprecated functions still work)test_scoped.adb: "condition is always True" (intentional test pattern)
- Added
*__GNATPP-TEMPto.gitignore(GNAT Pretty Print temp files)
Technical Details
- Test Coverage: 269 unit tests (all passing)
- SPARK Status: 410 checks: 8 flow, 401 proved, 1 unproved (~98% proved)
SPARK Formal Verification
| Metric | Result |
|---|---|
| Status | Verified |
| Mode | gnatprove --mode=prove --level=2 |
| Results | 410 checks: 8 flow, 401 proved, 1 unproved |
Verified using SPARK Ada formal verification tools.
Release 4.0.0
Test Coverage: 269 unit + 0 integration + 0 examples = 269 total
BREAKING CHANGES
- Removed exception-raising functions from Result and Option
Expectremoved from Result (was: extract value or raise Program_Error)Expect_Errorremoved from Result (was: extract error or raise Program_Error)Unwrap_Errorremoved from Result (was: extract error with precondition)Expectremoved from Option (was: extract value or raise Program_Error)
Rationale:
- Functional programming principle: Errors should be values, not exceptions.
Exception-based control flow violates the core tenet of functional error handling. - SPARK compatibility: SPARK formal verification prohibits exceptions.
These functions were incompatible with SPARK_Mode => On despite the package annotation. - Architectural consistency: The functional crate should model pure functional
patterns without exception escape hatches.
Migration:
-- Old (3.0.0): Uses exception
Val := Int_Result.Expect (R, "Expected Ok");
-- New: Use precondition + Value (compile-time safety)
pragma Assert (Int_Result.Is_Ok (R));
Val := Int_Result.Value (R);
-- Or: Use Unwrap_Or for default fallback
Val := Int_Result.Unwrap_Or (R, Default_Value);Added
New Exception Mapping Packages
Functional.Try.Map_To_Result- Declarative exception-to-Result mapping with
configurable exception→error kind tables. Supports empty mappings (catch-all)
or specific exception discrimination.Functional.Try.Map_To_Result_With_Param- Parameterized version for actions
requiring input context (file paths, user IDs, etc.). Supports indefinite types.
New RAII Resource Management
Functional.Scoped.Guard_For- Unconditional RAII guard for automatic resource
cleanup. Calls Release procedure when guard goes out of scope.Functional.Scoped.Conditional_Guard_For- Conditional RAII guard that checks
Should_Release predicate before calling Release.
New Tests
- 11 tests for
Functional.Scopedcovering normal exit, exception paths,
multiple guards, conditional release, and exception-safe Finalize behavior. - 35 tests for
Map_To_ResultandMap_To_Result_With_Paramcovering
success paths, mapped exceptions, unmapped exceptions, and catch-all behavior.
Fixed
- Hardened Finalize in Scoped -
Finalizeprocedures now catch all exceptions
to prevent exception propagation during stack unwinding (which causes
Program_Error or termination). - Keyword casing - Fixed
in Outtoin outin generic formal parameters. - Comment clarity - Fixed misleading "order doesn't matter" comment in
Map_To_Result; now correctly states "first match wins if duplicates exist".
Changed
- Operation counts:
- Result: 33 operations (was 36, removed Expect/Expect_Error/Unwrap_Error)
- Option: 25 operations (was 26, removed Expect)
- Try: 7 operations (was 5, added Map_To_Result variants)
- Scoped: 2 generic packages (new)
Technical Details
- All 269 unit tests passing
- SPARK proved (Option, Result, Either, Version)
- Scoped uses SPARK_Mode => Off (requires Ada.Finalization)
- Zero heap allocation maintained
SPARK Formal Verification
| Metric | Result |
|---|---|
| Status | Verified |
| Mode | gnatprove --mode=prove --level=2 |
| Results | 68 checks: 0 flow, 68 proved, 0 unproved |
Verified using SPARK Ada formal verification tools.
Release 3.0.0
⚠️ BREAKING CHANGES
- Boolean discriminants replace enumeration discriminants
- Option:
Kind→Has_Value(Boolean) - Result:
Kind→Is_Ok(Boolean),Err_Value→Error_Value - Either:
Kind→Is_Left(Boolean)
- Option:
- Result API renaming for clarity
Err→New_Error(constructor)Is_Err→Is_Error(predicate)Map_Err→Map_Error(transform)
- Try module generic formal renamed:
Err→New_Error
Added
Documentation
docs/guides/cheatsheet.md- All types and operators on 1-2 pagesdocs/guides/user_guide.md- Design philosophy, SPARK, embedded, best practices
Result (36 operations, +16 new)
Zip_With- Combine two Results with a functionFlatten- Unwrap nested Result[Result[T,E],E] → Result[T,E]To_Option- Convert Ok(v) → Some(v), Error(_) → NoneContains- Check if Ok value equals given valueIs_Ok_And- Test if Ok and predicate holds (strict)Is_Error_And- Test if Error and predicate holds (strict)Is_Ok_Or- Test if Error or predicate holds on Ok (lenient)Is_Error_Or- Test if Ok or predicate holds on Error (lenient)Expect_Error- Extract error or raise with messageUnwrap_Error- Extract error (Pre: Is_Error)Map_Or- Transform Ok value or return default (eager)Map_Or_Else- Transform Ok value or call default producer (lazy)Tap_Ok- Side effect on Ok onlyTap_Error- Side effect on Error only"or"operator forUnwrap_Or-R or Defaultsyntax"or"operator forFallback-A or Bsyntax"="operator forContains-R = Vsyntax
Option (26 operations, +15 new)
"and"operator - Returns second when both have values"xor"operator - Returns one when exactly one has valueZip_With- Combine two Options with a functionFlatten- Unwrap nested Option[Option[T]] → Option[T]Ok_Or- Convert Some(v) → Ok(v), None → Error(e) (eager)Ok_Or_Else- Convert Some(v) → Ok(v), None → Error(f()) (lazy)Contains- Check if Some value equals given valueIs_Some_And- Test if Some and predicate holds (strict)Is_None_Or- Test if None or predicate holds on Some (lenient)Expect- Extract value or raise with messageMap_Or- Transform Some value or return default (eager)Map_Or_Else- Transform Some value or call default producer (lazy)Tap- Side effect on Some value"or"operator forUnwrap_Or-O or Defaultsyntax"or"operator forOr_Else-A or Bsyntax"="operator forContains-O = Vsyntax
Either (20 operations, +12 new)
Map- Right-biased transform (convenience for common case)Swap- Exchange Left and Right valuesAnd_Then- Right-biased monadic bind for chainingContains- Check if Right value equals given valueIs_Left_And- Test if Left and predicate holds (strict)Is_Right_And- Test if Right and predicate holds (strict)Is_Left_Or- Test if Right or predicate holds on Left (lenient)Is_Right_Or- Test if Left or predicate holds on Right (lenient)Get_Or_Else- Get Right value or defaultMerge- Extract value when both types are the sameTo_Option- Convert Right(v) → Some(v), Left(_) → NoneTo_Result- Convert Right(v) → Ok(v), Left(e) → Error(e)"="operator forContains-E = Vsyntax
Migration Guide (2.x → 3.0.0)
Discriminant access:
-- Old (2.x)
if R.Kind = K_Ok then ...
if O.Kind = K_Some then ...
-- New (3.0.0)
if R.Is_Ok then ...
if O.Has_Value then ...Result constructors/predicates:
-- Old (2.x)
Str_Result.Err (E);
if Str_Result.Is_Err (R) then ...
-- New (3.0.0)
Str_Result.New_Error (E);
if Str_Result.Is_Error (R) then ...Map_Error:
-- Old (2.x)
function Transform is new Str_Result.Map_Err (F => ...);
-- New (3.0.0)
function Transform is new Str_Result.Map_Error (F => ...);SPARK and Embedded Compliance (NEW)
SPARK_Mode => Onfor Option, Result, Either (formally verifiable)SPARK_Mode => Offfor Try (exception boundary, by design)Preelaboratecategorization for Result, EitherPurecategorization for Version- Postconditions added to all transform operations for prover assistance
- Zero heap allocation, no controlled types, Ravenscar compatible
Technical Details
- All 227 unit tests passing (Result: 84, Option: 65, Either: 58, Try: 14, Try_Option: 6)
- Tested on POSIX (macOS, Linux) and Windows platforms
- stmt+decision coverage: 95%+
- Total operations: 87 (Result: 36, Option: 26, Either: 20, Try: 5)
Release 2.3.0
Added
- Expanded test coverage: Added tests for previously uncovered functions
Result.From_Error(boundary constructor - 3 tests)Result.And_Then_Into(type-changing monadic chain - 5 tests)Either.Map_Left(both Left and Right input paths)Either.Map_Right(both Left and Right input paths)Try.Try_To_Result_With_Param(success and exception paths)Try.Try_To_Option_With_Param(success and exception paths)- Coverage improved: 89% → 95% (exceeds 90% target)
Changed
- Documentation regeneration: Complete refresh of all documentation per documentation agent standards
- quick_start.md: Regenerated with all 44 operations (Result: 20, Option: 11, Either: 10, Try: 5)
- Added Map, Map_Err, Bimap examples for Result
- Added Filter example for Option
- Added Map_Left, Map_Right, Bimap, Fold examples for Either
- Added Try_To_Option and Try_To_Option_With_Param sections
- Added Tap/logging pattern to Common Patterns
- Formal docs (SRS, SDS, STG): Completely regenerated for functional library
- Previous content was from TZif project (incorrect)
- SDS now correctly describes nonhybrid utility library (not hexagonal architecture)
- Source file docstrings: Updated headers with operation counts and purpose descriptions
- config/README.md: Updated version to 2.3.0
- quick_start.md: Regenerated with all 44 operations (Result: 20, Option: 11, Either: 10, Try: 5)
- Project cleanup: Removed orphaned shared/ directory (release script generates to src/version/)
- GPR cleanup: Removed Documentation package reference (docs/api doesn't exist)
Fixed
- Release script library detection: Added GPR-based project type detection
- Checks for
Library_NameorLibrary_Kindin GPR files - Correctly identifies nonhybrid utility libraries (like functional) as libraries
- Prepares for future distinction: hybrid_app, hybrid_lib, nonhybrid_lib
- Checks for
- Documentation terminology: Updated Try.ads comment to use "Boundary adapters" instead of "Infrastructure/Presentation" to avoid false positives in release validation
Technical Details
- All 101 unit tests passing (Result: 43, Option: 22, Either: 16, Try: 14, Try_Option: 6)
- stmt+decision coverage: 95%+
- All 20 Result operations now have tests (From_Error, And_Then_Into added)
Release 2.2.1
Added
- ROADMAP marker scanning: Release script now detects ROADMAP markers alongside TODO/FIXME/STUB
- ROADMAP markers indicate planned future work tracked in roadmap.md
- Helps identify deferred features during release preparation
Fixed
- Library_Name casing: Changed from
"Functional"to"functional"in functional.gpr- Fixes GPRbuild elaboration object lookup (
p__functional_0.ovsp__Functional_0.o) - Follows GNAT convention: library name matches lowercase project filename
- Eliminates
ar: p__functional_0.o: not found in archivewarning in dependent projects
- Fixes GPRbuild elaboration object lookup (
- Alire deployment: Add
export-ignorefor submodules (scripts/python,test/python,docs/common) to prevent path collisions with dependencies during Alire source archive creation
Release 2.2.0
Added
- Preelaborate pragma for Option: Added
Preelaboratecategorization toFunctional.Option- Allows Option to be instantiated in preelaborable packages
- Enables use in domain/application layers with strict elaboration requirements
- Backwards compatible: only expands where Option can be used, no breaking changes
Technical Details
- All 83 Ada tests passing
- Zero breaking changes from 2.1.1
Release 2.1.1
Added
- Test Build Mode: Added "test" mode to functional.gpr for compatibility with downstream projects that use
-Xmode=test- Supports test-specific compiler flags (debug info, assertions, validity checks)
- Enables symbolic tracebacks in test mode
Release 2.1.0
Added
- Parameterized Try Functions: Enhanced exception handling with input context support
Try_To_Result_With_Param- Parameterized Result bridge for actions requiring input (e.g., console messages, file paths, user IDs)Try_To_Option_With_Param- Parameterized Option bridge for actions with input context- Support for indefinite types (String, unconstrained arrays) via
type Param (<>) is privategeneric formal parameter - Eliminates need for module-level mutable state and unsafe
Unchecked_Accesspatterns
- Backwards-Compatible Child Packages: Restored legacy API for existing code
Functional.Try.To_Result- Child package wrappingTry_To_Functional_Resultwith.RunAPIFunctional.Try.To_Option- Child package wrappingTry_To_Functional_Optionwith.RunAPI- Zero breaking changes - all existing test code continues to work unchanged
Changed
- Enhanced Documentation: Updated API documentation with parameterized Try usage patterns
- Added examples showing safe parameter passing without
Unchecked_Access - Documented indefinite type support (
type Param (<>) is private) - Updated architecture notes explaining exception boundary conversion
- Added examples showing safe parameter passing without
- Build Infrastructure: Modernized build system with standardized tooling
- Adopted Makefile from simple_hybrid with architecture validation (
check-arch) - Added cleanup utilities (
clean-clutter), Python testing (test-python), and tool installation targets - Renamed
tests/directory totest/for consistency with project standards - Updated test infrastructure to work with relocated
scripts/makefile/arch_guard.py - Professional colored test output with bordered success/failure banners
- Adopted Makefile from simple_hybrid with architecture validation (
Fixed
- Type Safety: Generic formal parameters now support indefinite types (String, unconstrained arrays)
- Thread Safety: Parameterized approach eliminates module-level mutable state in client code
Technical Details
- All 83 Ada tests passing (Result: 35, Option: 22, Either: 12, Try: 14)
- All 35 Python tests passing (arch_guard validation suite)
- Zero unsafe code patterns required for using Try functions with parameters
- Fully backwards compatible with 2.0.0 API
Release 2.0.0
⚠️ BREAKING CHANGES
- Try Module API Redesign: Complete refactoring of exception handling
Changed
- Try Module: Redesigned for maximum flexibility
- Renamed
Functional.Try.To_Result→Functional.Try.Try_To_Result - Renamed
Functional.Try.To_Option→Functional.Try.Try_To_Functional_Option - Added
Functional.Try.Try_To_Functional_Result(convenience for Functional.Result) Try_To_Resultnow works with any Result type (domain-specific, custom implementations)- Consolidated all Try functions into single
Functional.Trypackage - Removed child packages
Functional.Try.To_ResultandFunctional.Try.To_Option - Generic parameters allow bridging to any Result implementation with custom
Ok/Errconstructors
- Renamed
Added
- Generic
Try_To_Resultsupports custom Result types with configurable constructors - Example code showing usage at infrastructure boundaries
- Comprehensive documentation for Try pattern in README
Migration Guide (1.0.0 → 2.0.0)
Old Code (1.0.0):
with Functional.Try.To_Result;
with Functional.Try.To_Option;
function Try_Read is new Functional.Try.To_Result (...);
function Try_Parse is new Functional.Try.To_Option (...);New Code (2.0.0):
with Functional.Try;
-- For custom domain Result types:
function Try_Read is new Functional.Try.Try_To_Result
(T => Integer_32, E => Error_Type,
Result_Type => Domain_Result.Result,
Ok => Domain_Result.Ok,
Err => Domain_Result.From_Error,
Map_Exception => From_Exception,
Action => Raw_Read);
-- For Functional.Result:
function Try_Parse is new Functional.Try.Try_To_Functional_Result
(T => String, E => Error,
Result_Pkg => Str_Result,
Map_Exception => From_Exception,
Action => Raw_Parse);
-- For Functional.Option:
function Try_Lookup is new Functional.Try.Try_To_Functional_Option
(T => Integer,
Option_Pkg => Int_Option,
Action => Raw_Lookup);v1.0.0 - Initial Release
[1.0.0] - 2025-10-25
Overview
Initial stable release of the Functional library for Ada 2022, providing type-safe
functional programming abstractions including Result<T,E>, Option, Either<L,R>,
and Try utilities (To_Result, To_Option) for exception handling.
Added
-
Core Types:
Functional.Result<T,E>- Type-safe error handling with 17 operationsFunctional.Option<T>- Optional values with 11 operationsFunctional.Either<L,R>- Disjoint union type with 8 operationsFunctional.Try.To_Result- Convert exception-based code to ResultFunctional.Try.To_Option- Convert exception-based code to Option
-
Result Operations:
- Constructors:
Ok,Err - Predicates:
Is_Ok,Is_Err - Extractors:
Value,Error,Expect(with custom error messages) - Unwrapping:
Unwrap_Or,Unwrap_Or_With - Transformations:
Map,And_Then,Map_Err,Bimap - Recovery:
Fallback,Fallback_With,Recover,Recover_With - Validation:
Ensure,With_Context - Side effects:
Tap - Postconditions on
Unwrap_Orfor contract verification
- Constructors:
-
Option Operations:
- Constructors:
New_Some,None - Predicates:
Is_Some,Is_None - Extractors:
Value - Unwrapping:
Unwrap_Or,Unwrap_Or_With - Transformations:
Map,And_Then,Filter - Fallback:
Or_Else,Or_Else_With,Fallback(alias) - Postconditions on
Unwrap_Orfor contract verification
- Constructors:
-
Either Operations:
- Constructors:
Left,Right - Predicates:
Is_Left,Is_Right - Extractors:
Left_Value,Right_Value - Transformations:
Bimap(transform both sides),Fold(reduce to single value)
- Constructors:
-
Exception Handling:
Functional.Try.To_Result- Convert exception-raising code to Result<T,E>Functional.Try.To_Option- Convert exception-raising code to Option- Full exception information preservation in Try.To_Result
-
Testing:
- 83 comprehensive unit tests achieving 100% function coverage
- All packages tested with 90%+ code coverage target
- Test framework with aggregated reporting
-
Code Quality:
- Package-level generics (Ada 2022 best practice)
- Inline annotations for compiler optimization
- Preconditions and postconditions for contract programming
- Comprehensive API documentation with usage examples
- Line length convention: 120 characters for code, 80 characters for comments