diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-04-15 19:23:10 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-04-15 19:26:07 -0400 |
| commit | 8ad841e92f70fba73a5c778aa972186387f9ff5c (patch) | |
| tree | 44d051e0c4d984ddc630cdbdb456d3b2b9dbf7cf /doc/hook.md | |
| parent | 08115ba7569cbd21cfe89be152a311e01ebb6c88 (diff) | |
Documentation for Before and After
Diffstat (limited to 'doc/hook.md')
| -rw-r--r-- | doc/hook.md | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/doc/hook.md b/doc/hook.md new file mode 100644 index 00000000..0eb5d5ce --- /dev/null +++ b/doc/hook.md @@ -0,0 +1,61 @@ +*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/hook.html).* + +# Before and After + +([This joke](https://aplwiki.com/wiki/File:Before_and_after.jpg) has already been claimed by APL, unfortunately) + +*Also see [this tutorial section](../tutorial/combinator.md#before-and-after) for an introduction that doesn't require so much context to understand.* + +<!--GEN combinator.bqn +DrawComp β"βΈβ" +--> + +The "hook" combinators Before and After serve a few purposes in BQN. The important thing to remember: the pointy side goes towards the first function to be executed, and the next function that returns the final result is at the ring side. If the pointy-side function is actually a constant like a number, then the ring-side function just gets applied to that constant and one of the arguments. This is the thing Haskell programmers are constantly telling each other isn't called currying, or "Bind" in BQN. + +| Name | `Cmp` | `Cmp π©` | `π¨ Cmp π©` | Unified | Train +|--------|-------|------------|------------|--------------|-------- +| Before | `FβΈG` | `(Fπ©) G π©` | `(Fπ¨) G π©` | `{(π½π¨β£π©)πΎπ©}` | `Fββ£ G β’` +| After | `FβG` | `π© F (Gπ©)` | `π¨ F (Gπ©)` | `{(π¨β£π©)π½πΎπ©}` | `β£ F Gββ’` + +## Description + +In the general case, I think of Before as using `π½` as a preprocessing function applied to `π¨` (when there are two arguments) and After as using `πΎ` as preprocessing for `π©`. Then the other operand is called on the result and remaining argument. Here are some simple calls with Pair (`β`): the result is a pair that corresponds to `π¨βΏπ©`, but one or the other result has been modified by the pointy-side function. + + 9 ββΈβ 2 + + 9 βββ 2 + +When only one argument is given, it's used in both positions, so that the arguments to the final function are `π©` and a function applied to `π©`. + + βββ 5 + +This can be used to make a "filter" pattern using [Replicate](replicate.md) (`/`). The difference is that Replicate takes a list `π©` and boolean list `π¨` indicating which elements to keep, but filter should take a list and a function that says whether to keep each element. The pattern is `FΒ¨βΈ/ x`, expanding to `(FΒ¨x) / x`. Here's a list filtered with the function `{π©<0}`. + + {π©<0}Β¨βΈ/ 4βΏΒ―2βΏ1βΏΒ―3βΏΒ―3 + +As `<` is a pervasive function, there's no need for the Each (`Β¨`) in this case, and the clunky block function `{π©<0}` can also be written smaller with a combinator, as `<β0`. More on that in the next sectionβ¦ + + <β0βΈ/ 4βΏΒ―2βΏ1βΏΒ―3βΏΒ―3 + +## Bind + +"Bind" isn't a special case of Before and After, but instead a description of one way to use them. Let's take a look at the example from the previous section: + + <β0 4βΏΒ―2βΏ1βΏΒ―3βΏΒ―3 + +If we expand `<β0 x`, we get `x < (0 x)`, which doesn't quite make sense. That's because `0` has a subject role, but `β` always applies its operands as functions. It's more accurate to use `x < (0{π½} x)`, or just skip ahead to `x < 0`. + +Similar reasoning gives the following expansions: + +| `Cmp` | `0βΈ<` | `<β0` +|-----------|---------|--------- +| ` Cmp x` | `0 < x` | `x < 0` +| `w Cmp x` | `0 < x` | `w < 0` + +Note that when there are two arguments, the constant "swallows" the one on the same side, so that the function is applied to the constant and the argument on the *opposite* side. + +As in a train, if you want to use a function as a constant then you need to be explicity about it, with the [Constant](constant.md) (`Λ`) modifier. + + 3 ββ(βΛ)βΈβ₯ 'a'+β12 + +In the more extreme case of wanting a *modifier* operand, you might try `ββ({β}Λ)βΈβ₯`, or `(β£β{β}Λ)βΈβ₯`, or just cheat with `βΎββ¨ββ©βΈβ₯`. |
