From 8afd6d6d22e3b123423a95eae1389c3fa942a066 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Fri, 12 Aug 2022 09:33:39 -0400 Subject: Fix broken sentence --- docs/commentary/overload.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/commentary') diff --git a/docs/commentary/overload.html b/docs/commentary/overload.html index f45771f1..b5ab0f3e 100644 --- a/docs/commentary/overload.html +++ b/docs/commentary/overload.html @@ -26,7 +26,7 @@

If that was all, it would hardly be worth mentioning. A more significant family of extensions is the use of depth to allow a primitive to work on multiple axes in general but also to have a convenient one-axis form. Then there's character arithmetic, allowing 'a' + 3. In fact, isn't array arithmetic itself a big extension?

There are examples outside the array world that I find worse than anything in BQN. + for string catenation. This no longer obeys commutativity or distributivity: it's not safe to rearrange a + b to b + a or (a+b)*c to (a*c)+(b*c) in languages that do this! NumPy and MATLAB allow a boolean array to be used as an index, performing filtering. This one doesn't obey the rule that the length of a[b] is the length of b, or any other length-based rules really.

Sometimes what seems like an extension can be unified into a single more general primitive. For example, APL has scalar extension to allow you to add, say, a scalar to a list in 1 + 234. J and BQN use the more general leading axis agreement, which has this extension as a special case (although incidentally, BQN removes some unprincipled extension of list-like functions like Reverse to rank-0 arguments). Character arithmetic can also be viewed in this way considering numbers and characters to be pairs of "characterness" 0 or 1, and a numeric value.

-

I think many primitive pairs, such as -, , «, , and , fall into this category too. Primitives like can be described as a general dyadic function, and a monadic case that comes from a default left argument (sometimes dependent on the right argument: it's (=𝕩)-1 for ). The primitive is so tight it might be considered a fully compatible overload, returning a list of all arguments. Such primitive pairs can sometimes be used ambivalently in simple ways ( is pretty nice), but more often the usefulness is just that it's easier to think about each pair as one thing rather than two. It's just two views of the same idea.

+

I think many primitive pairs, such as -, , «, , and , fall into this category too. These can all be described as a general dyadic function, and a monadic case that comes from a default left argument (sometimes dependent on the right argument: it's (=𝕩)-1 for ). The primitive is so tight it might be considered a fully compatible overload, returning a list of all arguments. Such primitive pairs can sometimes be used ambivalently in simple ways ( is pretty nice), but more often the usefulness is just that it's easier to think about each pair as one thing rather than two. It's just two views of the same idea.

Mnemonic overloading

Okay, we are slipping down the slope nicely, now what about the primitives where the two halves don't quite do the same thing? Take to start smoothly. The dyadic form joins two lists and the monadic form joins a list of lists. Well, this is really one function that takes its arguments in a slightly unusual way, since dyadic is . The primitive for Prefixes/Take ( too) is similar, but in a trickier way: if 𝕨 is between 0 and 𝕩, 𝕨𝕩 is a prefix of 𝕩. Then is the list of all these prefixes, so 𝕨⊑↑𝕩 is 𝕨𝕩. It's almost a kind of partial application.

These primitives are easier to remember in the same way that it's much easier to memorize just instead of a select function and a separate first-cell function. If I weren't allowed to overload them together, I probably just wouldn't include monadic ↑↓⊏ (or √⋆, even -?), and maybe not even dyadic .

-- cgit v1.2.3