[HN Gopher] My Ideal Array Language
       ___________________________________________________________________
        
       My Ideal Array Language
        
       Author : bobajeff
       Score  : 107 points
       Date   : 2025-08-04 13:05 UTC (9 hours ago)
        
 (HTM) web link (www.ashermancinelli.com)
 (TXT) w3m dump (www.ashermancinelli.com)
        
       | abcd_f wrote:
       | > _User-Extensible Rank Polymorphism_
       | 
       | > _IMO this is what makes something an array language._
       | 
       | Great to hear. So what is it?
        
         | preommr wrote:
         | Not op, but I assume it means that there's rank polymorphism
         | (i.e. data can be of arbitrary dimensions, and there's support
         | for things like functions working on both N-dimensions, without
         | having to specify n, or maybe setting constraints on n), and
         | that the polymorphism can be used on the programmer side (so
         | it's not limited to just a handful of language builtins)
         | through the oop equivalent of subclasses and interfaces.
        
           | goldenCeasar wrote:
           | A question, would you interpret this as rank polymorphism?
           | schema do         input do           array :regions do
           | float :tax_rate             array :offices do
           | float :col_adjustment               array :employees do
           | float :salary                 float :rating               end
           | end           end         end              trait
           | :high_performer, input.regions.offices.employees.rating > 4.5
           | value :bonus do           on high_performer,
           | input.regions.offices.employees.salary * 0.25           base
           | input.regions.offices.employees.salary * 0.10         end
           | value :final_pay,
           | (input.regions.offices.employees.salary + bonus *
           | input.regions.offices.col_adjustment) *           (1 -
           | input.regions.tax_rate)       end            result =
           | schema.from(nested_data)[:final_pay]       # => [[[91_000,
           | 63_700], [58_500]], [[71_225]]]
        
             | CraigJPerry wrote:
             | I think i'm misunderstanding, rank is explicit throughout
             | this example but i'm not familiar with this syntax (ruby
             | maybe?) but whatever the case i don't see the rank
             | polymorphism.
             | 
             | If i'm reading the syntax correctly, this would translate
             | in kdb/q to a raze (flatten) on the 3 dimensions (regions,
             | offices, employees). Probably more likely to be expressed
             | as a converge but in either case, the calculations here are
             | not possible in a rank polymorphic way.
        
               | goldenCeasar wrote:
               | The broadcasting handles the rank differences
               | automatically. When bonus (at employee level) multiplies
               | with col_adjustment (at office level), each employee's
               | bonus gets their office's adjustment applied, no
               | flattening or manual reshaping. The structure [[[91_000,
               | 63_700], [58_500]], [[71_225]]] was preserved.
               | 
               | This is from a Ruby DSL I'm working on (Kumi). Probably
               | the broadcasting semantics are very different from
               | traditional rank operators in q/APL?
               | 
               | Edit: I realized that I missed the input structure:
               | Region 0: Office 0 has 2 employees, Office 1 has 1
               | employee       Region 1: Office 0 has 1 employee
        
         | djoldman wrote:
         | The programmer can define functions that operate on matrices
         | without having to be explicit about the number of dimensions
         | and possibly (types of data, size of data, or length).
         | 
         | Example 1: A function that can take as input a 4x2x8 matrix or
         | a 3x7 matrix.
         | 
         | Example 2: A function that can take as input a 4x2x8 matrix and
         | a 3x7 matrix and output a third matrix.
        
           | almostgotcaught wrote:
           | > A function that can take as input a 4x2x8 matrix and a 3x7
           | matrix and output a third matrix.
           | 
           | which shows that this feature request is complete jibberish
        
             | rscho wrote:
             | Why gibberish ? It's a common feature in both array
             | languages and Iverson ghosts, and many find it extremely
             | useful.
        
             | tracker1 wrote:
             | You mean like a "winner" function able to check for both
             | Tic-Tac-Toe, a Connect Four field and a Similar 3D+ tower
             | game?
        
               | taeric wrote:
               | I'm not sure I follow? The "winning" condition is
               | different in all of those examples?
        
               | tracker1 wrote:
               | X adjacent cell values in an N dimensional array? For tic
               | tac toe, it's 3 in a row, for connect 4 it's 4 in a row.
        
           | tomsmeding wrote:
           | Rank polymorphism means that a function can be polymorphic in
           | the additional dimensions of arrays. For example, if you
           | write a function that takes a 2x3 and a 4x5 array, it can
           | also work on 10x15x2x3 and 10x15x4x5 arrays by broadcasting.
           | 
           | If rank polymorphism results in accepting both 4x2x8 and 3x7,
           | then that means the function was a function on elements to
           | begin with. Which is possible, but not the most interesting
           | application of rank polymorphism.
        
             | djoldman wrote:
             | > Rank polymorphism means that a function can be
             | polymorphic in the additional dimensions of arrays. For
             | example, if you write a function that takes a 2x3 and a 4x5
             | array, it can also work on 10x15x2x3 and 10x15x4x5 arrays
             | by broadcasting.
             | 
             | Thanks, this is what I was ineloquently attempting to
             | describe with "A function that can take as input a 4x2x8
             | matrix or a 3x7 matrix."
        
         | CapsAdmin wrote:
         | game math libraries often have this (and glsl gpu shader
         | language), like "2 * vec3(1,2,3)" results in "vec3(2,4,6)"
         | 
         | There are other cases like adding vectors to matrices and so
         | on, but in the end this logic is defined in some custom add
         | operator overload on a class or object in the language.
         | 
         | (I had no idea what it meant either until i searched for
         | examples..)
        
       | adregan wrote:
       | The author of this post was the guest on the most recent episode
       | of the podcast _The Array Cast_
       | 
       | https://www.arraycast.com/episodes/episode111-ideal-array-la...
        
       | teleforce wrote:
       | Dlang does not has rank polymorphism and it handle array just
       | fine with crazy speed in both compilation and execution.
       | 
       | It can be faster than Fortran based library that is still being
       | used by Matlab, Rust and Julia [1].
       | 
       | It will be interesting to compare Mojo moblas BLAS library with
       | GLAS library performance in D.
       | 
       | [1] Numeric age for D: Mir GLAS is faster than OpenBLAS and Eigen
       | (2016):
       | 
       | http://blog.mir.dlang.io/glas/benchmark/openblas/2016/09/23/...
        
         | cdavid wrote:
         | If I understand correctly what is meant by rank polymorphism,
         | it is not just about speed, but about ergonomics.
         | 
         | Taking examples I am familiar w/, it is key that you can add a
         | scalar 1 to a rank 2 array in numpy/matllab without having to
         | explicitly create a rank 2 array of 1s, and numpy somehow
         | generalizes that (broadcasting). I understand other array
         | programming languages have more advanced/generic versions of
         | broadcasting, but I am not super familiar w/ them
        
       | nromiun wrote:
       | [?]x0[?][?]"V[?][?][?]"           # Marshall & Dzaima (tacit!)
       | ([?][?]')V{x([?][?][?])0[?]} # Dzaima & Rampoina
       | {x([?]"V[?][?][?]")0[?]}     # Dzaima
       | 
       | Call me old fashioned and stuck in C style syntax but I can't
       | imagine anyone describing this as beautiful art.
        
         | hyperbrainer wrote:
         | I see it as beautiful the same way Galadriel would be beautiful
         | as the Dark Queen. Utterly captivating and powerful, and yet
         | something that should never be.
        
           | KineticLensman wrote:
           | "All shall love me and despair"
        
         | badlibrarian wrote:
         | When the junior programmers start saying "Turing complete" or
         | the academics build a DSL in Julia that uses RegEx to parse
         | Logic Symbols and stuffs the result in variables that use
         | ancient characters that don't appear on your keyboard, it's a
         | sure sign of imminent progress. Bonus if the PhD with nine
         | years of schooling and five months of PHP experience at
         | Facebook starts using emoji in commit messages.
        
           | hinkley wrote:
           | "irony! Oh, no, no, we don't get that here. See, uh, people
           | ski topless here while smoking dope, so irony's not really a,
           | a high priority. We haven't had any irony here since about,
           | uh, '83, when I was the only practitioner of it. And I
           | stopped because I was tired of being stared at."
        
         | ashleyn wrote:
         | It's giving APL:
         | https://en.wikipedia.org/wiki/APL_(programming_language)
        
           | icen wrote:
           | It is BQN, a descendant language
        
             | pavlov wrote:
             | Why is it BQN instead of BQM? Clearly the idea was to
             | increment every letter from APL, but then they had to go
             | one further on the third letter.
        
               | mlochbaum wrote:
               | It's just. So gross. Say it. Sudden interruption of slime
               | coming up your throat. Like walking out the door into a
               | spiderweb. Alphabetically I was mistaken but in every way
               | that matters I was right.
        
               | pavlov wrote:
               | Hmm. I guess it if was BQM, it would be pronounced
               | "bequem" which means comfortable in German.
               | 
               | And a comfortable APL is clearly an oxymoron.
        
               | mlochbaum wrote:
               | Ordinarily I'd make fun of the Germans for giving such an
               | ugly name to a nice concept, but I've always found
               | "comfortable" to be rather unpleasant too (the root
               | "comfort" is fine).
        
               | hinkley wrote:
               | I'm hoping they pronounce it "beacon" but the off by one
               | error jokes also just write themselves.
        
               | rscho wrote:
               | No, it's 'bacon' :-)
        
               | ModernMech wrote:
               | They were following a Fibonacci sequence.
        
               | taolson wrote:
               | Supposedly it stands for "Big Questions Notation", but
               | that could just be a backronym.
        
               | cenamus wrote:
               | I'm somewhat sure the author actually mentioned that that
               | was the intention, "Big Question Notation" and basically
               | "apl" + 1. But he realized that it didn't match up
        
               | BoiledCabbage wrote:
               | This actual answer according the the author realized
               | after he already liked the name.
               | 
               | He created it intending to be +1 of APL. Accidentally
               | came up with BQN instead of BQM. Sat with that for 1hr,
               | really liked the name, then realized that it should be
               | BQM which he hated, so he stuck with BQN.
               | 
               | That said, it's and _incredibly_ designed language. I
               | honestly have never read any language (especially not
               | designed by a single person) with the level of creative
               | thought as he put into BQN. Some really incredible
               | insights and deep understanding. It 's amazing reading
               | his posts / documentation about it. The focus on
               | ergonomics, brand new constructs and the
               | consistency/coherence of how all of his decisions fit
               | together is really impressive.
        
               | layer8 wrote:
               | So, you write bequations in it? ;)
        
         | mlochbaum wrote:
         | Well, do you know how it works? Don't judge a book by its cover
         | and all. Although none of these are entirely aiming for
         | elegance. The first is code golf and the other two have some
         | performance hacks that I doubt are even good any more, but
         | replacing [?][?] with [?][?] in the last gets you something
         | decent (personally I'm more in the "utilitarian code is never
         | art" camp, but I'd have no reason to direct that at any
         | specific language).
         | 
         | The double-struck characters have disappeared from the second
         | and third lines creating a fun puzzle. Original post
         | https://www.ashermancinelli.com/csblog/2022-5-2-BQN-reflecti...
         | has the answers.
        
         | skydhash wrote:
         | Array Programming is an acquired taste, but once you do,
         | solutions can be extremely simple, both to write and to
         | explain.
         | 
         | Think about using matrix to describe geometric transformations
         | instead of using standard functions.
        
           | badlibrarian wrote:
           | You mean abstracted stuff like this instead of two lines of
           | code that actually uses x and y?                 [ cos(th)
           | -sin(th)  0  0  ]       [ sin(th)   cos(th)  0  0  ]       [
           | 0        0       1  0  ]       [ 0        0       0  1  ]
        
         | rscho wrote:
         | This type of syntax allows rapid iteration when looking at
         | different implementations and experimenting with array
         | problems. It should be thought of more as math notation than
         | general programming.
        
       | rramadass wrote:
       | A previous relevant discussion since there is so little on Array
       | Languages - https://news.ycombinator.com/item?id=38981639
        
       | goldenCeasar wrote:
       | Funny, on another totally unrelated domain (business logic/rules
       | engines) I was building something very very related - array
       | broadcasting with semantic preservation through arbitrary nesting
       | levels
        
       | hinkley wrote:
       | You explain the evolution of CPUs but then don't explain Rank
       | Polymorphism.
        
         | IncreasePosts wrote:
         | It's just like polymorphism, only stinkier
        
         | jph00 wrote:
         | "Rank" means the number of dimensions of an array.
         | 
         | So "rank polymorphism" means being able to write expressions
         | that work correctly regardless of how many dims the arrays
         | involved have.
         | 
         | For example, in numpy you can write a function that handles
         | both lists and matrices automatically, by taking advantage of
         | broadcasting. (The J language takes this idea a lot further --
         | numpy is a fairly minimal implementation of the idea.)
        
           | hinkley wrote:
           | That just sounds like someone needing to feel smarter than
           | 'multidimensional arrays' sounds. Which if you ask the
           | average unskilled laborer, already sounds pretty damned
           | fancy.
        
             | diziet_sma wrote:
             | It's not the same thing as multidimensional arrays though.
             | You can have multidimensional arrays without rank
             | polymorphism. Rank polymorphism makes working with
             | multidimensional arrays much easier because you can write
             | one function which works over input arrays with different
             | shapes.
        
       | npalli wrote:
       | Strange to read this article and find no mention of Julia (but
       | APL, Mojo, MLIR BQN etc.. which are not exactly widely used
       | languages). It checks many of the boxes
       | 
       | User-Extensible Rank Polymorphism is just beautiful with the
       | broadcast dot syntax. I don't think any other language has this
       | clean and flexible implementation.
       | 
       | Others -- GPU programing, parallelism, etc. are pretty good with
       | Julia. Real shame it hasn't taken off.
        
         | capyba wrote:
         | I love working in Julia, it makes clean numerical code so easy
         | to write.
        
       ___________________________________________________________________
       (page generated 2025-08-04 23:00 UTC)