aboutsummaryrefslogtreecommitdiff
path: root/doc/fromJ.md
blob: b2884c1eddcddfad4f4e8d79a0269ee19ab84f66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/fromJ.html).*

# BQN–J dictionary

<!--GEN
"style" Enc ".Comment { color: inherit; }"
-->

A guide to help users of J get up to speed with BQN quickly. For a higher-level comparison, check [Why BQN?](../commentary/why.md#versus-apl-and-j).

## Terminology

### Array model

BQN uses the [based array model](based.md), which is fundamentally different from J's flat array model. BQN uses non-array values such as characters and numbers, called "atoms", while in J every noun is an array. A BQN array can contain any values in any mixture, while a J array must be uniformly numbers, characters, or boxes (BQN doesn't use boxes).

The J terms "atom" and "element" are used to mean different things by different authors. In BQN, a rank-0 array or atom is called a "unit", and the values contained in an array—which may or may not be arrays—are called "elements". Each element is contained in a 0-cell, or rank-0 subarray. BQN uses the term "major cell" for what J calls an "item" of an array: a cell with rank one less than that array. BQN shares the terms "list" and "table" for rank-1 and rank-2 arrays with J.

BQN uses "[depth](depth.md)" rather than "boxing level". BQN gives atoms depth 0, so that the depth of a BQN array is one higher than the boxing level of the corresponding J array.

### Roles

In J, the part of speech is an inherent property of a value, while in BQN it's determined by how the value is used in a particular expression, and can be different from the value's type. See [context-free grammar](context.md).

| J part of speech    | BQN role   | Spelling    |
|---------------------|------------|-------------|
| Noun                | Subject    | `lowerCase` |
| Verb                | Function   | `UpperCase` |
| Adverb              | 1-modifier | `_leading`  |
| Conjunction         | 2-modifier | `_both_`    |

## Syntax

| J                 | BQN         | Remarks
|-------------------|-------------|---------
| `NB.`             | `#`         |
| `'`               | `"`         | `'` for character atoms
| `=.` and `=:`     | `←` and `↩` | `←` to define; `↩` to modify
| `3 :…` or `{{…}}` | `{…}`       |
| `:`               | `;`         | To separate function cases
| `x` `y`           | `𝕨` `𝕩`     | `𝕊` for block function self-reference
| `u` `v`           | `𝔽` `𝔾`     | `𝕣` for block modifier self-reference
| `_`               | `¯` or `∞`  |
| `2 3 4`           | `2‿3‿4`     |
| `[:`              | `·`         | Cap
| `assert.`         | `!`         |

BQN's explicit functions and modifiers are called [blocks](block.md), and have a more sophisticated syntax than J. BQN uses [lexical scope](lexical.md), and has no global variables. BQN also has a [list notation](arrayrepr.md#brackets) using `⟨⟩`, and `[]` for higher-rank arrays.

## For reading

J analogues of BQN primitive functions are given below. They are not always the same; usually this is because BQN has extra functionality relative to J, although in some cases it has less or different functionality.

Functions `+` `-` `|` `<` `>` are the same in both languages.

| BQN | `×` | `÷` | `⋆` | `√`  | `⌊`  | `⌈`  | `≤`  | `≥`  | `⊣` | `⊢` |
|:---:|:---:|:---:|:---:|:----:|:----:|:----:|:----:|:----:|:---:|:---:|
| J   | `*` | `%` | `^` | `%:` | `<.` | `>.` | `<:` | `>:` | `[` | `]` |

| BQN | `≍`  | `⋈`    | `⌽`   | `⍉`   |
|:---:|:----:|:------:|:-----:|:-----:|
| J   | `,:` | `,&:<` | `\|.` | `\|:` |

| BQN   | `∧`   | `∨`   | `¬`   | `=`   | `≠`  | `≡`  | `≢`     | `⥊` | `∾` |
|:-----:|:-----:|:-----:|:-----:|:-----:|:----:|:----:|:-------:|:---:|:---:|
| Monad | `/:~` | `\:~` | `-.`  | `#@$` | `#`  | `L.` | `$`     | `,` | `;` |
| Dyad  | `*.`  | `+.`  | `+-.` | `=`   | `~:` | `-:` | `-.@-:` | `$` | `,` |

| BQN   | `↑`  | `↓`   | `↕`  | `»`            | `«`             | `/`  |
|:-----:|:----:|:-----:|:----:|:--------------:|:---------------:|:----:|
| Monad | `<\` | `<\.` | `i.` | `#{.(_1-#){.]` | `-@#{.(1+#){.]` | `I.` |
| Dyad  | `{.` | `}.`  | `]\` | `#@]{.,`       | `-@#@]{.,~`     | `#`  |

| BQN   | `⍋`  | `⍒`     | `⊏`  | `⊑`     | `⊐`     | `⊒` | `∊`  | `⍷`  | `⊔`       |
|:-----:|:----:|:-------:|:----:|:-------:|:-------:|:---:|:----:|:----:|:---------:|
| Monad | `/:` | `\:`    | `{.` | `0{::,` | `i.~~.` | `…` | `~:` | `~.` | `</.i.@#` |
| Dyad  | `I.` | `I.&:-` | `{`  | `{::`   | `i.`    | `…` | `e.` | `E.` | `</.`     |

Most of BQN's combinators have J equivalents. The J equivalent `"_` for `˙` assumes a noun operand, but `˙` makes a constant function for any operand. `◶` has arguments reversed relative to `@.`, and uses an actual array of functions rather than gerunds. Besides these, BQN's `⟜` is like a J hook, that is, `F⟜G` is `(F G)`, and `⊸` applies in the opposite direction.

| BQN | `˙`  | `˜` | `∘`  | `○`  | `⌾`   | `⊘` | `◶`  | `⎊`  |
|:---:|:----:|:---:|:----:|:----:|:-----:|:---:|:----:|:----:|
| J   | `"_` | `~` | `@:` | `&:` | `&.:` | `:` | `@.` | `::` |

For other modifiers the correspondence is looser. Here `⌜` shows the dyadic case and `´` `˝` the monadic case only.

| BQN | `¨`   | `⌜`    | `´`    | `˝` | `` ` `` | `˘`   | `` | ``  | ``  | `⁼`    |
|:---:|:-----:|:------:|:------:|:---:|:-------:|:-----:|:---:|:----:|:----:|:------:|
| J   | `&.>` | `&.>/` | `&.>/` | `/` | `/\`    | `"_1` | `"` | `L:` | `^:` | `^:_1` |

## For writing

J's primitive nouns are easily defined in BQN.

| J    | BQN      |
|------|----------|
| `a.` | `@+↕256` |
| `a:` | `<↕0`    |

Functions `+` `-` `|` `<` `>` are the same in both languages.

Some other primitives are essentially the same in J and BQN, but with different spellings (but [transpose](transpose.md) behaves differently; J's dyadic `|:` is more like `⍉⁼`):

| J   | `*` | `%` | `^` | `^.` | `%:` | `<.` | `>.` | `[` | `]` | `\|.` | `\|:` |
|:---:|:---:|:---:|:---:|:----:|:----:|:----:|:----:|:---:|:---:|:-----:|:-----:|
| BQN | `×` | `÷` | `⋆` | `⋆⁼` | `√`  | `⌊`  | `⌈`  | `⊣` | `⊢` | `⌽`   | `⍉`   |

| J   | `~` | `@:` | `&:` | `&.:` | `:` | `"` | `L:` | `^:` | `::` |
|:---:|:---:|:----:|:----:|:-----:|:---:|:---:|:----:|:----:|:----:|
| BQN | `˜` | `∘`  | `○`  | `⌾`   | `⊘` | `⎉` | `⚇`  | `⍟`  | `⎊`  |

The tables below give approximate implementations of J primitives. J has a whole lot of complicated primitives that no one uses (some of which are officially deprecated), so not everything is translated here. Operations that only apply to complex numbers are omitted because no BQN implementation currently supports them.

| J    | Monad                   | Dyad
|------|-------------------------|-----
| `=`  | `⍷⊸(≡⌜)`                | `=`
| `<:` | `-⟜1`                   | `≤`
| `>:` | `1⊸+`                   | `≥`
| `+.` |                         | `∨`
| `+:` | `2⊸×`                   | `¬∨`
| `*.` |                         | `∧`
| `*:` | `ט`                    | `¬∧`
| `-.` | `¬`                     | `¬∘∊/⊣`
| `-:` | `÷⟜2`                   | `≡`
| `%.` | `Inverse`,              | `Solve` from [here](https://github.com/mlochbaum/bqn-libs/blob/master/matrix.bqn)
| `$`  | `≢`                     | `⥊`
| `~.` | `⍷`                     |
| `~:` | `∊`                     | `≠`
| `,`  | `⥊`                     | `∾`
| `,.` | `⥊˘`                    | `∾˘`
| `,:` | `≍`                     | `≍`
| `;`  | `∾`                     | `∾⟜(<⍟(1≥≡))`
| `#`  | `≠`                     | `/`
| `#.` | `+˜⊸+˜´∘⌽`              |
| `#:` | `⌽2\|⌊∘÷⟜2⍟(↕1+·⌊2⋆⁼⊢)` | ``{𝕨\|1↓⌊∘÷`⌾⌽𝕨∾<𝕩}``
| `!`  | `×´1+↕`                 | `(-÷○(×´)1⊸+)⟜↕˜`
| `/:` | `⍋`                     | `⍋⊸⊏`
| `\:` | `⍒`                     | `⍒⊸⊏`
| `{`  | `(<⟨⟩)<⊸∾⌜´⊢`           | `⊏`
| `{.` | `⊏`                     | `↑`
| `{:` | `⊢˝`                    |
| `{::`|                         | `⊑`
| `}.` | `1⊸↓`                   | `↓`
| `}:` | `¯1⊸↓`                  |
| `".` | `•BQN`                  |
| `":` | `•Fmt`                  |
| `?`  | `•rand.Range⚇0`         | `•rand.Deal`
| `e.` | `><∘∾∊¨⊢`               | `∊`
| `E.` |                         | `⍷`
| `i.` | `↕` (`⥊⟜(↕×´)` for lists) | `⊐`
| `i:` | `{𝕩-˜↕1+2×𝕩}`           | `≠∘⊣-1+⌽⊸⊐`
| `I.` | `/`                     | `⍋`
| `L.` | `≡`                     |
| `o.` | `π⊸×`                   | `•math`

Some J modifier expressions are translated below. BQN doesn't keep track of the rank of functions, so the "close" compositions `@` `&` `&.` have no BQN equivalents: instead, specify a rank after composing.

| J              | BQN
|----------------|-----
| `&.>`          | `¨`
| `F/ y`         | `F˝ y`
| `x F&.>/ y`    | `x F⌜ y`
| `x F/ y`       | `x F⎉r‿∞ y` where `r` is `F`'s left rank
| ``F`G`H@.C``   | `C◶⟨F,G,H⟩`
| `x y} z`       | `x⌾(y⊸⊏) z` (`x¨` if `x` is an atom)
| `x F/ . G y`   | `x F˝∘G⎉1‿∞ y`
| `F :. G`       | `{𝕊: 𝕨F𝕩; 𝕊⁼: 𝕨G𝕩}`
| `<;._1`        | ``((1-˜¬×+`)=⟜⊏⊘⊣)⊔⊢``
| `x {.!.f y`    | `y » x⥊f`
| `x \|.!.f y`   | `x ⥊⟜f⊸« y`, or `(-x) ⥊⟜f⊸» y` if `𝕩<0`

BQN uses functions, not modifiers, for structural manipulation. The following table gives BQN functions corresponding to J's structural modifiers. The result is an array of arrays; use `F¨` to apply a function to each of these, and `>F¨` to apply a function and merge the results into a single array.

| J    | Monad         | Dyad
|------|---------------|------
| `/.` | `(+⌜´↕¨∘≢)⊸⊔` | `⊐⊸⊔`
| `\`  | `1↓↑`         | `<˘↕`
| `\.` | `¯1↓↓`        |