PHP SLANG The place where PHP meets Functional Programming
arrow down
What is a functional programming?

Functional programming shifts you thinking about the code to a more expressive one. Your code does not show HOW you want to achieve things anymore – it becomes rather WHAT you want to achieve. Methods of your classes become much more expressive... yes – methods of classes, because OOP and FP make a great couple together!

What is the PHP SLANG?

PhpSlang helps you to achieve this goal in PHP7. We learned from the best – PhpSlang gives you constructs like Option, Future, ParallelCollection which are the main reason why Scala, F# or Haskell developer love their languages so much. If you come from this world – this is what you missed in a PHP. PhpSlang documentation is not only a raw manual on how to use this library, but also a good starting point to learn how write a proper purely functional code in PHP.

Benefits

// No more surprises

Much more descriptive methodswhich are much closer to a mathematical expressions than to step- by-step recipee leave a very little, or no space for stupid bugs and undiscovered edge cases.

// Scalability out of box

You can easily encapsulate your login in parallel data structures which make full use of your hardware with transparent asynchronous computation.

// Write less code

...and read it like a poetry. With monadic types and proper usage of higher order functions your code becomes readable even for dummies.

Features

// CLEAR CODE

Functional languages. It provides constructs optimizing your work and letting you develop with a purely functional style.

                                
                    // THIS IS A FIRST EXAMPLE TITLE - 1

                    public function of(...$cases)
                    {
                        return (new ListCollection($cases))
                            ->any(function (AbstractWhen $case) {
                                return $case->matches($this->matched);
                            })
                            ->map(function (AbstractWhen $case) {
                                return $case->getResult($this->matched);
                            })
                            ->getOrCall(function () {
                                throw new NoMatchFoundException();
                            });
                    }
                                
                            
Code examples

// 1. Optional type

No more null function results or method parameters. Option abstracts things that may, but also may not exist. It makes you feel much more comfortable and you don’t have to double check if your code covers all possible rerutn variants with tons of if statements.

// 2. Either type

Allows you to return from your functions one of two types with completely different structures and eg. handle errors in a purely functional way.

// 3. Pattern matching

Put some declarative programming into PHP. Switch your thinking not only from HOW to WHAT, but also to WHAT WITH attitude. It’s a purely functional replacement both for a try catch and case switch statement.

// 4. Immutable list collections

It looks friendly to Doctrine ArrayCollection – but computations run in parallel and we promise you that there are no side-effects that you’ll have to take care on.

// 5. Future monad

Parallel computation of immutable structures is a future and Future monad allows you to be there with the rest cool guys.

// 6. Trampolines

Yes – it’s possible in PHP. Wrap your recursive functions with trampolines and you don’t have to be afraid of reaching a limit of nested functions.

keyboard_arrow_down PREV See Code NEXT keyboard_arrow_down
COPIED! COPY TO CLIPBOARD
                            
                  $this->maybeString()
                      ->map(function (string $existingString){
                          return 'Yes we have it: ' . $existingString;
                      })
                      ->getOrElse('No, we don\'t');
                            
                        
                            
          $this->update($domainObject)
              ->right($this->successfulResponse())
              ->left($this->failWithGrace())
              ->get();
                            
                        
                            
          Match::val("test 123")->of(
              When::typeOf(Option::class, "maybe string"),
              When::results(function ($item) {
                  return $item == "test";
              }, "equal to test"),
              When::equals("test", "oh my, it was that easy"),
              When::other("default result")
          )
                            
                            ← swipe to see rest of code →
                        
                            
          function avgOfTopTenBiggestEvenNumbersWithMessage(
              ParallelListCollection $numbers, string $message)
          {
              return $numbers
                  ->filter($this->isEven())
                  ->sort()
                  ->slice(0, 10)
                  ->avg()
                  ->map(function (int $number) use ($message) {
                      return $number . $message;
                  });
          }
                            
                        
                            
          public function search(string $query) : ListCollection
          {
              return Future::all([
                  $this->textService->search($query),
                  $this->imageService->search($query),
                  $this->videoService->search($query),
              ])
              ->map(function (ListCollection $searchResults) {
                  return $searchResults->flatten()->sort();
              })
              ->await();
          }
                            
                        
                            
          function tailRecursiveFibonacci(
              int $index,
              int $previous = 0,
              int $next = 1) : Trampoline
          {
              return ($index <= 1)
                  ? new Done($index == 0 ? $previous : $next)
                  : new Bounce(function () use (
                      $index, $next, $previous) {
                          return $this
                              ->tailRecursiveFibonacci(
                                  $index - 1,
                                  $next,
                                  $next + $previous
                              );
                  });
          }