commit a63eef012aec910b1ad03986862d0a72d67c8e07
parent 25fe1d35d7dbbb601fa63d5b412455a443663730
Author: mpizzzle <m@michaelpercival.xyz>
Date: Fri, 24 Feb 2023 11:35:55 +0000
minor touching up
Diffstat:
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/content/thoughts/dyalog-scan.md b/content/thoughts/dyalog-scan.md
@@ -4,26 +4,24 @@ date: 2023-02-22T19:57:02Z
draft: false
---
-I saw [this](https://twitter.com/code_report/status/1628131083760898052/photo/1) recent tweet by Conor Hoekstra, which has some neat (riveting, even) code comparisons.
+I saw [this](https://twitter.com/code_report/status/1628131083760898052/photo/1) recent tweet by Conor Hoekstra, which has some artistic code comparisons.
-The idea is to write a function that can tell whether there are at least 3 consecutive odd numbers in a given array.
+The problem he gives is to write a function that can tell whether there are at least 3 consecutive odd numbers in a given array.
-He broadly compares three algorithms across a few different languages:
+He broadly compares three algorithmic solutions across a few different languages:
{{< img src="/assets/three-odd-ints.png" width="900" height="480">}}
-The image highlights a few curiosities that I'd like to touch upon, namely:
+The image highlights a few questions that I'd like to touch upon, namely:
- what's up with BQN partitioning?
- is APL's scan really broken?
- (sorry q, perhaps I'll learn about you another time.)
-Lets find out.
-
---
-So why is writing a "ChunkBy" algorithm harder in BQN than APL?
+So, why is writing a "ChunkBy" algorithm harder in BQN than APL?
-I see the main difference in the following glyphs: APL has a dedicated '[partition](http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Partition.htm)' function (dyadic
+The main difference is in the following glyphs: APL has a dedicated '[partition](http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Partition.htm)' function (dyadic
{{< highlight APL "hl_inline=true, style=catppuccin-mocha" >}}
⊆
{{< /highlight >}}), whereas BQN has the more generalised '[group](https://mlochbaum.github.io/BQN/help/groupindices_group.html)'
@@ -31,7 +29,7 @@ I see the main difference in the following glyphs: APL has a dedicated '[partiti
(⊔)
{{< /highlight >}}.
-Group has a bit of a learning curve, but is the more [flexible](https://mlochbaum.github.io/BQN/commentary/problems.html#how-to-choose-a-partitioning-function) of the two primitives; the trade-off however is that partitions in BQN are done [idiomatically](https://mlochbaum.github.io/BQN/doc/group.html#partitioning) rather than as a single glyph.
+Group has a bit of a learning curve to it, but is the more [flexible](https://mlochbaum.github.io/BQN/commentary/problems.html#how-to-choose-a-partitioning-function) of the two primitives; the trade-off is that partitions in BQN have to be done [idiomatically](https://mlochbaum.github.io/BQN/doc/group.html#partitioning) rather than as a single glyph.
Here is a potential BQN [partition](https://mlochbaum.github.io/bqncrate/?q=Cut%20slice#) solution to Conor's problem:
@@ -57,10 +55,12 @@ G ⟨1,2,3,7,5,6⟩
These both look overly cumbersome, and well, they are.
-However, I think there is a hidden clue: within each partition function is a plus scan
+However, I think there is a hidden clue as to why: within each partition function is a plus scan
{{< highlight APL "hl_inline=true, style=catppuccin-mocha" >}}
(+`)
-{{< /highlight >}}, and isn't that already the basis for the first algorithm? I would take that as a hint from the cosmos that partitioning is not a highly baconic approach here, and to instead go with either a scan or windowed reduction.
+{{< /highlight >}}, and isn't that already the basis for the first algorithm?
+
+I would take that as a hint from the cosmos that partitioning is not the highly baconic approach here, and to instead go with either a scan or windowed reduction.
---
@@ -87,12 +87,12 @@ Scan in APL is applied left-to-right, so why do we not instead get
(3 ¯3 ¯4 ¯12 ¯17)
{{< /highlight >}}?
-The missing ingredient is that each intermediate is equivalent to a minus reduction
+The missing ingredient is that each intermediate is really a minus reduction
{{< highlight APL "hl_inline=true, style=catppuccin-mocha" >}}
(-/)
{{< /highlight >}} of the elements up to n, and reductions in APL are evaluated _right-to-left_. Therein lies the problem!
-For example, applying a minus reduction to the first four elements yields the fourth element of the minus scan:
+For example, applying a minus _reduction_ to the first four elements yields the fourth element of the minus scan:
{{< highlight APL "linenos=true, style=catppuccin-mocha" >}}
-/ 3 6 1 8 ⍝ i.e. (3-(6-(1-8)))
⍝ ¯10
@@ -126,7 +126,7 @@ being a right fold in BQN (left fold is
{{< /highlight >}}),
I think that this is still the more intuitive scan primitive, so I do sympathise with Conor's assertion.
-To add another example, Haskell also agrees with this left scan definition:
+As another example, Haskell also agrees with this left scan definition:
{{< highlight haskell "linenos=true, style=catppuccin-mocha" >}}
ghci> scanl1 (-) [3,6,1,8,5]