Skip to content

Commit 8e3ca8f

Browse files
committed
add docs
1 parent dc9a4cc commit 8e3ca8f

7 files changed

+349
-1
lines changed

Diff for: README.md

+49-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,55 @@
22

33
[![github action status](https://github.com/Hexlet/phpstan-functional-programming/workflows/PHP%20CI/badge.svg)](https://github.com/Hexlet/phpstan-functional-programming/actions)
44

5-
PHPStan for functional programming
5+
[PHPStan](https://phpstan.org) rules for functional programming
6+
7+
## Install
8+
9+
To use this extension, require it in [Composer](https://getcomposer.org):
10+
11+
```sh
12+
$ composer require --dev hexlet/phpstan-fp
13+
```
14+
15+
## Usage
16+
17+
All of the rules provided (and used) by this library are included in [`extension.neon`](extension.neon).
18+
19+
When you are using [phpstan/extension-installer](https://github.com/phpstan/extension-installer), `extension.neon` will be automatically included.
20+
21+
Otherwise you need to include `extension.neon` in your `phpstan.neon`:
22+
23+
```neon
24+
includes:
25+
- vendor/hexlet/phpstan-fp/extension.neon
26+
```
27+
28+
## Rules
29+
30+
This package provides the following rules for use with *PHPStan*:
31+
32+
* [`DisallowClassesRule`](docs/rules/DisallowClassesRule.md)
33+
* [`DisallowThrowRule`](docs/rules/DisallowThrowRule.md)
34+
* [`DisallowUnusedExpressionRule`](docs/rules/DisallowUnusedExpressionRule.md)
35+
* [`DisallowMutatingFunctionsRule`](docs/rules/DisallowMutatingFunctionsRule.md)
36+
* [`DisallowLoopsRule`](docs/rules/DisallowLoopsRule.md)
37+
* [`DisallowMutationRule`](docs/rules/DisallowMutationRule.md)
38+
39+
## Disabling rules
40+
41+
If you don't want to start using some of the available rules at once, you can.
42+
43+
```neon
44+
parameters:
45+
46+
phpstanFunctionalProgramming:
47+
disallowClasses: false
48+
disallowLoops: false
49+
disallowThrow: false
50+
disallowUnusedExpression: false
51+
disallowVariablesMutation: false
52+
disallowMutatingFunctions: false
53+
```
654

755
[![Hexlet Ltd. logo](https://raw.githubusercontent.com/Hexlet/hexletguides.github.io/master/images/hexlet_logo128.png)](https://ru.hexlet.io/pages/about?utm_source=github&utm_medium=link&utm_campaign=phpstan-functional-programming)
856

Diff for: docs/rules/DisallowClassesRule.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# DisallowClassesRule
2+
3+
*Forbid the use of `class`*
4+
5+
Classes are nice tools to use when programming with the object-oriented paradigm, as they hold internal state and give access to methods on the instances. In functional programming, having stateful objects is more harmful than helpful, and should be replaced by the use of pure functions.
6+
7+
### Fail
8+
9+
```php
10+
<?php
11+
12+
class Point
13+
{
14+
private int $x;
15+
private int $y;
16+
17+
public function __construct(int $x, int $y)
18+
{
19+
$this->x = $x;
20+
$this->y = $y;
21+
}
22+
}
23+
```
24+
25+
### Pass
26+
27+
```php
28+
<?php
29+
30+
function point(int $x, int $y): array
31+
{
32+
return [
33+
'x' => $x,
34+
'y' => $y,
35+
];
36+
}
37+
```
38+
39+
## Rule configuration
40+
41+
The rule is enabled by default. To turn it off, edit your *phpstan.neon* file.
42+
43+
```neon
44+
parameters:
45+
46+
phpstanFunctionalProgramming:
47+
disallowClasses: false
48+
```

Diff for: docs/rules/DisallowLoopsRule.md

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# DisallowLoopsRule
2+
3+
*Forbid the use of loops*
4+
5+
Loops, such as `for`, `foreach`, `do` or `while` loops, work well when using a procedural paradigm. In functional programming, recursion or implementation agnostic operations like `array_map`, `array_filter` and `array_reduce` are preferred.
6+
7+
### Fail
8+
9+
```php
10+
<?php
11+
12+
$result = [];
13+
$elements = [1, 2, 3];
14+
15+
for ($i = 0; $i < count($elements); $i++) {
16+
if ($elements[$i] > 2) {
17+
$result[] = $elements[$i];
18+
}
19+
}
20+
21+
foreach ($elements as $element) {
22+
$result[] = $element * 10;
23+
}
24+
25+
$a = 1;
26+
while ($a < 100) {
27+
$result[] = $a;
28+
$a *= 2;
29+
}
30+
31+
$b = 1;
32+
do {
33+
$result[] = $b;
34+
$b *= 2;
35+
} while ($b < 100);
36+
```
37+
38+
### Pass
39+
40+
```php
41+
<?php
42+
43+
$elements = [1, 2, 3];
44+
45+
$result1 = array_filter($elements, fn($element) => $element > 2);
46+
47+
$result2 = array_map(fn($element) => $element * 10, $elements);
48+
49+
function doubleThemAll(int $n): array
50+
{
51+
if ($n >= 100) {
52+
return [];
53+
}
54+
55+
return [$n, ...doubleThemAll($n * 2)];
56+
}
57+
58+
$result3 = doubleThemAll(1);
59+
```
60+
61+
## Rule configuration
62+
63+
The rule is enabled by default. To turn it off, edit your *phpstan.neon* file.
64+
65+
```neon
66+
parameters:
67+
68+
phpstanFunctionalProgramming:
69+
disallowLoops: false
70+
```

Diff for: docs/rules/DisallowMutatingFunctionsRule.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# DisallowMutatingFunctionsRule
2+
3+
*Forbid the use of mutating functions*
4+
5+
If you want to program as if your variables are immutable, you should not use mutating functions of arrays, such as `array_push`. This rule reports the use of functions with the following names: `array_multisort`, `array_pop`, `array_push`, `array_shift`, `array_splice`, `array_unshift`, `arsort`, `asort`, `krsort`, `ksort`, `natcasesort`, `natsort`, `rsort`, `shuffle`, `sort`, `uasort`, `uksort`, `usort`.
6+
7+
### Fail
8+
9+
```php
10+
<?php
11+
12+
$arr1 = [10, 100, 100, 0];
13+
$arr2 = [1, 3, 2, 4];
14+
15+
array_multisort($arr1, $arr2);
16+
$last = array_pop($arr2);
17+
array_push($arr2, 6, 7);
18+
$first = array_shift($arr2);
19+
array_splice($arr1, 2);
20+
array_unshift($arr1, -1, 0);
21+
arsort($arr2);
22+
asort($arr2);
23+
krsort($arr2);
24+
ksort($arr2);
25+
natcasesort($arr2);
26+
natsort($arr2);
27+
rsort($arr2);
28+
shuffle($arr2);
29+
sort($arr2);
30+
uasort($arr2);
31+
uksort($arr2);
32+
usort($arr2);
33+
```
34+
35+
## Rule configuration
36+
37+
The rule is enabled by default. To turn it off, edit your *phpstan.neon* file.
38+
39+
```neon
40+
parameters:
41+
42+
phpstanFunctionalProgramming:
43+
disallowMutatingFunctions: false
44+
```

Diff for: docs/rules/DisallowMutationRule.md

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# DisallowMutationRule
2+
3+
*Forbid the use of mutating operators*
4+
5+
If you want to program as if your variables are immutable, part of the answer is to not mutation by re-assigning to a variable, and not use update operators like `++`, `+=` or `--` and others.
6+
7+
### Fail
8+
9+
```php
10+
<?php
11+
12+
$a = 6;
13+
$b =& $a;
14+
$text = 'hello';
15+
$arr = [1, 2, 3];
16+
17+
$b = 18;
18+
$a = 15;
19+
20+
$a += 1;
21+
$a -= 1;
22+
$a *= 1;
23+
$a /= 1;
24+
$a %= 1;
25+
$a ??= 7;
26+
$text .= ' world';
27+
...
28+
29+
$a++;
30+
$a--;
31+
++$a;
32+
--$a;
33+
34+
function (int $num1, &$num2)
35+
{
36+
$num1 = 2;
37+
$num2 = 5;
38+
}
39+
40+
$fn = function () use ($a, &$b) {
41+
$a = 5;
42+
$b = 10;
43+
};
44+
45+
$arr[1] = 5;
46+
$arr[] = 125;
47+
$arr = [5, 6, 7];
48+
[$a, $b] = $arr;
49+
```
50+
51+
## Rule configuration
52+
53+
The rule is enabled by default. To turn it off, edit your *phpstan.neon* file.
54+
55+
```neon
56+
parameters:
57+
58+
phpstanFunctionalProgramming:
59+
disallowVariablesMutation: false
60+
```

Diff for: docs/rules/DisallowThrowRule.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# DisallowThrowRule
2+
3+
*Forbid the use of `throw`*
4+
5+
When you throw an exception in PHP, you effectively perform a `GOTO`: your position in the program's execution jumps to the appropriate exception handler, and execution continues. This is fine, but it obviously means that your original function has a side-effect: calling it will fundamentally alter the program flow.
6+
7+
### Fail
8+
9+
```php
10+
<?php
11+
12+
function throwAnError(): void
13+
{
14+
throw new Exception('some error message');
15+
}
16+
```
17+
18+
## Rule configuration
19+
20+
The rule is enabled by default. To turn it off, edit your *phpstan.neon* file.
21+
22+
```neon
23+
parameters:
24+
25+
phpstanFunctionalProgramming:
26+
disallowThrow: false
27+
```

Diff for: docs/rules/DisallowUnusedExpressionRule.md

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# DisallowUnusedExpressionRule
2+
3+
*Enforce that an expression gets used*
4+
5+
In functional programming, functions do not mutate any values or cause side-effects, and it is therefore useless to call a function without using its result. The result should be assigned to a variable, passed as a parameter of another function, etc. Unused literals are reported too as they represent dead code.
6+
7+
### Fail
8+
9+
```php
10+
<?php
11+
12+
2 + 5;
13+
14+
foo();
15+
16+
function sum(int $a, int $b)
17+
{
18+
2 + 5;
19+
}
20+
21+
sum(2, 5);
22+
```
23+
24+
### Pass
25+
26+
```php
27+
<?php
28+
29+
$result1 = 2 + 5;
30+
31+
$result2 = foo();
32+
33+
function sum(int $a, int $b): int
34+
{
35+
return 2 + 5;
36+
}
37+
38+
$result3 = sum(2, 5);
39+
40+
```
41+
42+
## Rule configuration
43+
44+
The rule is enabled by default. To turn it off, edit your *phpstan.neon* file.
45+
46+
```neon
47+
parameters:
48+
49+
phpstanFunctionalProgramming:
50+
disallowUnusedExpression: false
51+
```

0 commit comments

Comments
 (0)