A simple functional programming library for PHP

Overview

bingo-functional

Join the chat at https://gitter.im/bingo-functional/Lobby StyleCI bingo-functional CI codecov Latest Stable Version License Total Downloads Monthly Downloads composer.lock Twitter

A simple functional programming library for PHP.

Requirement(s)

  • PHP 7 or higher

Rationale

PHP, a language not commonly associated with Functional Programming, does support the paradigm - to an extent. The language's Functional Programming affability though substantial is not the same as that of Haskell, OCaml, or F# - purely Functional languages. bingo-functional is an attempt at enhancing the usability of FP techniques - those that warrant the use of helper functions, applicatives, monads, pattern matching, and immutable lists.

Documentation

Please check out the documentation for more knowledge on how to use this library.

Also, a changelog exists and can be used to track changes made to the project.

Dealing with problems

Endeavor to create an issue on GitHub when the need arises or send an email to [email protected]

Functional Programming in PHP

I published a book titled - Functional Programming in PHP - which is currently available on LeanPub. The bingo-functional library features extensively in the text as a tool whose potencies demonstrate usage of Functional Programming ideas in PHP. I advise that you purchase a copy for $9.99.

Related Projects

Buy Me A Coffee

Comments
  • Recursion vs Loop structures

    Recursion vs Loop structures

    I have implemented recursive functions in the structures of multiple helper functions map, filter, and fold inclusive. I recently ran some tests to ascertain the potency of said implementations and the results - higher memory usage for large data sets even with trampoline optimization - triggered a contemplation of the perks of PHP loops. I ran some more tests centered around the usage of foreach loops and discovered a performance increment for large datasets.

    My current dilemma is this: I am not willing to revert to PHP loops but want to find a way to justify the recursion implemented in the library.

    help wanted question 
    opened by ace411 13
  • Integrate the coding style tool/service

    Integrate the coding style tool/service

    As we see, the package doesn't follow the PSR-2 coding style. To fix this coding style issue automatically, I suggest we can use the PHP-CS-Fixer or StyleCI to complete this issue.

    opened by peter279k 8
  • getOrElse method in Nothing class is strange

    getOrElse method in Nothing class is strange

    Consider the following code snippet:

    public function getOrElse($default)
    {
            return $this;
    }
    

    I don't know the type of $default and pass the correct variable to this method.

    And the getter method should not require any argument I think.

    Maybe this method should be changed into:

    public function getOrElse(Maybe $maybe)
    {
            return $this->orElse(Maybe $maybe);
    }
    

    @ace411 , what do you think?

    opened by peter279k 6
  • Replace the self-defined functions with the PHP native functions

    Replace the self-defined functions with the PHP native functions

    As title. According to the Unique function, it looks like we use the foreach loop to try to get the unique array on specific array collection.

    But the PHP has the native array_unique function to help us to get the unique array quickly without using the foreach loop.

    I think we can use the native PHP functions easily and it will be better than using foreach loop.

    investigation required 
    opened by peter279k 4
  • Compact function purges TRUE from an array.

    Compact function purges TRUE from an array.

    The description of the Compact function says that it purges an array of falsey values (null, false). It means that true should stay in the array, right? Though, that test will fail:

    $mixed = [1, 2, 'foo', false, null, true];
    $purged = A\compact($mixed);
    $this->assertEquals([1, 2, 'foo', true], $purged);
    

    It seems that either the function description is incorrect or the function does not function properly.

    bug investigation required 
    opened by OlexandrPopov 3
  • Just::ap should pass a callable to the Monadic::map method

    Just::ap should pass a callable to the Monadic::map method

    Take a look at this line https://github.com/ace411/bingo-functional/blob/4ce0f4d620b63bf0c4e77ceee46ef7c9a4563c77/src/Functors/Maybe/Just.php#L85

    At present it passes $this but the Monadic::map method requires a callable.

    opened by OlexandrPopov 3
  • getJust method in Nothing class is strange

    getJust method in Nothing class is strange

    Consider the following code snippet:

    public function getJust()
    {
    }
    

    It looks strange because this method does nothing after using that.

    I think it should return null because it's the Nothing class :+1:.

    opened by peter279k 3
  • Improve the Pattern Matching Algorithm

    Improve the Pattern Matching Algorithm

    Implemented in v1.9.0 along with a variety of helper functions was the patternMatch() function. It has undergone several modifications since its inception and still feels a bit incomplete. Why - one might ask? The snippet below evaluates to a wildcard pattern when it should not.

    use function \Chemem\Bingo\Functional\PatternMatching\patternMatch;
    
    $match = patternMatch(
      [
        '[_, "foo"]' => function () { return 'first-pattern'; },
        '_' => function () { return 'wildcard'; }
      ],
      explode('/', 'api/foo')
    );
    

    The snippet above is a syntactical facsimile of the Haskell code shown below which evaluates to the string, first-pattern.

    patternMatch :: [a] -> a
    patternMatch (_,  foo) = "first-pattern"
    patternMatch _ = "wildcard"
    

    I intend to fix the problem that is the current patternMatch function's inability to reconcile list patterns that contain wildcards in them.

    bug enhancement 
    opened by ace411 3
  • PHP 8+ compatibility

    PHP 8+ compatibility

    The dependency functional-php/pattern-matching (which looks unmaintained) is using match, which is a reserved word in PHP 8.0 since it now has a built-in pattern matching. That breaks library's compatibility with newer PHP versions, which should be warned in readme while the problem is being addressed.

    opened by odelrio 2
  • Optimize Any function

    Optimize Any function

    It looks like the \Chemem\Bingo\Functional\Algorithms\any function filters the collection at first and then applies the predicate. Can you think of any reason why we can't remove the filter and return the result immediately when the predicate returns true? For example: https://github.com/DusanKasan/Knapsack/blob/7189f5bfc9acca1bca07eeff242743c61ddda1ff/src/collection_functions.php#L579

    enhancement 
    opened by OlexandrPopov 2
  • Property tests

    Property tests

    Property tests are a great way to ensure function completeness - they help validate the invariants in a function's intended behavior. I currently feel that the unit tests written for this library, though accurate, are not complete. I currently envisage an adoption of property testing ideas for the library. For example:

    public function testIdentityFunctionConveysInputAsOutput()
    {
      $this->forAll(
        Generator\int(),
        Generator\string(),
        Generator\float(),
        Generator\bool()
      )
        ->then(function ($value) {
          $id = A\identity($value);
          
          $this->assertEquals($value, $id);
          $this->assertTrue(gettype($value) == gettype($id));
        });
    }
    

    The snippet above utilizes the Eris package to perform property tests. The result is a litany of assertions which ordinarily - constitute atomic use cases.

    enhancement ambitious 
    opened by ace411 2
  • Fatal error when using Nothing::flatMap

    Fatal error when using Nothing::flatMap

    Consider the following code:

    $maybe = Maybe::fromValue(null)
        ->flatMap(function () {
            return Maybe::fromValue('some value');
        })
        ->getOrElse('default');
    

    It causes the error: PHP Fatal error: Uncaught Error: Call to a member function getOrElse() on null. Probably Nothing::flatMap should return an instance of Nothing instead of null.

    opened by OlexandrPopov 0
  • Shouldn't IO::bind be lazy?

    Shouldn't IO::bind be lazy?

    Consider the following code:

    use Chemem\Bingo\Functional\Functors\Monads\IO;
    
    $io = IO::of(function () {
        echo 'LOG 1', PHP_EOL;
    })
    ->bind(function () {
        return IO::of(function () {
            echo 'LOG 2', PHP_EOL;
        });
    });
    

    It prints LOG 1 even $io->exec() is not called.

    question 
    opened by OlexandrPopov 3
Releases(v2.0.1)
  • v2.0.1(Aug 7, 2021)

  • v2.0.0(Jul 20, 2021)

    • Renamed namespace Chemem\Bingo\Functional\Algorithms to Chemem\Bingo\Functional
    • Moved Maybe and Either monad artifacts into Chemem\Bingo\Functional\Functors\Monads namespace
    • Modified patternMatch, cmatch, compact, keysExist, reject, max, min, firstIndexOf, fill, every, compact, mean, intersects, tail, zip helper functions
    • Modified pattern matching primitives namespaced under Chemem\Bingo\Functional\PatternMatching\Internal
    • Removed readIO, ask, Maybe::lift, Either::lift functions
    • Added lenses
    • Added transducer functions
    • Modified List and Writer monads
    • Added Functor, ApplicativeFunctor, and Monad interfaces
    • Modified intersects function in immutable Collection
    • Renamed match to cmatch
    • Added liftM monad helper function
    • Added K function (K-combinator)
    • Revamped project test suite
    Source code(tar.gz)
    Source code(zip)
  • v1.13.0(Sep 19, 2020)

    • Modified putStr, getLine, putStrLn, putChar IO helper functions

    • Added default values to pick and pluck functions

    • Added internal functions namespaced under Chemem\Bingo\Functional\Algorithms\Internal

    • Modified some list/collection primitives to work on objects as well as hashtables

    • Infused Collection with Transient properties

    • Added mergeN() Collection method

    • Modified any() and every() Collection methods

    • Added ImmutableDataStructure and ImmutableList interfaces

    • Added a Tuple immutable structure

    • Added mapM() Monad function

    • Replaced original pattern-matching algorithm with that in the functional-php/pattern-matching library

    • Added new helper functions

    • Jettisoned docs folder. Moved docs site to new address

    New Helper Functions

    • intersperse()

    • difference()

    • countOfKey()

    • countOfValue()

    • renameKeys()

    New Monadic Helper functions

    • mapM()

    Modified functions

    • map()

    • filter()

    • fold()

    • reject()

    • pluck()

    • pick()

    • any()

    • every()

    • partial()

    • indexOf()

    • indexesOf()

    • addKeys()

    • omit()

    • partialRight()

    • dropLeft()

    • dropRight()

    • mapDeep()

    • filterDeep()

    Source code(tar.gz)
    Source code(zip)
  • v1.12.0(Feb 25, 2019)

    • Removed function parameter from zip function

    • Created Monadic interface for Monads

    • Added new helper functions

    • Added new Monad helper functions

    • Added APCU-supported functionality to memoize function

    • Added constant static function definitions for Monadic types

    • Added new Collection functions

    New Helper functions

    • toWords()

    • slugify()

    • truncate()

    • intersects()

    • composeRight()

    • filePath()

    • union()

    • unionWith()

    • zipWith()

    New Monadic Helper functions

    • filterM()

    • foldM()

    New Collection functions

    • fetch()

    • contains()

    • unique()

    • head()

    • tail()

    • last()

    • intersects()

    • implode()

    • offsetGet()

    Source code(tar.gz)
    Source code(zip)
  • v1.11.0(Nov 24, 2018)

    • Modified pattern matching algorithm to enable usage of wildcards in patterns

    • Modified State, List, Writer, and Reader monads

    • Added monadic helper functions

    • Added Applicative helper functions

    • Added bind and of methods to Either and Maybe type classes

    • Added flip helper function

    • Added liftIn function

    New Applicative Helper functions

    • Applicative\pure()

    • Applicative\liftA2()

    New Monadic Helper functions

    • mcompose()

    • bind()

    • IO\IO

    • IO_print()

    • IO\getChar()

    • IO\putChar()

    • IO\putStr()

    • IO\getLine()

    • IO\interact()

    • IO\readFile()

    • IO\writeFile()

    • IO\appendFile()

    • IO\readIO()

    • State\state()

    • State\gets()

    • State\modify()

    • State\evalState()

    • State\execState()

    • State\put()

    • State\runState()

    • ListMonad\fromValue()

    • ListMonad\concat()

    • ListMonad\prepend()

    • LIstMonad\append()

    • ListMonad\head()

    • ListMonad\tail()

    • Reader\reader()

    • Reader\runReader()

    • Reader\mapReader()

    • Reader\withReader()

    • Reader\ask()

    • Writer\writer()

    • Writer\runWriter()

    • Writer\execWriter()

    • Writer\mapWriter()

    New union type helper functions

    • Either\either()

    • Either\isLeft()

    • Either\isRight()

    • Either\lefts()

    • Either\rights()

    • Either\fromLeft()

    • Either\partitionEithers()

    • Maybe\maybe()

    • Maybe\isJust()

    • Maybe\isNothing()

    • Maybe\fromJust()

    • Maybe\fromNothing()

    • Maybe\maybeToList()

    • Maybe\listToMaybe()

    • Maybe\catMaybes()

    • Maybe\mapMaybe()

    Source code(tar.gz)
    Source code(zip)
  • v1.10.0(Aug 29, 2018)

    • Added object matching capability to patternMatch

    • Modified patternMatch array matching to give more concise match results

    • Jettisoned reverse function

    • Added Immutable collections to library

    New Helper functions

    • mapDeep()
    • omit()
    • addKeys()
    • last()
    • reject()
    • mean()

    Modified the following functions

    • patternMatch()
    Source code(tar.gz)
    Source code(zip)
  • v1.9.0(Jun 9, 2018)

    • Added more robust pattern matching to library

    Modified the following function(s)

    • dropLeft()
    • dropRight()
    • map()
    • filter()

    Added new helper function(s)

    • min()
    • max()
    • any()
    • every()
    • where()
    • groupBy()
    • foldRight()
    • toException()
    • reduceRight()
    Source code(tar.gz)
    Source code(zip)
  • v1.8.0(May 16, 2018)

    Removed the following callback function(s)

    • invalidArrayKey()
    • invalidArrayValue()
    • emptyArray()
    • memoizationError()

    Modified the following function(s)

    • map()
    • pick()
    • fold()
    • pluck()
    • reduce()
    • filter()
    • memoize()
    • isArrayOf()

    Added new helper functions

    • fill()
    • partial()
    • indexOf()
    • reverse()
    • toPairs()
    • fromPairs()

    Added pattern matching to library

    Source code(tar.gz)
    Source code(zip)
  • v1.7.2(Mar 3, 2018)

    Made the following change(s):

    • Modified the orElse() methods of the Left, Right, Nothing, and Just functors

    • Added the flatMap() method to the State and List monads

    Source code(tar.gz)
    Source code(zip)
  • v1.7.1(Feb 13, 2018)

    Made the following change(s):

    • Modified the throttle() function to accept multiple arguments

    • Added type signatures and doc blocks for functions without any

    • Added immutable const definition for concat() function

    Source code(tar.gz)
    Source code(zip)
  • v1.7.0(Jan 30, 2018)

  • v1.6.0(Jan 4, 2018)

    Made the following changes:

    • Modified the filter() function to accurately filter values whenever a boolean predicate is defined.

    • Changed parameter order of the return value for the reduce() function.

    Added new helper functions:

    • arrayKeysExist()

    • dropLeft()

    • dropRight()

    • unique()

    • flatten()

    Source code(tar.gz)
    Source code(zip)
  • v1.5.0(Dec 18, 2017)

  • v1.4.0(Dec 7, 2017)

    Made the following changes:

    • the pluck(), pick(), isArrayOf(), and memoize() functions have been given callback signatures.

    • the extractErrorMessage() function and all other related callback functions have been replaced.

    • the Monad class has been replaced with new Monads: IO, Reader, Writer, and State.

    Added new helpers:

    • concat()

    • throttle()

    Added new callback functions:

    • invalidArrayKey()

    • invalidArrayValue()

    • emptyArray()

    • memoizationError()

    Added new Monads:

    • State monad

    • IO monad

    • Reader monad

    • Writer monad

    Source code(tar.gz)
    Source code(zip)
  • v1.3.1(Nov 4, 2017)

    Made the following fix:

    • Edit the Monad class to return a Monad null class instance as opposed to an uncaught exception upon filter() condition assertion failure
    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Oct 18, 2017)

  • v1.2.1(Oct 4, 2017)

    Fixed the following problems:

    • the error message shown when a mixed array is supplied to the isArrayOf() function

    • the partialRight() behavior of partialLeft()

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Sep 23, 2017)

    This version includes the following new functions and monad additions:

    • isArrayOf()

    • partialRight()

    • partialLeft() as a replacement for partial()

    • A TransientMutator trait

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Sep 13, 2017)

  • v1.0.0(Sep 13, 2017)

    First release of the bingo-functional library.

    Helpers

    • compose()
    • constantFunction()
    • curry()
    • curryN()
    • extend()
    • identity()
    • memoize()
    • partial()
    • pick()
    • pluck()
    • zip()
    • unzip()

    Functors

    • Either Left/Right
    • Maybe Just/Nothing
    • Applicatives Applicative/CollectionApplicative
    • Monad Monad
    Source code(tar.gz)
    Source code(zip)
Owner
Lochemem Bruno Michael
I worship at the altars of the PHP, C++, and JavaScript gods.
Lochemem Bruno Michael
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
Simple libary for functional programing paradigm with arrays.

rodrigodornelles/php-array-lib simple libary for functional programing paradigm with arrays Features Test driven development style (TDD) PHP version c

null 10 Nov 28, 2022
This example shows how to use Anychart library with the PHP programming language, Laravel framework and MySQL database.

PHP basic template This example shows how to use Anychart library with the PHP programming language, Laravel framework and MySQL database. Running To

AnyChart Integrations and Templates 23 Jul 17, 2022
Simple game server with php without socket programming. Uses the Api request post(json).

QMA server Simple game server with php without socket programming. Uses the Api request post(json). What does this code do? Register the user as a gue

reza malekpour 3 Sep 4, 2021
A collection of type-safe functional data structures

lamphpda A collection of type-safe functional data structures Aim The aim of this library is to provide a collection of functional data structures in

Marco Perone 99 Nov 11, 2022
N2Web turns your Notion HTML export into a fully functional static website

Notion2Web N2Web turns your Notion HTML export into a fully functional static website. What is Notion? Notion is an online tool. But I can't tell you

Lars Lehmann 15 Nov 23, 2022
WARNING! This software is currently non-functional. - A system which makes installing Jexactyl far, far easier.

Jexactyl Assistant A system which makes installing Jexactyl far, far easier. WARNING ?? This software is currently in heavy alpha testing and WILL NOT

Jexactyl 7 Nov 14, 2022
Sitepackage for TYPO3 CMS that adheres to the recommended standards, maps all conceivable functional areas and contains examples for common use cases.

TYPO3 CMS Sitepackage This sitepackage sticks as closely as possible to the recommended standard and maps all conceivable functional areas. There are

Eric Bode 3 Dec 18, 2022
This is a plugin written in PHP programming language and running on the PocketMine platform that works stably on the API 3.25.0 platform

This is a plugin written in PHP programming language and running on the PocketMine platform that works stably on the API 3.25.0 platform. It allows you to hear the sound

Thành Nhân 10 Sep 27, 2022
A repository for showcasing my knowledge of the PHP programming language, and continuing to learn the language.

Learning PHP (programming language) I know very little about PHP. This document will list all my knowledge of the PHP programming language. Basic synt

Sean P. Myrick V19.1.7.2 2 Oct 29, 2022
Bearer client for the PHP programming language

Bearer PHP Client This is the official PHP client for interacting with Bearer.sh. Installation Install the package by running: composer require bearer

Bearer 9 Oct 31, 2022
Learning design patterns by implementing them in various programming languages.

design-patterns Learning design patterns by implementing them in various programming languages. Creational design patterns Creational design patterns

Paweł Tryfon 1 Dec 13, 2021
All about docker projects either from dockerfile or compose. Anyway, here the project is in the form of a service, for the programming language I will make it later

Docker Project by ItsArul Hey, yo guys okay, this time I made some projects from Docker. Anyway, this project is open source, for example, if you want

Kiyo 10 Nov 4, 2022
A Finite State Machine System based on Chapter 3.1 of Game Programming Gems 1 by Eric Dybsand

A Finite State Machine System based on Chapter 3.1 of Game Programming Gems 1 by Eric Dybsand,Written by Roberto Cezar Bianchini, July 2010 ported to php by MrFerrys.

null 4 Apr 18, 2022
Utilities for concurrent programming of PocketMine-MP plugins.

Utilities for concurrent programming of PocketMine-MP plugins Overview Plugin that implements the pthreads channels and in the future, promises (which

Dmitry Uzyanov 0 Aug 15, 2022
Dobren Dragojević 6 Jun 11, 2023
Columnar analytics for PHP - a pure PHP library to read and write simple columnar files in a performant way.

Columnar Analytics (in pure PHP) On GitHub: https://github.com/envoymediagroup/columna About the project What does it do? This library allows you to w

Envoy Media Group 2 Sep 26, 2022
Simple PHP Pages - A simple puristic PHP Website Boilerplate

Simple PHP Pages - A simple puristic PHP Website Boilerplate ?? Hey! This project provides simple and basic concepts for PHP pages. It includes ideas

SteamPixel 8 Sep 22, 2022
Sslurp is a simple library which aims to make properly dealing with SSL in PHP suck less.

Sslurp v1.0 by Evan Coury Introduction Dealing with SSL properly in PHP is a pain in the ass and completely insecure by default. Sslurp aims to make i

Evan Coury 65 Oct 14, 2022