Functional Programming with Raku
Tags: raku, functional
Published: 2023-04-23 18:36:52

Raku is a great language for functional programming, it has support for anonymous functions (blocks), partial application via `assuming`, and much more.

In this post I hope to outline how I use Raku as a functional (object-oriented) programming language similar to how I'd write a language like Scala.

## The compose operator
In Raku `o` is an operator (a binary function). Which means we can compose two functions together to create a new one. This lets us build really cool abstractions over our functions. For example we can use it to create functions with hidden side-effects:

```raku
my $logger = -> $m { say $m; $m };
my $add-five = -> $x { $x + 5 };
my $add-five-and-log = $add-five o $logger;

say $add-five-and-log(25); # Prints 25, then prints 30
```

Note that the composition occurs backwards in a way, `$add-five o $logger` is equivalent to `-> x { $add-five($logger(x)) }`. Pretty neat right!

This also allows us to simply reduce arrays of functions into a single function, in the Humming-Bird source-code, you can see that in practice for "advice" the end-of-routing hooks:

```raku
method !add-route(Route:D $route, HTTPMethod:D $method --> Route:D) {
        my &advice = [o] @!advice;
        my &cb = $route.callback;
        my $r = $route.clone(path => $!root ~ $route.path,
                             middlewares => [|@!middlewares, |$route.middlewares],
                             callback => { &advice(&cb($^a, $^b)) });
        @!routes.push: $r;
        delegate-route($r, $method);
    }
```

This method on the Router class adds a route object to the context of the application, you'll notice the first line of the method, we apply `o` in a reduction to produce a single function from the advice array. `@!advice` being all the advice on this router. Advice are simply functions that take a response, and return a response. So you can imagine how the composition operator is layering all of them together like:

```
-> x { advice-four(advice-three(advice-two(advice-one(x)))) }
```

Then, to call the advice all we have to do is pass a response to the composition, and it will handle the rest.

## Assuming
Assuming is a method derived from the `Code` class, and it allows us to perform partial-application on a function. Partial application is very simple, it means to call a function with less arguments than it requires, which in-turn returns a new function that contains the parameters you've already supplied. For example if we have an `add` function that takes two numbers, we could partially apply it like so:

```
my $add = -> $x, $y { $x + $y };

my $add-five = $add.assuming(5);

say $add-five(10); # prints 15
say $add-five(5); # prints 10
```

The result of calling `.assuming(5)` on the `add` function is a new function that looks like: `-> $y { 5 + $y }`.

This is a really neat feature that lets us create what I like to call 'stateless-state', meaning we can add state to our functions without actually exposing it to the consumer of the function.

A fairly complicated, yet elegant example of using `.assuming` in the wild is Humming-Birds middleware system:

```
my &composition = @!middlewares.map({ .assuming($req, $res) }).reduce(-> &a, &b { &a({ &b }) });
&composition(&!callback.assuming($req, $res))
```

We have to map all middleware to partially-apply the request and response objects that will be used throughout the request chain, then reduce to a single function that will take another function. Then finally, call the composition with the callback provided by the user. This is what allows middleware to have the `$request, $response, &next` parameters. Calling `&next()` is simply calling the next partially applied function in the chain!

## Anonymous functions (blocks)
Raku is one of the only languages I know that has more than one way to declare an anonymous function (aka lambda). In Raku we have pointy-blocks (my favorite), normal blocks, [WhateverCodes](https://docs.raku.org/type/WhateverCode.html) and anonymous sub-routines.

Typically, in my experience, you'll be fine with a normal block for most things, unless you want to strictly define your parameters, then it's best to use a pointy-block or anonymous sub-routine. If you need to explicitly return i.e short-circuit you'll probably want to use an anonymous sub, otherwise a pointy block will do.

Here's the same function `add` written using each type of block:

##### Normal block
```
my &add = { $^a + $^b };
```

##### Whatever Code
```
my &add = * + *;
```

##### Pointy block
```
my &add = -> $a, $b { $a + $b };
```

##### Anonymous sub
```
my &add = sub ($a, $b) { $a + $b };
```

You can use the `&` sigil to declare functions stored in variables in a more 'Raku-ish' way, this will tell other developers that the variable is a `Callable`.

You can pass these anonymous functions to other functions, this is used fairly-extensively in the realm of reactive-programming. `whenever` registers a callback with an anonymous function (block or pointy block):

```
react {
    whenever Supply.interval(1) -> $second {
        say 'Current second: $second';
    }
}
```

In Raku's standard library, for example, a for loop takes a block or point block as an argument, you probably never thought about it like that before right?

```
for [1,2,3,4] -> $x { say $x }; # That block can be thought of as a lambda!
```

In Humming-Bird when you declare routes like:

```
get('/', -> $request, $response {
   $response.write('Hello World!');
});
```

In the background that block is taken in by the `get` function then registered as what to call when the router receives a request.

Overall, Raku has some really interesting and usable functional patterns. I personally am a big fan of partial application and the composition operator. It is really fun as-well!

To finish off I'd like to leave a fun example, see if you can predict the result:

```
([o] [-> $a { $a + 1 }, -> $a { $a + 1 }])(2).say
```

Take care! Raku rocks!