PathToPerformance

Here's the rough sketch of this blogpost:

  1. I will give a brief intro to BQN and talk about its pros and cos

  2. I will show a few Julia vs BQN code problems side by syde

  3. I will argue that there's areas for Julians to draw inspiration from BQN

  4. I will give a few resources at the end for you to dive deeper.

As usual, if you want to support my writings and open source work, please consider sponsoring me on GitHub. I'm reaaaaally close to 50 monthly sponsors, and it makes a huuuuge difference in how much time/worries/resources I have for working on stuff like this.

Alright, on with the blogpost.


Why is BQN is cool

  1. It has fast multidimensional arrays

  2. They love unicode

  3. It has a REPL!

  4. It's super at code golfing 🏌

  5. It's self hosted

  6. They use JuliaMono! 💝

  7. They're building a JIT!

Name: funny bacon puns. BQN vs APL:

Getting started

Range:

Scripting

online REPL or download BQN repo and open with browser BQN/docs/try.html from their github repo.

Everything in green is a function Everything in yellow is a 1 modifier Everything in purple/pink is a 2 modifer

Defining Hi function

REPL Duel

Tutorial

Julia vs BQN problems:

Here's a few "classic" problems in both Julia and BQN

  1. Find the Hamming/edit distance between 2 strings:

julia> dist(s1, s2) = count(((x,y),) -> x != y, zip(s1, s2))
dist (generic function with 1 method)

julia> dist("ACCAGGG", "ACTATGG")
2

julia> dist(s1, s2) = sum(map(!=, s1, s2)) # kudos to Michael Abbot for the broadcasting tip
dist (generic function with 1 method)

julia> dist(s1, s2) = mapreduce(!=, +, s1, s2) # kudos to J. Ling for this one

And in BQN:

s1 ← "XXXXGGG"
s2 ← "ACTAGGG"
Sol ← +´≠
s1 Sol s2 # 4

This is a neat 3 char solution that Asher will no doubt be very proud of.

  1. Increasing Array

You should take 3 minutes to go read the problem statement.

I like that after seeing the problem (you should go and click the link), I didn't think about a C++ but a BQN solution. Here's my attempt:

a ← 3‿2‿5‿1‿7
+´a-˜⌈`a
Sol ← {+´𝕩-˜⌈`𝕩}
Sol ← +´∘(⌈`-⊢) # Asher's solution
Sol a

which in Julia I would write like

x = [3 2 5 1 7]
sol(x) = accumulate(max, x) - x |> sum
sol(x)

Which took be a bit because scanl is called accumulate in Julia. Not too shabby. (Extra kudos if you can get a non-allocating version working)

  1. Maximum parenthesis depth

What Julians can learn from BQN

  1. Broadcasting semantics, Each ([¨](https://mlochbaum.github.io/BQN/doc/map.html)), and Taking Arrays Seriously™

  2. Data parallelism techniques

  3. Bit vector optimizations

  4. Flattening data recursive structures for performance

  5. Array-ify all the things

  6. Algorithmic thinking

Notes and words of caution

3 1⊸+⊸× 5
20
    3‿1⊸+⊸× 5
⟨ 40 30 ⟩

As stated in the page, general array notation is a thorny problem in APL, and it took Julia about 10 years to finally nail down the tools and syntax to land it in Base..

Sol ← +´∘(⌈`-⊢)
"whatsin" {(𝕨∊𝕩)/𝕨} "intersect"
"whatsin" (∊/⊣) "intersect"

proficiently will really up your game in code-golfing powers, should you be interested in that. This APL Wiki page and the Trainspotting links and videos at the end are also useful resources.

Interesting resources

For those that truly want to stare into the abyss and have it stare right back at them, there's some ~university level courses that are written in APL/BQN/J.

What's next?

...Well, I think I want to learn a bit from the people that took parallelism and performance seriously in ML aka, "What if Haskell wasn't slow and they wanted to dunk on MATLAB"?

Don't forget...

miguelito:

If you want to see more blogposts, sponsor me on GitHub