Primitives for functional programming in PHP

Overview

Functional PHP: Functional primitives for PHP

Test

NOTE: functional-php used to come with a C extension that implemented most of the functions natively. As the performance differences weren’t that huge compared to the maintenance cost it has been removed.

A set of functional primitives for PHP, heavily inspired by Scala’s traversable collection, Dojo’s array functions and Underscore.js

  • Works with arrays and everything implementing interface Traversable
  • Consistent interface: for functions taking collections and callbacks, first parameter is always the collection, then the callback. Callbacks are always passed $value, $index, $collection. Strict comparison is the default but can be changed
  • Calls 5.3 closures as well as usual callbacks
  • All functions reside in namespace Functional to not raise conflicts with any other extension or library

Functional Comic

Installation

Run the following command in your project root:

composer require lstrojny/functional-php

Docs

Read the docs

Contributing

  1. Fork and git clone the project
  2. Install dependencies via composer install
  3. Run the tests via composer run tests
  4. Write code and create a PR

Mailing lists

Thank you

Comments
  • Introduce autocurring and function composition

    Introduce autocurring and function composition

    What do you think about introducing to functional php autocurring and function composition?

    I have created working prototype of library with autocurring, function composition and making$collection as last argument: https://github.com/psliwa/rfp

    In my opinion it looks promising, allows to take advantage of functional programming in even better way. There is the chance to make new release, aka "functional php 2"?

    opened by psliwa 16
  • hashMap

    hashMap

    For my own use I wrote a function called hashMap to create associative arrays:

    >>> hashMap(
    ...     ['abc', 'foobar'],
    ...     function ($value) {
    ...         return [$value[0], $value];
    ...     }
    ... )
    => [
         "a" => "abc",
         "f" => "foobar",
       ]
    
    function hashMap($collection, callable $callback)
    {
        InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1);
    
        $aggregation = [];
    
        foreach ($collection as $index => $element) {
            list($key, $value) = $callback($element, $index, $collection);
            $aggregation[$key] = $value;
        }
    
        return $aggregation;
    }
    

    Is this something that would also be useful to others? If yes, I can prepare a proper pull request. Of course it can be named differently if there is a better term for what this function does.

    opened by MazeChaZer 14
  • Memoize as a high order function

    Memoize as a high order function

    What do you think about transforming the memoize function into a high order function? I think it would become easier to use from the client perspective and it may simplify its internal implementation. I'm thinking of something like

    function memoize(callable $function, callable $hashGenerator = null) {
        if (null === $hashGenerator) {
            $hashGenerator = function(array $arguments) {
                // ...
            }
        }
    
        return function (...$arguments) use ($function, $hashGenerator) {
            static $localCache = [];
    
            $key = $hashGenerator($arguments);
    
            if (!array_key_exists($key, $localCache)) {
                $localCache[$key] = $callback(...$arguments);
            }
    
            return $localCache[$key];
        };
    }
    
    Feature 
    opened by theUniC 12
  • Add `ary` function which ignores arguments over the supplied number

    Add `ary` function which ignores arguments over the supplied number

    Added function which defines a function of an arbitry number of arguments and calls the provided callable with only the given number of arguments

    Didn't add tests as it wasn't obvious how they worked and wanted feedback before investing the time

    opened by someonewithpc 11
  • Add `entries` and `from_entries`, similar to JavaScript's `Object.entries` and `Object.fromEntries`

    Add `entries` and `from_entries`, similar to JavaScript's `Object.entries` and `Object.fromEntries`

    Previous title: Add enumerate, similar to Python's

    This PR adds an enumerate(Transversable|array, int=) function that acts like Python's enumerate

    foreach (enumerate($this->hash) as $i => [$k => $v]) {
        // ...
    }
    

    My use case is to iterate over an array with string keys and have an associated integer that can be used as an ID

    opened by someonewithpc 10
  • Add tap()

    Add tap()

    tap() calls the given $callback with the given $value, which, in quite a few cases, makes the code read more fluent and "functional":

    tap(User::create('John Doe'), function (User $user) {
        UserService::sendWelcomeEmail($user);
    })->login();
    
    // or
    
    tap(DisposableEmail::create('From Nigerian Prince with luv'), function (Email $email) {
        EmailManager::send($email);
    })->destroy();
    

    This function is inspired by Laravel, which is in turn inspired by Ruby.

    opened by phanan 8
  • [RFC] provide a `not` function

    [RFC] provide a `not` function

    Is it me or one currently can't invert a boolean-returning function ?

    I'd like a not function looking like:

    namespace Functional;
    
    function not(callable $callback) {
        return function($value) use ($callback) {
            return !$callback($value);
        };
    }
    

    see https://3v4l.org/G3vtd for a working impl.

    Do you think it's a good idea? If yes, I can try to make a PR.

    Thanks!

    opened by docteurklein 8
  • Multiple fn version of partition()

    Multiple fn version of partition()

    Partition() currently only accepts one predicate function and splits an array in to two partitions, putting elements which pass in the first, and those which fail in the second.

    Partition() should accept n predicate functions, create n+1 partitions, and place each element in the partition of the first predicate it matches, with unmatched ones in the last.

    In the case of single predicate function the behavior should be unchanged.

    opened by mkrauss 8
  • Semigroup, Monoid, Functor, Monad and basic Option implementation

    Semigroup, Monoid, Functor, Monad and basic Option implementation

    I've added a few functional typeclasses using interfaces.

    Also, this PR provides a basic implementation of Scala Option (or Haskell Maybe). Option implements all included interfaces and comes with unit tests.

    opened by ornicar 8
  • Implement sort_by

    Implement sort_by

    I implemented the function, but tests for it are failing, because for some reason PHPUnit thinks that the sort_by function is not defined. I don't know why that error occurs, as far as I can see the function is defined and used correctly. @lstrojny Can you help me with this one?

    Fixes #162

    opened by gvlasov 7
  • Flat map with key preservation

    Flat map with key preservation

    I found myself in need of such a function

    So you could transform a list to a dictionary like so:

    $dictionary = flatMapWithKeys($list, function($element) {
        $key = ...
        $value = ...
        return [
            $key => $value,
        ];
    });
    

    Naive implementation would be something like this:

    function flatMapWithKeys(array $array, callable $fn)
    {
        $result = [];
        foreach ($array as $key => $value)
        {
            $result += $fn($value, $key);
        }
        return $result;
    }
    

    Would this be useful?

    opened by Erikvv 7
  • Add iterable to the method definitions

    Add iterable to the method definitions

    Hi,

    since PHP 7.1 one can use iterable type hint for everything that is iterable, including array and Traversable.

    I know this lib shall also work for older PHP version, but adding iterable to the phpdoc-block would not hurt.

    Currently IDE's and other tools throw warnings when I pass an iterable instead of an array or a Traversable.

    Suggestion:

    Add iterable to all doc-blocks.

    Best Regards Martin

    opened by mschop 0
  • `take_left(sequence_linear(date('Y') - 3, 1), 3)` infinite loop

    `take_left(sequence_linear(date('Y') - 3, 1), 3)` infinite loop

    Expected take_left to support iterators without requiring fully iterating through it. Because sequence_linear returns an infinite iterator the take_left function is never able to provide the first $count of iteration values due to its use of array_to_iterator.

    opened by Maxdw 0
  • Use php-quickcheck for testing

    Use php-quickcheck for testing

    Generative testing looks ideal for Functional PHP and https://github.com/steos/php-quickcheck looks like a good implementation.

    TBD

    • [ ] weither to use it inside of PHPUnit or not. First instinct is rather not but the question is weither it's sensible to port tests like FunctionalTest and AnnotationsTest
    opened by lstrojny 0
  • Updating Pipe Tests for psalm branch

    Updating Pipe Tests for psalm branch

    Surprised to see InvalidArgumentException::assertCallback was removed with no apparent substitute on sight, implemented check for callables inside Pipe functor construction, and adding some docblocks that Psalm complained about.

    opened by tzkmx 0
Releases(1.17.0)
Owner
Lars Strojny
CTO @InterNations
Lars Strojny
sample code for several design patterns in PHP 8

DesignPatternsPHP Read the Docs of DesignPatternsPHP or Download as PDF/Epub This is a collection of known design patterns and some sample codes on ho

null 21k Jan 1, 2023
Option Type for PHP

PHP Option Type This package implements the Option type for PHP! Motivation The Option type is intended for cases where you sometimes might return a v

Johannes 2.4k Dec 26, 2022
A Simple PHP Finite State Machine

Finite, A Simple PHP Finite State Machine Finite is a Simple State Machine, written in PHP. It can manage any Stateful object by defining states and t

Yohan Giarelli 1.3k Dec 31, 2022
A simple stateless production rules engine for PHP 5.3+

Ruler Ruler is a simple stateless production rules engine for PHP 5.3+. Ruler has an easy, straightforward DSL ... provided by the RuleBuilder: $rb =

Justin Hileman 1k Dec 28, 2022
Powerful implementation of the Specification pattern in PHP

RulerZ The central idea of Specification is to separate the statement of how to match a candidate, from the candidate object that it is matched agains

Kévin Gomez 865 Dec 22, 2022
A simple Monad library for PHP

MonadPHP This is a basic Monad library for PHP. Usage Values are "wrapped" in the monad via either the constructor: new MonadPHP\Identity($value) or t

Anthony Ferrara 283 Dec 29, 2022
YCOM Impersonate. Login as selected YCOM user 🧙‍♂️in frontend.

YCOM Impersonate Login as selected YCOM user in frontend. Features: Backend users with admin rights or YCOM[] rights, can be automatically logged in v

Friends Of REDAXO 17 Sep 12, 2022
PHP Functional Programming library. Monads and common use functions.

Functional PHP PHP Functional Programming library. Monads and common use functions. Documentation Functions Monads Installation Composer $ composer re

Alexander Sv. 169 Dec 27, 2022
A simple functional programming library for PHP

bingo-functional A simple functional programming library for PHP. Requirement(s) PHP 7 or higher Rationale PHP, a language not commonly associated wit

Lochemem Bruno Michael 52 Sep 28, 2022
Small library providing some functional programming tools for PHP, based on Rambda

Functional library for PHP. Features: set of useful functions helpful in functional programming all functions are automatically curried every array ca

Wojciech Nawalaniec 5 Jun 16, 2022
Iteration primitives using generators

Iteration primitives using generators This library implements iteration primitives like map() and filter() using generators. To a large part this serv

Nikita Popov 1.1k Dec 31, 2022
Dictionary of attack patterns and primitives for black-box application fault injection and resource discovery.

FuzzDB was created to increase the likelihood of finding application security vulnerabilities through dynamic application security testing. It's the f

FuzzDB Project 7.1k Dec 27, 2022
A complete and fully-functional implementation of the Jade template language for PHP

Tale Jade for PHP Finally a fully-functional, complete and clean port of the Jade language to PHP — Abraham Lincoln The Tale Jade Template Engine brin

Talesoft 91 Dec 27, 2022
A functional and simple rate limit control to prevent request attacks ready-to-use for PHP.

RateLimitControl A functional and simple rate limit control to prevent request attacks ready-to-use for PHP. Features: Prepared statements (using PDO)

b(i*2)tez 5 Sep 16, 2022
PHP libraries that makes Selenium WebDriver + PHPUnit functional testing easy and robust

Steward: easy and robust testing with Selenium WebDriver + PHPUnit Steward is a set of libraries made to simplify writing and running robust functiona

LMC s.r.o. 219 Dec 17, 2022
A functional Prison Management Portal completely developed on php

A functional Prison Management Portal completely developed on php, Inspired by existing models. With interactive modules, and high scalability because of MySQL.

Tuhin Chakrabarty 3 Jul 16, 2022
Attempting to create an intelligent mock of the Google API PHP Client for unit and functional testing

google-api-php-client-mock A small scale intelligent mock of the Google API PHP Client for unit and functional testing. Overview This is intended to m

SIL International 0 Jan 4, 2022
Simple library that abstracts different metrics collectors. I find this necessary to have a consistent and simple metrics (functional) API that doesn't cause vendor lock-in.

Metrics Simple library that abstracts different metrics collectors. I find this necessary to have a consistent and simple metrics API that doesn't cau

Benjamin Eberlei 311 Nov 20, 2022
Workout application with fully functional Frontend and Backend.

Fit_Me_Application About Application: This FIT-ME management system is an easy way to use gym and health membership system. It can help to keep the re

Talha 3 Feb 20, 2022