mpercivalxyz

this website!
Log | Files | Refs

commit a63eef012aec910b1ad03986862d0a72d67c8e07
parent 25fe1d35d7dbbb601fa63d5b412455a443663730
Author: mpizzzle <m@michaelpercival.xyz>
Date:   Fri, 24 Feb 2023 11:35:55 +0000

minor touching up

Diffstat:
Mcontent/thoughts/dyalog-scan.md | 28++++++++++++++--------------
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]