BQN: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
m (Compilers category)
m (Text replacement - "first-class function" to "first-class function")
 
(49 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{Infobox array language
{{Infobox array language
| logo                    = [[File:BQN logo.png]]
| array model              = [[based array model|based]]
| array model              = [[based array model|based]]
| index origin            = 0
| index origin            = 0
Line 7: Line 8:
| released                = 2020
| released                = 2020
| developer                = [[Marshall Lochbaum]]
| developer                = [[Marshall Lochbaum]]
| latest release version  = 2020 (unversioned)
| latest release version  = 0.7.0 / 2024-05-23
| implementation languages = BQN, [[wikipedia:JavaScript|JavaScript]]
| implementation languages = BQN with [[wikipedia:JavaScript|JavaScript]], [[wikipedia:C (programming language)|C]], or others<ref name="running">[[Marshall Lochbaum]]. [https://mlochbaum.github.io/BQN/running.html "How to run BQN"]</ref>
| source                  = [https://github.com/mlochbaum/BQN GitHub]
| source                  = [https://github.com/mlochbaum/BQN GitHub]
| platforms                = In-browser, [[wikipedia:Node.js|Node.js]]
| platforms                = x86, ARM, in-browser, [[wikipedia:Node.js|Node.js]]
| license                  = [[wikipedia:ISC license|ISC]]
| license                  = [[wikipedia:ISC license|ISC]]
| website                  = [https://mlochbaum.github.io/BQN mlochbaum.github.io/BQN]
| website                  = [https://mlochbaum.github.io/BQN mlochbaum.github.io/BQN]
| file ext                = .bqn
| file ext                = .bqn
| documentation            = [https://mlochbaum.github.io/BQN/doc Documentation]
| documentation            = [https://mlochbaum.github.io/BQN/doc Documentation]
| influenced by            = [[J]], [[A+]], [[Dyalog APL]], [[Co-dfns]], [[APL\iv]], [[wikipedia:JavaScript|JavaScript]]
| forum                    = [https://app.element.io/#/room/%23bqn:matrix.org #bqn:matrix.org]
| influenced              = [[dzaima/BQN]]
| influenced by            = [[J]], [[A+]], [[Dyalog APL]], [[Co-dfns]], [[APL\iv]], [[wikipedia:JavaScript|JavaScript]]<ref>[[Marshall Lochbaum]]. [https://mlochbaum.github.io/BQN/commentary/history.html "BQN's development history"].</ref>
| run online              = [https://mlochbaum.github.io/BQN/try.html Online REPL]
| influenced              = [[Goal]], [[Kap]], [[Uiua]], [[TinyAPL]]
| run online              = [https://bqnpad.mechanize.systems/ BQNPAD]
}}
}}


'''BQN''' is an APL-family language designed primarily by [[Marshall Lochbaum]]. Although it maintains the concept of array-driven computing and much of APL's array functionality, BQN discards all [[backwards compatibility|compatibility]] with other array languages and changes many fundamental concepts. It uses the [[based array model]] with dedicated [[array notation]], distinguishes between data types and expression roles to give the language a [[wikipedia:context-free grammar|context-free grammar]] with [[wikipedia:first-class function|first-class function]]s, and uses a new set of [[glyph]]s with different primitive pairings. The language uses the [[leading axis model]] and [[tacit programming]] as core paradigms. Its implementation is largely self-hosted, with an array-based compiler like [[Co-dfns]].
'''BQN''' is an APL-family language designed primarily by [[Marshall Lochbaum]]. Although it maintains the concept of array-driven computing and much of APL's array functionality, BQN discards all [[backwards compatibility|compatibility]] with other array languages and changes many fundamental concepts. It uses the [[based array model]] with dedicated [[array notation]], distinguishes between data types and expression roles to give the language a [[wikipedia:context-free grammar|context-free grammar]] with [[first-class function]]s, uses a new set of [[glyph]]s with different primitive pairings, and implements [[character arithmetic]]. The language uses the [[leading axis model]] and [[tacit programming]] as core paradigms. Its implementation is largely self-hosted, with an array-based compiler like [[Co-dfns]].
 
== Implementations ==
 
BQN has several implementations,<ref name="running"/> with all complete ones based on self-hosted sources, which are compiled to bytecode and included as literal arrays or similar in the implementation's source. [https://github.com/dzaima/CBQN CBQN], developed by [[dzaima]] in [[wikipedia:C (programming language)|C]], is the primary implementation with the best performance. A [[wikipedia:JavaScript|JavaScript]] version can be run online. It's slower than CBQN compiled to [[wikipedia:WebAssembly|Wasm]], but easier to connect with browser functionality.
 
The [https://github.com/mlochbaum/Singeli Singeli] language was developed in order to implement BQN more effectively. CBQN uses Singeli for primitive code that uses [[vector instruction]]s, and can be built with or without these optimized implementations. The Singeli implementation is written in BQN and currently targets C.
 
=== dzaima/BQN ===
 
Now largely replaced by CBQN, dzaima/BQN is [[dzaima]]'s independent implementation in Java, based on [[dzaima/APL]]. While dzaima/APL adds significant new functionality and is different from any other APL, dzaima/BQN follows the BQN specification closely and sometimes extends it with [[system function]]s. It has often been the first implementation to support new functionality, particularly syntax such as block headers, and was the fastest implementation before CBQN was created. It introduced the [[wikipedia:bytecode|bytecode]] format now shared with self-hosted BQN, and was used for development and bootstrapping.


== Primitives ==
== Primitives ==
Line 29: Line 41:
! Glyph                    !! Monadic                  !! Dyadic
! Glyph                    !! Monadic                  !! Dyadic
|-
|-
| <source inline>+</source> || [[Conjugate]]            || [[Add]]
| <code>+</code> || [[Conjugate]]            || [[Add]]
|-
| <code>-</code> || [[Negate]]                || [[Subtract]]
|-
| <code>×</code> || [[Sign]]                  || [[Multiply]]
|-
|-
| <source inline>-</source> || [[Negate]]               || [[Subtract]]
| <code>÷</code> || [[Reciprocal]]           || [[Divide]]
|-
|-
| <source inline>×</source> || [[Sign]]                 || [[Multiply]]
| <code></code> || [[Exponential]]           || [[Power (function)|Power]]
|-
|-
| <source inline>÷</source> || [[Reciprocal]]           || [[Divide]]
| <code></code> || [[Square Root]]           || [[Root]]
|-
|-
| <source inline></source> || [[Exponential]]           || [[Power (function)|Power]]
| <code></code> || [[Floor]]                 || [[Minimum]]
|-
|-
| <source inline></source> || [[Square Root]]           || [[Root]]
| <code></code> || [[Ceiling]]               || [[Maximum]]
|-
|-
| <source inline></source> || [[Floor]]                 || [[Minimum]]
| <code></code> || [[Sort Up]]               || [[And]]
|-
|-
| <source inline></source> || [[Ceiling]]               || [[Maximum]]
| <code></code> || [[Sort Down]]             || [[Or]]
|-
|-
| <source inline></source> || Sort Up                  || [[And]]
| <code>¬</code> || [[Not]]                   || Span
|-
|-
| <source inline></source> || Sort Down                || [[Or]]
| <code><nowiki>|</nowiki></code> || [[Absolute Value]]        || [[Residue|Modulus]]
|-
|-
| <source inline>¬</source> || [[Not]]                   || Span
| <code></code> ||                          || [[Less Than or Equal to]]
|-
|-
| <source inline>|</source> || [[Absolute Value]]       || [[Residue|Modulus]]
| <code><</code> || [[Enclose]]               || [[Less Than]]
|-
|-
| <source inline></source> ||                           || [[Less Than or Equal to]]
| <code>></code> || [[Mix|Merge]]            || [[Greater Than]]
|-
|-
| <source inline><</source> || [[Enclose]]              || [[Less Than]]
| <code></code> ||                           || [[Greater Than or Equal to]]
|-
|-
| <source inline>></source> || [[Mix|Merge]]             || [[Greater Than]]
| <code>=</code> || [[Rank]]                 || [[Equals]]
|-
|-
| <source inline></source> ||                           || [[Greater Than or Equal to]]
| <code></code> || [[Tally|Length]]          || [[Not Equals]]
|-
|-
| <source inline>=</source> || [[Rank]]                 || [[Equals]]
| <code></code> || [[Depth]]                 || [[Match]]
|-
|-
| <source inline></source> || [[Tally|Length]]         || [[Not Equals]]
| <code></code> || [[Shape]]                 || [[Not Match]]
|-
|-
| <source inline></source> || [[Depth]]                 || [[Match]]
| <code></code> || [[Identity]]             || [[Left]]
|-
|-
| <source inline></source> || [[Shape]]                 || [[Not Match]]
| <code></code> || [[Identity]]             || [[Right]]
|-
|-
| <source inline></source> || [[Identity]]             || [[Left]]
| <code></code> || [[Ravel|Deshape]]         || [[Reshape]]
|-
|-
| <source inline></source> || [[Identity]]             || [[Right]]
| <code></code> || [[Raze|Join]]             || [[Catenate|Join to]]
|-
|-
| <source inline></source> || [[Ravel|Deshape]]         || [[Reshape]]
| <code></code> || [[Solo]]                 || [[Couple]]
|-
|-
| <source inline></source> || [[Raze|Join]]             || [[Catenate|Join to]]
| <code></code> || [[Pair|Enlist]]           || [[Pair]]
|-
|-
| <source inline></source> || Solo                      || Couple
| <code></code> || Prefixes                  || [[Take]]
|-
|-
| <source inline></source> || Prefixes                 || [[Take]]
| <code></code> || Suffixes                 || [[Drop]]
|-
|-
| <source inline></source> || Suffixes                  || [[Drop]]
| <code></code> || [[Index Generator|Range]] || Windows
|-
|-
| <source inline></source> || [[Index Generator|Range]] || Windows
| <code>»</code> || Nudge                    || Shift Before
|-
|-
| <source inline>»</source> || Nudge                     || Shift Before
| <code>«</code> || Nudge Back                || Shift After
|-
|-
| <source inline>«</source> || Nudge Back                || Shift After
| <code></code> || [[Reverse]]              || [[Rotate]]
|-
|-
| <source inline></source> || [[Reverse]]               || [[Rotate]]
| <code></code> || [[Transpose]]             || [[Transpose|Reorder axes]]
|-
|-
| <source inline></source> || [[Transpose]]             || [[Transpose|Reorder axes]]
| <code>/</code> || [[Indices]]               || [[Replicate]]
|-
|-
| <source inline>/</source> || [[Indices]]               || [[Replicate]]
| <code></code> || [[Grade|Grade Up]]       || [[Interval_Index|Bins Up]]
|-
|-
| <source inline></source> || [[Grade|Grade Up]]       || [[Interval_Index|Bins Up]]
| <code></code> || [[Grade|Grade Down]]     || [[Interval_Index|Bins Down]]
|-
|-
| <source inline></source> || [[Grade|Grade Down]]      || [[Interval_Index|Bins Down]]
| <code></code> || First Cell                || [[Select]]
|-
|-
| <source inline></source> || First Cell                || Select
| <code></code> || [[First]]                || Pick
|-
|-
| <source inline></source> || [[First]]                 || Pick
| <code></code> || [[Classify]]             || [[Index of]]
|-
|-
| <source inline></source> || Classify                  || [[Index of]]
| <code></code> || [[Occurrence Count]]      || [[Progressive Index of]]
|-
|-
| <source inline></source> || [[Occurrence Count]]     || [[Progressive Index of]]
| <code></code> || [[Nub Sieve|Mark Firsts]] || [[Member of]]
|-
|-
| <source inline></source> || [[Unique Mask]]           || [[Member of]]
| <code></code> || [[Unique|Deduplicate]]   || [[Find]]
|-
|-
| <source inline></source> || [[Unique|Deduplicate]]   || [[Find]]
| <code></code> || [[Group Indices]]         || [[Group (BQN)|Group]]
|-
|-
| <source inline></source> || Group Indices            || Group
| <code>!</code> || Assert                    || Assert with Message
|}
|}


=== Modifiers ===
=== Modifiers ===


[[Monadic operator|1-modifiers]] in BQN use superscript symbols, while [[Dyadic operator|2-modifiers]] use symbols with a circle, but not one with a line through it like <source inline>⌽</source> and <source inline>⍉</source>.
[[Monadic operator|1-modifiers]] in BQN use superscript symbols, while [[Dyadic operator|2-modifiers]] use symbols with a circle, but not one with a line through it like <code>⌽</code> and <code>⍉</code>.


{|
{|
Line 123: Line 139:
! Glyph                    !! Name(s)
! Glyph                    !! Name(s)
|-
|-
| <source inline>˙</source> || [[Constant]]
| <code>˙</code> || [[Constant]]
|-
|-
| <source inline>˜</source> || [[Commute|Self/Swap]]
| <code>˜</code> || [[Commute|Self/Swap]]
|-
|-
| <source inline>˘</source> || Cells
| <code>˘</code> || Cells
|-
|-
| <source inline>¨</source> || [[Each]]
| <code>¨</code> || [[Each]]
|-
|-
| <source inline>⌜</source> || [[Outer Product|Table]]
| <code>⌜</code> || [[Outer Product|Table]]
|-
|-
| <source inline>⁼</source> || Undo
| <code>⁼</code> || [[Undo]]
|-
|-
| <source inline>´</source> || [[Reduce|Fold]]
| <code>´</code> || [[Reduce|Fold]]
|-
|-
| <source inline>˝</source> || [[Reduce|Insert]]
| <code>˝</code> || [[Reduce|Insert]]
|-
|-
| <source inline>`</source> || [[Scan]]
| <code>`</code> || [[Scan]]
|}
|}
|style="vertical-align:top"|
|style="vertical-align:top"|
Line 145: Line 161:
! Glyph                    !! Name(s)
! Glyph                    !! Name(s)
|-
|-
| <source inline>∘</source> || [[Atop]]
| <code>∘</code> || [[Atop (operator)|Atop]]
|-
| <code>○</code> || [[Over]]
|-
|-
| <source inline></source> || [[Over]]
| <code></code> || [[Hook|Before]]/[[Bind]]
|-
|-
| <source inline></source> || [[Before]]/[[Bind]]
| <code></code> || [[Hook|After]]/[[Bind]]
|-
|-
| <source inline></source> || [[After]]/[[Bind]]
| <code></code> || [[Under]]
|-
|-
| <source inline></source> || [[Under]]
| <code></code> || Valences
|-
|-
| <source inline></source> || Valences
| <code></code> || Choose
|-
|-
| <source inline></source> || Choose
| <code></code> || [[Rank (operator)|Rank]]
|-
|-
| <source inline></source> || [[Rank (operator)|Rank]]
| <code></code> || [[Depth (operator)|Depth]]
|-
|-
| <source inline></source> || [[Depth (operator)|Depth]]
| <code></code> || [[Power (operator)|Repeat]]
|-
|-
| <source inline></source> || [[Power (operator)|Repeat]]
| <code></code> || Catch
|}
|}
|}
|}
Some modifiers are closely related, and some of their glyphs are intended to allude to this:
* The three 1-modifers Cells (<code>𝔽˘</code>), Each (<code>𝔽¨</code>), and Undo (<code>𝔽⁼</code>) are equivalent to using a right-[[operand]] of <code>¯1</code> with the 2-modifiers Rank (<code>𝔽⎉¯1</code>), Depth (<code>𝔽⚇¯1</code>), and Repeat (<code>𝔽⍟¯1</code>). Therefore the 2-modifiers are circled versions of the 1-modifiers (except in the case of Undo/Repeat).
* Under (<code>𝔽⌾𝔾</code>) is in principle equivalent to <code>𝔾⁼∘𝔽○𝔾</code>. Therefore, <code>⌾</code> is a combination of the glyphs <code>∘</code> and <code>○</code>.
== The Name BQN ==
The name "BQN" was originated as a forward iteration of the letters of APL, and "happens to match the capitals in 'Big Questions Notation'"<ref>[[Marshall Lochbaum]]. [https://mlochbaum.github.io/BQN/#what-kind-of-name-is-bqn "What Kind of a Name is BQN?"]</ref>.
Lochbaum recounts, "I obtained 'BQN' by moving each letter in 'APL' forward by one in the alphabet. I'd come up with the backronym 'Big Questions Notation' by the time I realized N doesn't come after L."<ref>[[Marshall Lochbaum]]. [https://chat.stackexchange.com/transcript/message/54753804#54753804 Stack Exchange Transcript]</ref>
Lochbaum commented further on this, saying:
<blockquote>
...the way I came up with the name BQN was I thought, ... alright, I'm working on this next APL. What do I call [it?] ... I took took APL and I moved it forward and I got BQN. And I said, well, BQN, that sounds pretty good... [B]ig Questions Notation is what I ended up with. I like it 'cause it suggests that not only you're solving big questions, but you have big questions about the notation, so it's a little tongue in cheek. And I said also, you can pronounce it like bacon, so there's even a food pun like Apple. And after some half hour or an hour of thinking about this, I realized that the letter that comes after L is M, not N. I think it would be much more logical for N to come first, because it's the letter with two humps. BQM is a horrible, horrible name, and so I stuck with BQN.
<ref>[[Array Cast#bqn|Marshall Lochbaum and the BQN array language]]. [[Array Cast]]. Aug 7, 2021. (In response to a question starting at the 11:29 mark.)</ref>
</blockquote>
== References ==
<references />


{{APL dialects}}[[Category:BQN| ]][[Category:Array languages]][[Category:Based array languages]][[Category:Compilers]][[Category:Leading axis languages]][[Category:Languages with tacit programming]]
{{APL dialects}}[[Category:Based array languages]][[Category:Languages with first-class functions]][[Category:IR compilers]][[Category:Leading axis languages]][[Category:Languages with tacit programming]]

Latest revision as of 02:01, 6 September 2024


BQN is an APL-family language designed primarily by Marshall Lochbaum. Although it maintains the concept of array-driven computing and much of APL's array functionality, BQN discards all compatibility with other array languages and changes many fundamental concepts. It uses the based array model with dedicated array notation, distinguishes between data types and expression roles to give the language a context-free grammar with first-class functions, uses a new set of glyphs with different primitive pairings, and implements character arithmetic. The language uses the leading axis model and tacit programming as core paradigms. Its implementation is largely self-hosted, with an array-based compiler like Co-dfns.

Implementations

BQN has several implementations,[1] with all complete ones based on self-hosted sources, which are compiled to bytecode and included as literal arrays or similar in the implementation's source. CBQN, developed by dzaima in C, is the primary implementation with the best performance. A JavaScript version can be run online. It's slower than CBQN compiled to Wasm, but easier to connect with browser functionality.

The Singeli language was developed in order to implement BQN more effectively. CBQN uses Singeli for primitive code that uses vector instructions, and can be built with or without these optimized implementations. The Singeli implementation is written in BQN and currently targets C.

dzaima/BQN

Now largely replaced by CBQN, dzaima/BQN is dzaima's independent implementation in Java, based on dzaima/APL. While dzaima/APL adds significant new functionality and is different from any other APL, dzaima/BQN follows the BQN specification closely and sometimes extends it with system functions. It has often been the first implementation to support new functionality, particularly syntax such as block headers, and was the fastest implementation before CBQN was created. It introduced the bytecode format now shared with self-hosted BQN, and was used for development and bootstrapping.

Primitives

Functions

Glyph Monadic Dyadic
+ Conjugate Add
- Negate Subtract
× Sign Multiply
÷ Reciprocal Divide
Exponential Power
Square Root Root
Floor Minimum
Ceiling Maximum
Sort Up And
Sort Down Or
¬ Not Span
| Absolute Value Modulus
Less Than or Equal to
< Enclose Less Than
> Merge Greater Than
Greater Than or Equal to
= Rank Equals
Length Not Equals
Depth Match
Shape Not Match
Identity Left
Identity Right
Deshape Reshape
Join Join to
Solo Couple
Enlist Pair
Prefixes Take
Suffixes Drop
Range Windows
» Nudge Shift Before
« Nudge Back Shift After
Reverse Rotate
Transpose Reorder axes
/ Indices Replicate
Grade Up Bins Up
Grade Down Bins Down
First Cell Select
First Pick
Classify Index of
Occurrence Count Progressive Index of
Mark Firsts Member of
Deduplicate Find
Group Indices Group
! Assert Assert with Message

Modifiers

1-modifiers in BQN use superscript symbols, while 2-modifiers use symbols with a circle, but not one with a line through it like and .

Glyph Name(s)
˙ Constant
˜ Self/Swap
˘ Cells
¨ Each
Table
Undo
´ Fold
˝ Insert
` Scan
Glyph Name(s)
Atop
Over
Before/Bind
After/Bind
Under
Valences
Choose
Rank
Depth
Repeat
Catch

Some modifiers are closely related, and some of their glyphs are intended to allude to this:

  • The three 1-modifers Cells (𝔽˘), Each (𝔽¨), and Undo (𝔽⁼) are equivalent to using a right-operand of ¯1 with the 2-modifiers Rank (𝔽⎉¯1), Depth (𝔽⚇¯1), and Repeat (𝔽⍟¯1). Therefore the 2-modifiers are circled versions of the 1-modifiers (except in the case of Undo/Repeat).
  • Under (𝔽⌾𝔾) is in principle equivalent to 𝔾⁼∘𝔽○𝔾. Therefore, is a combination of the glyphs and .

The Name BQN

The name "BQN" was originated as a forward iteration of the letters of APL, and "happens to match the capitals in 'Big Questions Notation'"[3].

Lochbaum recounts, "I obtained 'BQN' by moving each letter in 'APL' forward by one in the alphabet. I'd come up with the backronym 'Big Questions Notation' by the time I realized N doesn't come after L."[4]

Lochbaum commented further on this, saying:

...the way I came up with the name BQN was I thought, ... alright, I'm working on this next APL. What do I call [it?] ... I took took APL and I moved it forward and I got BQN. And I said, well, BQN, that sounds pretty good... [B]ig Questions Notation is what I ended up with. I like it 'cause it suggests that not only you're solving big questions, but you have big questions about the notation, so it's a little tongue in cheek. And I said also, you can pronounce it like bacon, so there's even a food pun like Apple. And after some half hour or an hour of thinking about this, I realized that the letter that comes after L is M, not N. I think it would be much more logical for N to come first, because it's the letter with two humps. BQM is a horrible, horrible name, and so I stuck with BQN. [5]

References


APL dialects [edit]
Maintained APL+WinAPL2APL64APL\ivApletteAprilCo-dfnsDyalog APLDyalog APL Visiondzaima/APLGNU APLKapNARS2000PometoTinyAPL
Historical A Programming LanguageA+ (A) ∙ APL#APL2CAPL\360APL/700APL\1130APL\3000APL.68000APL*PLUSAPL.jlAPL.SVAPLXExtended Dyalog APLIverson notationIVSYS/7090NARSngn/aplopenAPLOperators and FunctionsPATRowanSAXSHARP APLRationalized APLVisualAPL (APLNext) ∙ VS APLYork APL
Derivatives AHPLBQNCoSyELIGleeIIvyJJellyK (Goal, Klong, Q) ∙ KamilaLispLang5LilNialRADUiua
Overviews Comparison of APL dialectsTimeline of array languagesTimeline of influential array languagesFamily tree of array languages