*There is none. They are mostly point-free!*

.

or

as in point-free programming,

a point is a function argument

```
public static final void myFunction(String x) {...}
↑
```

== tacit programming

a programming paradigm in which function definitions do not identify the arguments (or "points") on which they operate. Instead the definitions merely compose other functions, among which are combinators that manipulate the arguments.

unix pipes

```
echo "hello old" | tr "h" "H" | sed s/old/world/
```

which in Java could be:

```
Function<String,String> f1 = str -> str.replace('h', 'H');
Function<String,String> f2 = str -> str.replace("old", "world");
f1.andThen(f2).apply("hello old");
```

Haskell

```
keepEven list = filter (\x -> x `mod` 2 == 0) list
```

```
keepEvenPointFree = filter (\x -> x `mod` 2 == 0)
```

```
keepEvenEvenMorePointFree = filter ((== 0) . (`mod` 2))
```

If you know Haskell and partial application,

the last one is perfectly readable.

== eta-reduction and eta-abstraction

Point-free style can be obtained via eta-reduction:

\x -> abs x ==> abs

The opposite of eta-abstraction:

abs ==> \x -> abs x

Conversion to (at least some) point-free form can be automated: http://pointfree.io

```
keepHalf list = take (length list `div` 2) list
```

```
> nix-shell -p haskellPackages.pointfree --run \
"pointfree -v '\list -> take (length list \`div\` 2) list'"
```

```
keepHalfPointFree = ap (take . flip (div . length) 2) id
```

🤔 Wait a second, that doesn’t look simple or easy!

Point-free style can (clearly) lead to Obfuscation when used unwisely. ... Perhaps these are why pointfree style is sometimes (often?) referred to aspointless style.

https://trends.google.com/trends/explore?date=all&q=point-free

https://trends.google.com/trends/explore?date=all&q=tacit%20programming

Uh, didn't look too good...

https://trends.google.com/trends/explore?date=all&q=combinator

Let’s use this one!

A function or definition with no free variables == A pure lambda-expression that refers only to its arguments

https://wiki.haskell.org/Combinator

A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.

https://en.wikipedia.org/wiki/Combinatory_logic

```
\a -> a
\a -> \b -> a
\f -> \a -> \b -> f b a
```

It is perhaps surprising that lambda-calculus can represent any conceivable computation using only the simple notions of function abstraction and application based on simple textual substitution of terms for variables. But even more remarkable is that abstraction is not even required. Combinatory logic is a model of computation equivalent to lambda calculus, but without abstraction.

no abstraction == no creation of lambdas

== no function arguments

But the example combinators on the previous slide were lambdas themselves!?!

Yes, but we assume that there exists a primitive set of combinators, from which more can be built without lambda abstraction.

- S-K-I

https://en.wikipedia.org/wiki/SKI_combinator_calculus - or just S-K (since I == SKK)
- B-C-K-W

https://en.wikipedia.org/wiki/B,_C,_K,_W_system - or just one of infinitely many one-point bases

https://www.sciencedirect.com/science/article/pii/S0020019003005416

Lambda calculus is sometimes also called **λK-calculus**, meaning that in combinator logic there’s a **K** combinator involved.

`K x y = x`

**K** is *cancellative*, it doesn’t use one of it’s arguments.

In **λI-calculus**, there’s no **K**

(that is, all arguments must be used)

Single-letter-names are a bit mathy.

Raymond m. Smullyan: To Mock a Mockingbird

- I
- Idiot x = x
- K
- Kestrel x y = x
- I*
- IdiotOnceRemoved x y = x y
- T
- Thrust x y = y x
- C
- Cardinal x y z = x z y
- B
- Bluebird x y z = x (y z)
- Q
- Queer x y z = y (x z)
- B
- Blackbird x y z w = x (y z w)
- ...

By Ryser915 at English Wikipedia, CC BY-SA 3.0, Link

By Yathin S Krishnappa - Own work, CC BY-SA 3.0, Link

By Dakota L. - Own work, CC BY-SA 3.0, Link

By Dehaan - Own work, CC BY-SA 3.0, Link

By Juan Emilio from Las Palmas de Gran Canaria, España - Mirlo. (Turdus merula cabrerae.)(♂)Uploaded by Snowmanradio, CC BY-SA 2.0, Link

```
keepHalf list = take (length list `div` 2) list
keepHalfPointFree = ap (take . flip (div . length) 2) id
```

phoenix == *pass a single value through two different functions, and pass the results to a two-parameter function*

```
phoenix x y z w = x (y w) (z w)
keepHalfCombi = phoenix take ((`div` 2) . length) id
```

starling == *pass a single value straight and also through a function, to a two-parameter function*

```
starling = x y z = x z (y z)
keepHalfCombi2 = starling (flip take) ((`div` 2) . length)
```

cardinal' == *pass first argument straight, and second argument through a function, to a two-parameter function*

warbler == *elementary duplicator*

```
cardinal' x y z w = x (y w) z
warbler x y = x y y
keepHalfCombi3 = warbler $ cardinal' take ((`div` 2) . length)
```

There might be a day, when these are taught in the universities and we all know all these combinators by heart!

...meanwhile, is there something easier?

Starling == *Applicative's (<*>) on functions*

Like ordinary application of *take* with two arguments:

```
keepHalf list = take (length list `div` 2) list
```

but instead we use kind of *lifted function application*,

syntactically with operators <$> and <*>:

```
keepHalfApplicative = take <$> ((`div` 2) . length) <*> id
```

This is actually readable!

By abstracting over function application in our language, we might not even need the operators...

Can be visualised as data flow

```
nix-shell --pure -p graphviz --run 'echo "digraph g{\
rankdir=\"LR\";\
\"input-list\" -> \"((\`div\` 2) . length)\";\
\"((\`div\` 2) . length)\" -> \"take :: Int -> [a] -> [a]\";\
\"input-list\" -> \"take :: Int -> [a] -> [a]\";\
\"take :: Int -> [a] -> [a]\" -> \"result-list\"\
}" | dot -Tsvg > graph.svg'
```

Imagine your editor/IDE to automatically visualize all Applicative-function usages with this kind of (even interactive) graphics!

Each previous example had something awkward

```
missingBird :: (b -> a -> c) -> (a -> b) -> a -> c
missingBird x y z = x (y z) z
keepHalfCombi4 = missingBird take ((`div` 2) . length)
```

I couldn't find references to this kind of combinator...?

```
-- from Haskell base:
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
someListOfTuples = [(1,'a'), (2,'b')]
sortedByNumberVerbose = sortBy (\t1 t2 -> compare (fst t1) (fst t2)) someListOfTuples
```

Do we happen to have a combinator for:

*Pass both parameters through same function, and pass the results to a two-parameter function*?

```
psi x y z w = x (y z) (y w)
sortedByNumberCombinator = sortBy (psi compare fst) someListOfTuples
```

This need was recognised ages ago

There’s already a psi bird with a different name in Haskell base: **on**

```
-- http://hackage.haskell.org/package/base/docs/Data-Function.html#v:on
sortedByNumberOn = sortBy (compare `on` fst) someListOfTuples
```

```
nix-shell --pure -p graphviz --run 'echo "digraph g{\
rankdir=LR;\
\"compare\" -> \"on :: (b -> b -> Ordering) -> (a -> b) -> a -> a -> Ordering\";\
\"fst\" -> \"on :: (b -> b -> Ordering) -> (a -> b) -> a -> a -> Ordering\";\
\"on :: (b -> b -> Ordering) -> (a -> b) -> a -> a -> Ordering\" -> \"sortBy :: (a -> a -> Ordering) -> [a] -> [a]\";\
\"input-list\" -> \"sortBy :: (a -> a -> Ordering) -> [a] -> [a]\";\
\"sortBy :: (a -> a -> Ordering) -> [a] -> [a]\" -> \"result-list\"\
}" | dot -Tsvg > graph2.svg'
```

"Point-Free or Die: Tacit Programming in Haskell and Beyond" by Amar Shah

aggregation == *first map over the function f, then sum the resulting numbers*

```
aggregate f list = sum (map f list)
```

in point-free style?

```
aggregate f = sum . map f
aggregate = (sum .) . map
```

Would we happen to have a combinator for:

*pass two parameters to a two-parameter function, and then pass the result to a one-parameter function*?

```
blackbird x y z w = x (y z w)
```

blackbird == *composition of composition and composition*

(.) . (.)

Yeah right, but the visualisation is clear

A function with the same type signature as blackbird happens to be defined in multiple Hackage packages with different name.

Could it be useful to have it defined in base with a suitable name, like that suggested by Amar Shah:

```
f ... g = (f .) . g
```

- Point-free style == tacit programming == no function arguments
- Point-free style can be extremely readable
- Excessive use of point-free style is bad for readability

- especially if one blindly takes what automatic tools provide - Knowledge of some basic building blocks is needed to figure out proper abstractions

- why oh why don’t they teach these to everyone in the university? - Combinators are often communicated by using names of specific birds
- Higher-level abstractions built from combinators might be more useful. For example:

- Applicative Functor of functions is awesome

- `on`

- blackbird - Using point-free style might bring opportunities for code visualisation

- My table of combinators (might contain errors)
- Recommended read: To Mock a Mockingbird and Other Logic Puzzles: Including an Amazing Adventure in Combinatory Logic by Raymond Smullyan

which is free-to-download - Recommended presentation: Point-Free or Die: Tacit Programming in Haskell and Beyond by Amar Shah
- https://en.wikipedia.org/wiki/Tacit_programming
- http://pointfree.io
- http://hackage.haskell.org/package/data-aviary-0.4.0/docs/Data-Aviary-Birds.html
- https://wiki.haskell.org/Pointfree
- https://en.wikipedia.org/wiki/Combinatory_logic
- http://www.angelfire.com/tx4/cus/combinator/birds.html
- http://dkeenan.com/Lambda/index.htm

Forget that cutting edge JavaScript framework!

Learn you a fundamental tool for great good!

Thank you.

link to this presentation: https://lahteenmaki.net/dev_*19/