PHPackages                             md/for-comprehension-preprocessor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. md/for-comprehension-preprocessor

ActivePre-macro[Utility &amp; Helpers](/categories/utility)

md/for-comprehension-preprocessor
=================================

0.1.1(6y ago)411MITRubyCI failing

Since Jul 22Pushed 6y agoCompare

[ Source](https://github.com/MarcelloDuarte/for-comprehension-preprocessor)[ Packagist](https://packagist.org/packages/md/for-comprehension-preprocessor)[ RSS](/packages/md-for-comprehension-preprocessor/feed)WikiDiscussions master Synced 2w ago

READMEChangelog (2)Dependencies (3)Versions (3)Used By (0)

A for-comprenhensions pre-processor for PHP
===========================================

[](#a-for-comprenhensions-pre-processor-for-php)

For-comprenhensions are syntax sugar for composing certain group of operations that can be found in monadic collections: `withEach`, `withFilter`, `filter`, `map` and `flatMap`. This pre-processor will translate the operations using the for-comprenhension syntax into pure PHP. This does not happen at runtime, so there is no hit on perfomance. The pre-processor works on top of the [pre](https://github.com/preprocess/pre-plugin) plugin and the [yay macro library](https://github.com/marcioAlmada/yay).

Let's see how it works in practice with iteration, filtering, mapping and flatmapping.

Iteration
---------

[](#iteration)

```
for ($a withEach(function ($a) {
    echo $a;
});
```

which prints

```
123

```

Ok, that's boring. PHP foreach does the same. Or does it? With this syntax you can do many iterations in one go.

```
for ($a withEach(function($c) use ($a, $b) {
            echo ($a + $b + $c) . "\n";
        });
    });
});
```

and prints

```
3
6
9

```

Hmm! Starting to be interesting, huh? Oh! but's this is really nothing yet.

Mapping
-------

[](#mapping)

When using the `yield` keyword, one-liner for-comprehensions translate to mapping:

```
for ($a map(function() {
    return $a + 1;
});
```

which produces a `ImmList(2, 3, 4)`.

Flatmapping
-----------

[](#flatmapping)

You can compose these expressions to create bigger expressions. When you add lines to your for-comprehension you get them translated into `flatMap` operations, only the last one remains a `map`.

```
for {
    $a map(function ($c) use ($a, $b) {
            return $c;
        });
    });
});
```

This is actually a very common pattern in functional programming and a very good way to keep operations within a pure context. The code below has no side effects and describes IO operations in a functional program.

```
for {
    $line map(function ($a) {
    return $a;
});
```

The result is a new List with only the elements that satisfy the predicate `$a % 2 == 0` or, in order words, are even.

A more complex example

```
for {
    $a flatMap(function ($a) {
    return ImmList(1, 2, 3)->withFilter(function ($b) use ($a) {
        return $b % 2 != 0;
    })->map(function ($b) use ($a) {
        return Pair($a, $b);
    });
});
```

We can also add the filters in the next line:

```
for {
    $a withFilter(function ($b) use ($a) {
        return $b % 2 != 0;
    })->map(function ($b) use ($a) {
        return Pair($a, $b);
    });
});
```

Note that the pre-processor recognises tuples syntax, so you can return tuples and have them assigned to more than one varible:

```
for {
    ($a) _1;
    return Some(Pair(1, 2))->map(function ($t1) use ($a) {
        $b = $t1->_1;
        $c = $t1->_2;
        return $b;
    });
});
```

or you can return tuples:

```
for {
    $a
