by Arne Sommer

# Abundantly First Class with Raku

[190] Published 3. July 2022.

This is my response to The Weekly Challenge #171.

## Challenge #171.1: Abundant Number

Write a script to generate first `20 Abundant Odd Numbers`.

According to wikipedia,

A number n for which the sum of divisors σ(n) > 2n, or, equivalently, the sum of proper divisors (or aliquot sum) s(n) > n.

For example, `945` is the first `Abundant Odd Number`.

```Sum of divisors: 1 + 3 + 5 + 7 + 9 + 15 + 21 + 27 + 35 + 45 + 63 + 105 + 135 + 189 + 315 = 975 ```
File: abundant-number ```#! /usr/bin/env raku unit sub MAIN (Int :c(:\$count) where \$count > 0 = 20, :v(:\$verbose)); # [1] my \$abundant := (1 .. Inf).grep( *.&is-abundant ); # [2] say \$abundant[^\$count].join(", "); # [3] sub divisors (\$number, :\$not-self, :\$not-one) # [4] { my @divisors; for (\$not-one ?? 2 !! 1) .. \$number/2 -> \$candidate { @divisors.push: \$candidate if \$number %% \$candidate; } @divisors.push: \$number unless \$not-self; say ": \$number -> @divisors[] = { @divisors.sum }" if \$verbose; return @divisors; } sub is-abundant (\$number) # [5] { return \$number % 2 && divisors(\$number, :not-self).sum > \$number; # [6] # return \$number % 2 && divisors(\$number).sum > \$number * 2; # [7] } ```

[1] Specify another number of values to print, if the default 20 does not suit you.

[2] Start with all the integers, and use `grep` to get only those that we want. Note the special `.&` calling syntax allowing us to pretend that a procedure is a method.

See docs.raku.org/language/operators#methodop_.& for more information about the special procedure invocation syntax `.&`.

[3] Print the required number of values from the sequence.

[4] This procedure should be familiar by now. See the second half of An Abundance of Numbers with Raku and Perl for details.

[5] Is the number abundant?

[6] Using the «Proper divisors» definition.

[7] Or you can use the «Divisors» definition.

Running it:

```\$ ./abundant-number 945, 1575, 2205, 2835, 3465, 4095, 4725, 5355, 5775, 5985, 6435, 6615, 6825, \ 7245, 7425, 7875, 8085, 8415, 8505, 8925 ```

Looking good.

You can use verbose mode to check the result manually, if you are so inclined. Here is a selection of the output:

```\$ ./abundant-number -v -c=1 : 1 -> = 0 : 3 -> 1 = 1 : 5 -> 1 = 1 : 7 -> 1 = 1 : 9 -> 1 3 = 4 : 11 -> 1 = 1 : 13 -> 1 = 1 … : 935 -> 1 5 11 17 55 85 187 = 361 : 937 -> 1 = 1 : 939 -> 1 3 313 = 317 : 941 -> 1 = 1 : 943 -> 1 23 41 = 65 : 945 -> 1 3 5 7 9 15 21 27 35 45 63 105 135 189 315 = 975 945 ```

## Challenge #171.2: First-class Function

Create `sub compose(\$f, \$g)` which takes in two parameters `\$f` and `\$g` as subroutine refs and returns subroutine ref i.e. `compose(\$f, \$g)->(\$x) = \$f->(\$g->(\$x))`.

e.g. ```\$f = (one or more parameters function) \$g = (one or more parameters function) \$h = compose(\$f, \$g) \$f->(\$g->(\$x,\$y, ..)) == \$h->(\$x, \$y, ..) for any \$x, \$y, ... ```

Let us start with the `f` and `g` functions:

File: first-class-function (partial) ```#! /usr/bin/env raku my \$f = sub f (\$val) # [1] { return \$val * 10; } my \$g = sub g (\$val) # [1] { return \$val + 1; } ```

[1] Two ordinary procedures, with one input value and one (deterministic) output value. The trick (so to speak) is the fact that the `sub` keyword returns a reference to the procedure, and we assign that value to a variable for each one.

See docs.raku.org/syntax/sub more information about `sub`.

#### Call Me

If you want to call a function, you can either use the name (i.e. the normal way):

```my \$b = f(12); ```

Or the reference (if you have one):

```my \$b = \$f(12); ```

The «compose» procedure is easy:

File: first-class-function (partial) ```sub compose(&f, &g) # [2] { return sub (\$arg) # [3] { &f(&g(\$arg)); # [4] }; } ```

[2] The procedure takes two arguments, of the callable type (courtesy of the `&` (Callable) sigil). Calling it with other argument types will fail. The generic `\$` sigil works just fine, but without the Callable check.

[3] An anonymous procedure (i.e. without name), taking one input parameter (in `\$arg`). The return value is a reference to this procedure.

[4] The procedure itself will - when executed - call the inner procedure `&g(\$arg)` first, and then the outer `&f` with the return value of the inner one.

And finally, executing the code:

File: first-class-function (the rest) ```my \$h = compose(\$f, \$g); # [5] say \$h(12); # [6] say \$h(13); # [7] my \$m = compose(\$g, \$f); # [8] say \$m(12); # [9] say \$m(13); ```

[5] Feel free to use the `&` (Callable) sigil here (i.e. `&h` instead of `\$h`), if that makes you feel better.

[6] Call the procedure(s).

[7] Ditto, with another input value.

[8] Changing the order of the procedures does matter.

[9] The same procedures, reordered, and the same input - but a different result.

Running it:

File: first-class-function (partial) ```\$ ./first-class-function 130 140 121 131 ```

Looking good.

And that's it.