├── .gitignore ├── composer.json ├── composer.lock ├── readme.md ├── session1_laravel.php ├── session1_pure.php ├── session3.php ├── session4_laravel.php ├── session4_pure.php └── session7.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | 3 | /vendor/ 4 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hsmfawaz/php-function-programming", 3 | "require": { 4 | "illuminate/collections": "^8.35" 5 | }, 6 | "authors": [ 7 | { 8 | "name": "hsmfawaz2", 9 | "email": "hsm.fawaz@gmail.com" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "2a2e4ef747c86d307322eed0fcc92f86", 8 | "packages": [ 9 | { 10 | "name": "illuminate/collections", 11 | "version": "v8.35.1", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/illuminate/collections.git", 15 | "reference": "0a7a96520928b61df1750b4e1909588f10ae2abe" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/illuminate/collections/zipball/0a7a96520928b61df1750b4e1909588f10ae2abe", 20 | "reference": "0a7a96520928b61df1750b4e1909588f10ae2abe", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "illuminate/contracts": "^8.0", 25 | "illuminate/macroable": "^8.0", 26 | "php": "^7.3|^8.0" 27 | }, 28 | "suggest": { 29 | "symfony/var-dumper": "Required to use the dump method (^5.1.4)." 30 | }, 31 | "type": "library", 32 | "extra": { 33 | "branch-alias": { 34 | "dev-master": "8.x-dev" 35 | } 36 | }, 37 | "autoload": { 38 | "psr-4": { 39 | "Illuminate\\Support\\": "" 40 | }, 41 | "files": [ 42 | "helpers.php" 43 | ] 44 | }, 45 | "notification-url": "https://packagist.org/downloads/", 46 | "license": [ 47 | "MIT" 48 | ], 49 | "authors": [ 50 | { 51 | "name": "Taylor Otwell", 52 | "email": "taylor@laravel.com" 53 | } 54 | ], 55 | "description": "The Illuminate Collections package.", 56 | "homepage": "https://laravel.com", 57 | "support": { 58 | "issues": "https://github.com/laravel/framework/issues", 59 | "source": "https://github.com/laravel/framework" 60 | }, 61 | "time": "2021-03-25T14:54:04+00:00" 62 | }, 63 | { 64 | "name": "illuminate/contracts", 65 | "version": "v8.35.1", 66 | "source": { 67 | "type": "git", 68 | "url": "https://github.com/illuminate/contracts.git", 69 | "reference": "121cea1d8b8772bc7fee99c71ecf0f57c1d77b3b" 70 | }, 71 | "dist": { 72 | "type": "zip", 73 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/121cea1d8b8772bc7fee99c71ecf0f57c1d77b3b", 74 | "reference": "121cea1d8b8772bc7fee99c71ecf0f57c1d77b3b", 75 | "shasum": "" 76 | }, 77 | "require": { 78 | "php": "^7.3|^8.0", 79 | "psr/container": "^1.0", 80 | "psr/simple-cache": "^1.0" 81 | }, 82 | "type": "library", 83 | "extra": { 84 | "branch-alias": { 85 | "dev-master": "8.x-dev" 86 | } 87 | }, 88 | "autoload": { 89 | "psr-4": { 90 | "Illuminate\\Contracts\\": "" 91 | } 92 | }, 93 | "notification-url": "https://packagist.org/downloads/", 94 | "license": [ 95 | "MIT" 96 | ], 97 | "authors": [ 98 | { 99 | "name": "Taylor Otwell", 100 | "email": "taylor@laravel.com" 101 | } 102 | ], 103 | "description": "The Illuminate Contracts package.", 104 | "homepage": "https://laravel.com", 105 | "support": { 106 | "issues": "https://github.com/laravel/framework/issues", 107 | "source": "https://github.com/laravel/framework" 108 | }, 109 | "time": "2021-03-12T14:45:30+00:00" 110 | }, 111 | { 112 | "name": "illuminate/macroable", 113 | "version": "v8.35.1", 114 | "source": { 115 | "type": "git", 116 | "url": "https://github.com/illuminate/macroable.git", 117 | "reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05" 118 | }, 119 | "dist": { 120 | "type": "zip", 121 | "url": "https://api.github.com/repos/illuminate/macroable/zipball/300aa13c086f25116b5f3cde3ca54ff5c822fb05", 122 | "reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05", 123 | "shasum": "" 124 | }, 125 | "require": { 126 | "php": "^7.3|^8.0" 127 | }, 128 | "type": "library", 129 | "extra": { 130 | "branch-alias": { 131 | "dev-master": "8.x-dev" 132 | } 133 | }, 134 | "autoload": { 135 | "psr-4": { 136 | "Illuminate\\Support\\": "" 137 | } 138 | }, 139 | "notification-url": "https://packagist.org/downloads/", 140 | "license": [ 141 | "MIT" 142 | ], 143 | "authors": [ 144 | { 145 | "name": "Taylor Otwell", 146 | "email": "taylor@laravel.com" 147 | } 148 | ], 149 | "description": "The Illuminate Macroable package.", 150 | "homepage": "https://laravel.com", 151 | "support": { 152 | "issues": "https://github.com/laravel/framework/issues", 153 | "source": "https://github.com/laravel/framework" 154 | }, 155 | "time": "2020-10-27T15:20:30+00:00" 156 | }, 157 | { 158 | "name": "psr/container", 159 | "version": "1.1.1", 160 | "source": { 161 | "type": "git", 162 | "url": "https://github.com/php-fig/container.git", 163 | "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" 164 | }, 165 | "dist": { 166 | "type": "zip", 167 | "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", 168 | "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", 169 | "shasum": "" 170 | }, 171 | "require": { 172 | "php": ">=7.2.0" 173 | }, 174 | "type": "library", 175 | "autoload": { 176 | "psr-4": { 177 | "Psr\\Container\\": "src/" 178 | } 179 | }, 180 | "notification-url": "https://packagist.org/downloads/", 181 | "license": [ 182 | "MIT" 183 | ], 184 | "authors": [ 185 | { 186 | "name": "PHP-FIG", 187 | "homepage": "https://www.php-fig.org/" 188 | } 189 | ], 190 | "description": "Common Container Interface (PHP FIG PSR-11)", 191 | "homepage": "https://github.com/php-fig/container", 192 | "keywords": [ 193 | "PSR-11", 194 | "container", 195 | "container-interface", 196 | "container-interop", 197 | "psr" 198 | ], 199 | "support": { 200 | "issues": "https://github.com/php-fig/container/issues", 201 | "source": "https://github.com/php-fig/container/tree/1.1.1" 202 | }, 203 | "time": "2021-03-05T17:36:06+00:00" 204 | }, 205 | { 206 | "name": "psr/simple-cache", 207 | "version": "1.0.1", 208 | "source": { 209 | "type": "git", 210 | "url": "https://github.com/php-fig/simple-cache.git", 211 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" 212 | }, 213 | "dist": { 214 | "type": "zip", 215 | "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 216 | "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", 217 | "shasum": "" 218 | }, 219 | "require": { 220 | "php": ">=5.3.0" 221 | }, 222 | "type": "library", 223 | "extra": { 224 | "branch-alias": { 225 | "dev-master": "1.0.x-dev" 226 | } 227 | }, 228 | "autoload": { 229 | "psr-4": { 230 | "Psr\\SimpleCache\\": "src/" 231 | } 232 | }, 233 | "notification-url": "https://packagist.org/downloads/", 234 | "license": [ 235 | "MIT" 236 | ], 237 | "authors": [ 238 | { 239 | "name": "PHP-FIG", 240 | "homepage": "http://www.php-fig.org/" 241 | } 242 | ], 243 | "description": "Common interfaces for simple caching", 244 | "keywords": [ 245 | "cache", 246 | "caching", 247 | "psr", 248 | "psr-16", 249 | "simple-cache" 250 | ], 251 | "support": { 252 | "source": "https://github.com/php-fig/simple-cache/tree/master" 253 | }, 254 | "time": "2017-10-23T01:57:42+00:00" 255 | } 256 | ], 257 | "packages-dev": [], 258 | "aliases": [], 259 | "minimum-stability": "stable", 260 | "stability-flags": [], 261 | "prefer-stable": false, 262 | "prefer-lowest": false, 263 | "platform": [], 264 | "platform-dev": [], 265 | "plugin-api-version": "2.0.0" 266 | } 267 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Implementing Functional Programming using PHP 2 | 3 | - [x] Pure PHP 4 | - [x] Laravel Collections -------------------------------------------------------------------------------- /session1_laravel.php: -------------------------------------------------------------------------------- 1 | map('addOne') 34 | ->map('square') 35 | ->filter(fn ($x) => $x < 70) 36 | ->sort() 37 | ->take(2) 38 | ->each('println'); -------------------------------------------------------------------------------- /session1_pure.php: -------------------------------------------------------------------------------- 1 | $x < 70); 35 | sort($transformed); 36 | array_filter(array_slice(array_map('subtractTen', $transformed), 0, 2), 'println'); -------------------------------------------------------------------------------- /session3.php: -------------------------------------------------------------------------------- 1 | self::testOne($x); 9 | $closureTwo = fn ($x) => self::testTwo($x); 10 | $closureThree = fn ($x, $y) => self::testThree($x, $y); 11 | $closureList = [$closureOne, $closureTwo]; 12 | 13 | echo $closureTwo($closureOne(5)).PHP_EOL; 14 | echo $closureOne($closureTwo(5)).PHP_EOL; 15 | 16 | echo $closureList[0](5).PHP_EOL; 17 | echo $closureList[1](5).PHP_EOL; 18 | 19 | echo $closureThree($closureOne, 5).PHP_EOL; 20 | echo $closureThree($closureTwo, 5).PHP_EOL; 21 | } 22 | 23 | public static function testOne(float $x) : float 24 | { 25 | return $x / 2; 26 | } 27 | 28 | public static function testTwo(float $x) : float 29 | { 30 | return $x / 4 + 1; 31 | } 32 | 33 | public static function testThree(Closure $f, float $value) : float 34 | { 35 | return $f($value) + $value; 36 | } 37 | } 38 | 39 | HigherOrderFunctionSession::handle(); -------------------------------------------------------------------------------- /session4_laravel.php: -------------------------------------------------------------------------------- 1 | "Paper"]), 11 | new Order(['name' => "Laptop"]), 12 | ]); 13 | $ordersWithDiscounts = $ordersList->map(function ($x) { 14 | return $this->GetOrderWithDiscount($x, $this->GetDiscountRules()); 15 | }); 16 | 17 | print_r($ordersWithDiscounts->toArray()); 18 | } 19 | 20 | public function GetOrderWithDiscount(Order $r, \Illuminate\Support\Collection $rules) : Order 21 | { 22 | $discount = $rules->filter(fn ($a) => $a['QualifyingCondition']($r)) 23 | ->map(fn ($b) => $b['GetDiscount']($r)) 24 | ->sort() 25 | ->take(3) 26 | ->avg(); 27 | $newOrder = new Order($r->orderData); 28 | $newOrder->discount = $discount; 29 | 30 | return $newOrder; 31 | } 32 | 33 | public function GetDiscountRules() : \Illuminate\Support\Collection 34 | { 35 | return new \Illuminate\Support\Collection([ 36 | [ 37 | 'QualifyingCondition' => [$this, 'isAQualified'], 38 | 'GetDiscount' => [$this, 'A'], 39 | ], 40 | [ 41 | 'QualifyingCondition' => [$this, 'isBQualified'], 42 | 'GetDiscount' => [$this, 'B'], 43 | ], 44 | [ 45 | 'QualifyingCondition' => [$this, 'isCQualified'], 46 | 'GetDiscount' => [$this, 'C'], 47 | ], 48 | ]); 49 | } 50 | 51 | public function isAQualified(Order $r) : bool 52 | { 53 | return true; 54 | } 55 | 56 | public function A(Order $r) : float 57 | { 58 | return 1.0; 59 | } 60 | 61 | public function isBQualified(Order $r) : bool 62 | { 63 | return true; 64 | } 65 | 66 | public function B(Order $r) : float 67 | { 68 | return 1.0; 69 | } 70 | 71 | public function isCQualified(Order $r) : bool 72 | { 73 | return true; 74 | } 75 | 76 | public function C(Order $r) : float 77 | { 78 | return 1.0; 79 | } 80 | } 81 | 82 | class Order 83 | { 84 | public float $discount; 85 | 86 | public array $orderData; 87 | 88 | public function __construct(array $orderData) 89 | { 90 | 91 | $this->orderData = $orderData; 92 | } 93 | } 94 | 95 | (new Session4Laravel())->handle(); 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /session4_pure.php: -------------------------------------------------------------------------------- 1 | "Paper"]), 10 | new Order(['name' => "Laptop"]), 11 | ]; 12 | $ordersWithDiscounts = array_map(function ($x) { 13 | return $this->GetOrderWithDiscount($x, $this->GetDiscountRules()); 14 | }, $ordersList); 15 | 16 | print_r($ordersWithDiscounts); 17 | } 18 | 19 | public function GetOrderWithDiscount(Order $R, array $Rules) : Order 20 | { 21 | $filterRules = array_filter($Rules, fn ($a) => $a['QualifyingCondition']($R)); 22 | $mapRules = array_map(fn ($b) => $b['GetDiscount']($R), $filterRules); 23 | sort($mapRules); 24 | $takeThree = array_slice($mapRules, 0, 3); 25 | $discount = array_sum($takeThree) / count($takeThree); 26 | $newOrder = new Order($R->orderData); 27 | $newOrder->discount = $discount; 28 | 29 | return $newOrder; 30 | } 31 | 32 | public function GetDiscountRules() : array 33 | { 34 | return [ 35 | [ 36 | 'QualifyingCondition' => [$this, 'isAQualified'], 37 | 'GetDiscount' => [$this, 'A'], 38 | ], 39 | [ 40 | 'QualifyingCondition' => [$this, 'isBQualified'], 41 | 'GetDiscount' => [$this, 'B'], 42 | ], 43 | [ 44 | 'QualifyingCondition' => [$this, 'isCQualified'], 45 | 'GetDiscount' => [$this, 'C'], 46 | ], 47 | ]; 48 | } 49 | 50 | public function isAQualified(Order $r) : bool 51 | { 52 | return true; 53 | } 54 | 55 | public function A(Order $r) : float 56 | { 57 | return 1.0; 58 | } 59 | 60 | public function isBQualified(Order $r) : bool 61 | { 62 | return true; 63 | } 64 | 65 | public function B(Order $r) : float 66 | { 67 | return 1.0; 68 | } 69 | 70 | public function isCQualified(Order $r) : bool 71 | { 72 | return true; 73 | } 74 | 75 | public function C(Order $r) : float 76 | { 77 | return 1.0; 78 | } 79 | } 80 | 81 | class Order 82 | { 83 | public float $discount; 84 | 85 | public array $orderData; 86 | 87 | public function __construct(array $orderData) 88 | { 89 | 90 | $this->orderData = $orderData; 91 | } 92 | } 93 | 94 | (new Session4Pure())->handle(); 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /session7.php: -------------------------------------------------------------------------------- 1 | 'a', 'basicSalary' => 1000], 10 | ['segment' => 'b', 'basicSalary' => 2000], 11 | ['segment' => 'c', 'basicSalary' => 3000], 12 | ]; 13 | $grossSalaryCalculators = array_map(fn ($i) => [ 14 | 'segment' => $i['segment'], 15 | 'MyGrossSalaryCalculator' => $this->grossSalaryCalculator($i['basicSalary']), 16 | ], $segments); 17 | 18 | echo $grossSalaryCalculators[0]['MyGrossSalaryCalculator'](80).PHP_EOL; 19 | echo $grossSalaryCalculators[1]['MyGrossSalaryCalculator'](90).PHP_EOL; 20 | echo $grossSalaryCalculators[2]['MyGrossSalaryCalculator'](100).PHP_EOL; 21 | } 22 | 23 | private function grossSalaryCalculator(float $basicSalary) : Closure 24 | { 25 | $tax = 0.2 * $basicSalary; 26 | 27 | return static fn (float $bonus) => $tax + $bonus + $basicSalary; 28 | } 29 | } 30 | 31 | (new SessionSeven())->handle(); 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | --------------------------------------------------------------------------------