From a26bd4e58c96734c142e0a79f4839d2e1c006fa1 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Sun, 17 Jul 2022 22:13:00 -0400 Subject: Section on ambivalence in tacit code --- doc/tacit.md | 8 +++++++- docs/doc/tacit.html | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/tacit.md b/doc/tacit.md index 75ab320f..67079c89 100644 --- a/doc/tacit.md +++ b/doc/tacit.md @@ -67,6 +67,12 @@ The [Repeat](repeat.md) (`⍟`) modifier makes a nice "if" conditional. `F⍟G`, For more complicated "if-else" or "select" type conditionals, use [Choose](choose.md) (`◶`). Watch for ordering here: `F◶⟨G0,G1⟩` puts the two parts in the opposite order to Repeat, and list element 1 comes after element 0 even though it might seem more intuitive for the "true" value to come first. +## Valences + +An ambivalent function is one that can take one or two arguments. Tacit code has a hot-and-cold kind of relationship with it. In cases that fit well with Atop, Over, and trains, it tends to work very well. In others, it might [not work](../commentary/problems.md#cant-always-transfer-ambivalence-in-tacit-code) at all. An example is the `{𝕨𝔽𝔾𝕩}` combinator: there's just no tacit equivalent. However, any ambivalent *function* can still be represented, because [Valences](valences.md) (`⊘`) combines a separate monadic and dyadic case. + +When designing complex ambivalent functions, it's often best to mix tacit programming with blocks. I usually think of the block as the base for this, since `𝕨` tends to work with, and might put small tacit functions like `⊢⊘∾` inside, or tack on shared functionality such as `⌽∘…` on the outside. + ## Example: combinations As an example, we'll look at the following [combinations function](https://en.wikipedia.org/wiki/Binomial_coefficient) implementation from bqncrate (substituting the conventional `k` and `n` in for `i0` and `j0`): @@ -87,7 +93,7 @@ This says there are 10 ways to choose 3 out of 5 different options. Of course it k {(×´𝕩-↕𝕨)÷×´1+↕𝕨} n -But we are on the tacit page, so we'd like to make it tacit. For better or for worse. There's a mechanical way to do this for many functions, using only identity functions and trains, and making no simplifications. First parenthesize all monadic functions, as these will become 2-trains. Then replace `𝕨` and `𝕩` with `⊣` and `⊢`, and add a `˙` to constants. For the number `1` the added `˙` isn't necessary unless it comes at the end of a train, but we include it here to show the principle. +But we are on the tacit page, so we'd like to make it tacit. For better or for worse. There's a mechanical way to do this for many functions, using only identity functions and trains, and making no simplifications. First parenthesize all monadic function calls, as these will become 2-trains. Then replace `𝕨` and `𝕩` with `⊣` and `⊢`, and add a `˙` to constants. For the number `1` the added `˙` isn't necessary unless it comes at the end of a train, but we include it here to show the principle. {(×´𝕩-↕𝕨)÷×´1+↕𝕨} diff --git a/docs/doc/tacit.html b/docs/doc/tacit.html index ef2483c6..3a2baaef 100644 --- a/docs/doc/tacit.html +++ b/docs/doc/tacit.html @@ -229,6 +229,9 @@ 3.5

For more complicated "if-else" or "select" type conditionals, use Choose (). Watch for ordering here: FG0,G1 puts the two parts in the opposite order to Repeat, and list element 1 comes after element 0 even though it might seem more intuitive for the "true" value to come first.

+

Valences

+

An ambivalent function is one that can take one or two arguments. Tacit code has a hot-and-cold kind of relationship with it. In cases that fit well with Atop, Over, and trains, it tends to work very well. In others, it might not work at all. An example is the {𝕨𝔽𝔾𝕩} combinator: there's just no tacit equivalent. However, any ambivalent function can still be represented, because Valences () combines a separate monadic and dyadic case.

+

When designing complex ambivalent functions, it's often best to mix tacit programming with blocks. I usually think of the block as the base for this, since 𝕨 tends to work with, and might put small tacit functions like inside, or tack on shared functionality such as on the outside.

Example: combinations

As an example, we'll look at the following combinations function implementation from bqncrate (substituting the conventional k and n in for i0 and j0):

k((×´)1+)˜n  # Number of unordered selections (combinations) of k items from n choices
@@ -247,7 +250,7 @@
 ↗️
    k {(×´𝕩-↕𝕨)÷×´1+↕𝕨} n
 10
 
-

But we are on the tacit page, so we'd like to make it tacit. For better or for worse. There's a mechanical way to do this for many functions, using only identity functions and trains, and making no simplifications. First parenthesize all monadic functions, as these will become 2-trains. Then replace 𝕨 and 𝕩 with and , and add a ˙ to constants. For the number 1 the added ˙ isn't necessary unless it comes at the end of a train, but we include it here to show the principle.

+

But we are on the tacit page, so we'd like to make it tacit. For better or for worse. There's a mechanical way to do this for many functions, using only identity functions and trains, and making no simplifications. First parenthesize all monadic function calls, as these will become 2-trains. Then replace 𝕨 and 𝕩 with and , and add a ˙ to constants. For the number 1 the added ˙ isn't necessary unless it comes at the end of a train, but we include it here to show the principle.

{(×´𝕩-↕𝕨)÷×´1+↕𝕨}
 
 {(×´𝕩-(𝕨))÷(×´1+(𝕨))}  # Parenthesize monadic functions
-- 
cgit v1.2.3