Skip to content

Instantly share code, notes, and snippets.

@oseau
Forked from abo-abo/j.org
Last active August 29, 2015 14:28
Show Gist options
  • Save oseau/82b6cfa9bb6e7b4c21bd to your computer and use it in GitHub Desktop.
Save oseau/82b6cfa9bb6e7b4c21bd to your computer and use it in GitHub Desktop.
My J notes in org-mode

Basics

Precedence

There’s none: only evaluation from right to left. Although adverbs and conjunctions are applied first.

Global Variables

=: is like `setq’

gvar =. 23
fun1 =: 3 : 0
gvar + y
)
fun2 =: 3 : 0
gvar =: 7
gvar + y
)
fun1 3
fun2 3
fun1 3

=. is like `let’

gvar =. 23
fun1 =: 3 : 0
gvar + y
)
fun2 =: 3 : 0
gvar =. 7
gvar + y
)
fun1 3
fun2 3
fun1 3

Comparisons

= dyad

23 = 34
23 = 23

Result is just a number:

10 + 3 = 3

< <: > >:

Control Structure

There are 9 control structure patterns:

if. T do. B end.

convert =: dyad : 0
if. x = 'c'
 do. *: y
 else. %: y
end.
)
'c' convert 4
'f' convert 4

if. T do. B else. B1 end.

x =: 3 : 0
if. y do. 2 else. 3 end.
)
x 0

if. T do. B elseif. T1 do. B1 elseif. T2 do. B2 end.

x =: 3 : 0
if. y = 1 do. 2 elseif. y = 2 do. 3 elseif. 1 do. y end.
)
x 1
x 2
x _10

try. B catch. B1 end.

x =: 3 : 0
try. 1 catch. 2 end.
)
x 1

while. T do. B end.

whilst. T do. B end.

for. T do. B end.

for_i. T do. B end.

select. T case. T0 do. B0 case. T1 do. B1 end.

Environment

Locale

Locale is equivalent to a namespace:

abc_def_ =: 2

is like def::abc = 2; in C++.

Locale defaults to base if elided:

abc_base_ =: 4
abc__

Names

depending on argument

0

list nouns

a =. 23
b =.  24
a_q_ =. 25
w_q_ =. 26
names 0
names_q_ 0

3

list verbs

foo =: 3 : 0
y * y
)
foo 5
names 3

6

list locale names

names 6

dyad

'n' names_z_ 3

Define a verb in a locale

NB. defines arg y as "a" in global locale
f_q_ =. 3 : 'a =: y'
a =. 23                         NB. define a in the base locale
a_q_ =. 24                      NB. define a in locale q
f_q_ 100
a
a_q_

z locale

names_z_ 0
names_z_ 3

scripts verb

scripts ''

‘v’

scripts 'v'

load verb

load 'convert'
toupper 'testing 1 2 3'

Debugging

define a function to debug

centigrade =. 3 : 0
t1 =. y - 32
t2 =. t1 * 5
t3 =. t2 % 9
)

load lib

load 'debug'

set breakpoint on all lines

dbss 'centigrade  *:*'

enable debugger

dbr 1

continue

dbrun ''

lists

assignment

a =. 12 24 47
b =. 12 34 45
a
b

index

a =. 12 24 47
0 { a
2 { a

append

a =. 1 2
b =. a , 3
b , 4

length

a =. 12 24 47
# a

reverse

|. 'abcdefg'
|. i.10

add lists

basic implementation

addlists =: dyad : 0
r =. ''
count =. #x
i =. 0
while. i < count do.
 left =. i { x
 right =. i { y
 sum =. left + right
 r =. r, sum
 i =. i + 1
end.
r
)
2 3 4 addlists 4 5 6

shorter implementation

adda =: dyad : 0
r =. ''
count =. #x
i =. 0
while. i < count do.
 r =. r , (i{x) + (i{y)
 i =. i + 1
end.
r
)
2 3 4 adda 4 5 6

J way

addb =: 4 : 'x + y'
2 3 4 addb 4 5 6

just +

2 3 4 + 4 5 6

+ variations

1 + 2 3 4
2 3 4 + 1

this works for - * % = < <: as well:

2 4 6 * 7 8 9
2 * 2 3 4
2 3 4 * 2
5 6 7 % 2
2 3 4 - 3
2 3 4 = 7 3 8
2 < 0 1 2 3 4 5
2 <: 0 1 2 3 4 5
't' = 'testing'

i. monad (integers)

approx range

i. 6

$ dyad (shape)

5 $ 7

? monad (roll)

Random number from 0 to arg.

? 10
? 10
? 10
? 10
? 0

combine $ ?

5 $ 100
? 5 $ 100                       NB. ? 100 100 100 100

^ dyad (power)

3 ^ 2
2 ^ 3

o. (circle)

with 1 on left gives sin

i.7
1 o. i.7

plot

load 'plot'
plot 5 10 23 45 8
load 'plot'
plot 2 ^ i.5
load 'plot'
plot ? 50 $ 100
load 'plot'
'TITLE myplot;TYPE bar' plot 2 ^ i.5
load 'plot'
plot 1 o. 0.1 * i.200

dimension

atom

23 ‘a’

list

23 24 25 ‘this is a string’

table and $ dyad (shape)

Can’t be written to, only created with $.

2 3 $ 7
2 3 $ i.6
3 4 $ 'abcdefghijklmnopqrstuv'
2 3 $ 7 8

$ monad (shape)

a =. 2 3 $ 7
$ a

i. a b creates table

i.2 3

higher dimension arrays

2 3 4 $ i.24

i. for higher dimension arrays

i. 2 3 4

shape of nouns

a =. 4 2 3 $ 'abcdef'
$ a

rank of arrays is #$

a =. 4 2 3 $ 'abcdef'
#$ a
#$ i. 2 3
#$ i.2
#$ 1
#$ ''

verb arguments

m =. i. 2 2
NB. add 2x2 matrices
m + 2 2 $ 10 11 12 13
NB. add numer to 2x2 matrix
10 + m
NB. add vector to each row
10 20 + m
NB. add vector to each col
10 20 + "1 m

adverbs

/ (insert)

approx reduce. +/ 1 2 3 is equivalent to 1 + 2 + 3.

+/ 1 2 3
a =. i. 3 4
a
+/ a

v/ (table)

addition table

a =. i.5
a +/ a

times table

a =. i.5
a */ a

+ table on booleans

0 1 +/ 0 1

times

0 1 */ 0 1

or

0 1 +./ 0 1

not-or

0 1 +:/ 0 1

and

0 1 *./ 0 1

not-and

0 1 *:/ 0 1

plot1

load 'plot'
plot 1 2 o. / 0.2 * i.60

box: monad <

basic

b =. < 2 3 4
b

append

b =. < 2 3 4
c =. < 4 7 9
d =. b , c
d

link: dyad ;

2 3 4 ; 4 7 9
'abc' ; 4 7 9
(2 3 $ 'abcdef') ; (i. 3 4) ; 23

Boxes the left agument always, but right only if it’s not already boxed:

'abc' ; 'defg' ; 'hijl'
'abc' ; ('defg' ; 'hijl')
'abc' ; < 'defg' ; 'hijl'

open: monad >

basic

Inverse of box. Applied to a noun that’s already open, has no effect.

a =. 1 2 3 ; 5 6 7
a
> a

results for different shape

Each atom is opened and the partial results are extended to fit into the result frame.

a =. 1 ; 2 3 ; 4 5 6
a
> a

results for characters of different shape

Gets extended with spaces

> 'abc' ; 'defg' ; 'hijkl'

results for mixed numbers and characters

> 1 2 3 ; 'asdf'

from: dyad {

basic

a =. 5 7 9 4 8
3 { a
0 { a
2 4 { a
2 0 4 { a

selects rows in tables

m =. i. 3 4
m
0 { m
2 1 { m

selects tables from rank 3 arrays

1 { i. 2 3 4

boxed indexes

If left argument of { is boxed, then it’s opened and each of its items gives the indexes along successive axes of the right argument.

m =. i. 3 4
m
(< 1 2) { m

when fewer indexes than axes

m =. i. 3 4
(<1) { m

rank 3 array example

d =. i.2 3 4
d
(< 1 2 3) { d
(< 1 2) { d

select rows 0 2 and columns 0 2 3 simultaneously

m =. i. 3 4
m
(< 0 2 ; 0 2 3) { m
] d =. i.2 3 4
(< 0 1 ; 0 2 ; 2 3) { d

select all rows and some columns

] m =. i. 3 4
(< 0 1 2 ; 2 3) { m

scattered indexing

When left argument isn’t a box, standard rules apply for { (it has left rank 0):

] m =. i. 3 4
(0 2 ; 2 3) { m
(0 0 ; 1 1 ; 2 2) { m

amend: adverb }

change list in one place

change_index_two =. 2}
15 change_index_two 5 6 7 8
15 (2}) 5 6 7 8

change list at multiple places

23 (1 4}) 7 7 7 7 7
23 24 (1 4}) 7 7 7 7 7
'pd' 1 3} 'ooooo'

more1

m =. i. 3 4
1 { m
23 23 23 23 (1}) m

more2

m =. i. 3 4
(2 4 $ 23 23 23 23 24 24 24 24) (1 2}) m

more3

m =. i. 3 4
12 ((< 1 2 ; 0 3)}) m

more4

m =. i. 3 4
(2 2 $ 23 24 25 26) ((< 1 2 ; 0 3)}) m

selecting without from

head: monad {.

{. 5 6 7

tail: monad {:

{: 5 6 7

behead: monad }.

}. 5 6 7

curtail: monad }:

}: 5 6 7

take: dyad {.

3 {. i.8
2 3 {. i.3 4
2 3 {. i.3 4

use take to extend array

5 {. 5 6 7
4 5 {. i. 2 3

drop: dyad }.

1 }. 2 3 4
1 2 }. i. 3 4

copy: dyad #

3 2 1 2 3 # 'abcde'

It’s equivalent to:

0 0 0 1 1 2 3 3 4 4 4 { 'abcde'

cut: conjunction ;.

2

means to use last element as splitter and include it

< ;. 2 'how now brown cow '
# ;. 2 'how now brown cow '
< ;. 2 (1 2 3 1 4 5 1)
# ;. 2 (1 2 3 1 4 5 1)

_2

means to use last element as splitter and not include it

< ;. _2 'how now brown cow '
# ;. _2 'how now brown cow '
< ;. _2 (1 2 3 1 4 5 1)
# ;. _2 (1 2 3 1 4 5 1)

more operations examples

a =. 2 3 4 _1 5 3 2 _1 23 45 65 132 _1
< ;. _2 a
# ;. _2 a
+/ ;. _2 a

1 or _1

< ;. 1 'madam i''m adam'
< ;. _1 'madam i''m adam'

splitter separately

1 0 0 0 1 0 0 < ;. 1 'abcdefg'
d =. 'the test is the thing'
'the' E. d

each

Apply op to boxed items

monad

a =. 10 12 13 ; 2 3 ; 4 5 6 8 3
a
+/ each a
,,*/ each a
|. each a                       NB. reverse each
>./ each a                      NB. max over each

dyad

a =. 10 12 13 ; 2 3 ; 4 5 6 8 3
23 , each a                     NB. append each
5 < each a                      NB. compare each to 5
1 |. each a

hook

A train is a sequence of two or three words in a row that is given a special meaning. A train of two words is a hook and is evaluated as follows:

(f g) yevaluates asy f g y
x (f g) yevaluates asx f g y

Divide all list elements by its max.

a =. 3 5 8 2 7
>./ a                           NB.max
a % (>./ a)                     NB.divide by max
(% >./)a                        NB.simplify

fork

A train of three verbs is a fork and is evaluated as follows:

(f g h) yevaluates as(f y) g (h y)
x (f g h) yevaluates as(x f y) g (x h y)

Average:

a =. 5 9 12
(+/ a) % (# a)
(+/ % #) a                      NB. same as above
mean =. +/ % #
mean i.999

bond: conjunction &

With a constant left argument returns a derived monad that is the verb on the right with constant left arg

add3 =: 3 & +
add3 i.3

tacit definition

examples

plus =. +
sumover =. +/
maxover =. >./
scale =. % >./
mean =. +/ % #

example convert to tacit

v0

fahrenheit =: 3 : 0
t1 =. y * 9
t2 =. t1 % 5
t3 =. t2 + 32
)
fahrenheit 100
fahrenheit 200

v1

fahrenheit in one line

fa =: 3 : '(y * 9 % 5) + 32'
fa 100
fa 200

v2

rearrange the terms

fa =: 3 : '32 + ((9 % 5) * y)'
fa 100
fa 200

v3

Create auxiliary verbs using bond &:

add32 =: 32 & +
ninefifthtimes =: (9 % 5) & *
add32 ninefifthtimes 100
add32 ninefifthtimes 200

v4

Use atop conjunction @ to compose add32 and ninefifthtimes:

add32 =: 32 & +
ninefifthtimes =: (9 % 5) & *
fc =: add32 @ ninefifthtimes
fc 100
fc 200

use fix to elide defining add32 and ninefifthtimes

add32 =: 32 & +
ninefifthtimes =: (9 % 5) & *
fc =: add32 @ ninefifthtimes
fc
fz =. fc f.
fz

atop: dyad @

(u @ v) y evaluates as u v y

fix: adverb f.

Like all adverbs, takes argument on the left. Takes a tacit definition and replaces names with their definitions.

inverse

fz =: 32&+@(1.8&*)
cz =: fz inverse
fz 100
cz 212
fz 0
cz 32

explicit-to-tacit translator

fx =: 3 : '32 + y * 9 % 5'      NB. 3 explicit
ft =: 13 : '32 + y * 9 % 5'     NB. 13 tacit
ft

files

write

writefile =: 1!:2

fn =. < '/tmp/test.txt'
'testing 1 2 3' writefile fn

read

readfile =: 1!:1
fn =. < '/tmp/test.txt'
data =: readfile fn
data

need to convert to string to write

writefile =: 1!:2
numtab =. i.4 5
cdata =. ": numtab
ddata =. cdata ,"1 LF
ddata
$ ddata
ldata =. , ddata
ldata
$ ldata
ldata writefile < '/tmp/test.txt'

linefeed: LF

'abc' , LF , 'def'

read the data back

rdata =. 1!:1 <'/tmp/test.txt'
dlf =. toJ rdata                NB.convert line breaks
bdata =. cutopen dlf
bdata
ndata =. 0 ". each bdata
ndata
> ndata

convert chars to numbers: dyad “.

0 ". '5 2 7'
1 + 0 ". '5 2 7'

left arg is value to use if conversion fails

0 ". '5 7.5 23.b 8'

wrap up in a function

writetable =: dyad : 0
d =. ": x
d =. d , "1 LF
d =. toHOST , d
d 1!:2 y
)
readtable =: 3 : 0
d =. 1!:1 y
d =. toJ d
d =. cutopen d
d =. 0 ". each d
d =. > d
)

shorter version

writetable =: 4 : '(toHOST,(": x),"1 LF) 1!:2 y'
(i.4 4) writetable < '/tmp/test.txt'

component files

A boxed list stored in a file

basic

load 'jfiles'
f =. '/home/oleh/data.jf'
jcreate f
'first component' jappend f
(1.5 + i.2 3) jappend f
('asdf' ; 23) jappend f
(< 'mum' ; 'dad') jappend f
jsize f
jread f ; 0
jread f ; 1
jread f ; 2
jread f ; 3
jread f ; 4

data processing

create data

load 'files'
fn =. '/tmp/text.txt'
data =. 'abc' , LF , 'bc' , LF , 'b' , LF
data fwrite fn
fread fn

JPhrases

conventions

cconjunction
nnoun
ddyad
vambivalent verb

change display

linear

9!:3 (5)
+/ % #

box, tree, and linear

9!:3 (2 4 5)
+/ % #

example 1

pss =: +/\
x =: }. i.7
x
pss x                           NB. partial sums
sss =: +/ \.
sss |. x
|. sss |. x
sss &. |. x
<\ x                            NB. Box prefix scan
<\. x                           NB. Box suffix scan

example 2

s =: sort =: /:~
numb =: 3 1 4 1 [ char =: 'cage'
poem =: 'i sing' , 'of olaf' ,: 'glad and big'
	(,.s numb) ; (,.s char) ; poem ; (s poem) ; s"1 poem

fixing definitions

n16 =: m =: 3 1 4 , 2 0 5 ,: 1 4 1
d17 =: ip =: +/ . *             NB. inner (matrix) product
m18 =: L =: m & ip
L
L x =: 1 2 5
h =: 'L' f.
h x
ip =: -/ . *
L x
h x

function tables

d0 =: +/                        NB. Addition table
d1 =: */                        NB. Multiplication table
d2 =: >./                       NB. Maximum table
d3 =: [ by ] over +/            NB. Bordered addition table
d4 =: by =: ' ' & ; @ ,. @ [ ,. ] NB. Format function
d5 =: over =: ({. ; }.) @ ": @ ,  NB. Format function
m6 =: +/ ~ @ i.                   NB. Addition table on first y integers
m7 =: bc =: !/~ @ i.              NB. Binomial coefficients of order y
a8 =: ft =: 1 : 'x/~ @ i.'        NB. Function table
a9 =: bft =: 1 : 'i. by i. over x/ ~ @ i.' NB. Bordered function table (explicity definition)
2 3 5 (d0 ; d1 ; d2) 0 1 2 3 4 5

Bond or Curry

m0 =: 1 & +                     NB. increment >:
m1 =: + & 1                     NB. "
m2 =: _1 & +                    NB. decrement <:
m3 =: - & 1                     NB. "
m4 =: 1 & -                     NB. Not -. (logical and probability complement)
m5 =: 1 & ~:                    NB. "
m6 =: 0 & =                     NB. "
m7 =: 0 & -                     NB. Negate - (arithmetic)
m8 =: _1 & *                    NB. "
m9 =: * & _1                    NB. "
m10 =: 2 & *                    NB. Double +:
m11 =: * & 2                    NB. "
m12 =: 3 & *                    NB. Triple
m13 =: * & 3                    NB. "
m14 =: 0j1 & *                  NB. j. (Multiply by sqrt(-1))
m15 =: ^ @ j.                   NB. r. (Complex # on unit circle at y radians)
m16 =: 1p1 & *                  NB. pi times
m17 =: 0.5 & *                  NB. Halve -:
m18 =: * & 0.5                  NB. "
m19 =: % & 2                    NB. "
m20 =: 1 & %                    NB. Reciprocal %
m21 =: ^& _1                    NB. "
m22 =: ^& 2                     NB. Square *:
m23 =: ^& 3                     NB. Cube
m24 =: ^& 0.5                   NB. Square root %:
m25 =: ^& 1r2                   NB. "
m26 =: 2 & %:                   NB. "
m27 =: ^& (% 3)                 NB. Cube root
m28 =: ^& 1r3                   NB. "
m29 =: 3 & %:                   NB. "
m30 =: (^1) & ^                 NB. Exponential ^
m31 =: 1x1 & ^                  NB. "
m32 =: 1x1 & ^.                 NB. Natural log ^.
m33 =: 10 & ^                   NB. power 10
m34 =: 10 & ^.                  NB. Base-10 log
NB. (1+ (floor (log10 (max 1 (ceil x)))))
m35 =: >: @ <. @ (10 & ^.)@(1 & >.) NB. # of digits needed to represent integer y
m36 =: # @ (10 & #. ^: _1)"0    NB. "

Learning J

|

monad: Magnitude

| 6 _6 3j4

dyad: Residue

3 | 0 1 2 3 4 5 6 7

#

monad: Tally

# 3 4 5

dyad: Copy

y =: 6 7 8 9 10
1 1 0 1 0 # y
(y > 7) # y

>.

monad: Ceiling

>. _1.7 1 1.7

dyad: Max

3 >. 1 3 5
>./ 1 6 5

>:

monad: Icrement

>: _2 3 5 6.3

dyad: Larger or Equal

3 >: 1 3 5

i.

monad: Integers

i.5

dyad: Index Of

'abra' i. 'r'

conditional and other forms

halve =: -:
mult =: 1: + (* 3:)
odd =: 2 & |
halve 6
mult 6
odd 6
collatz =: halve ` mult @. odd
collatz 17

bank interest example

  • If the balance is $100 or more, the bank pays interest of 0.5%
  • If the balance is negative, the bank charges interest at 2%.
  • Otherwise the balance is unchanged.
pi =: * & 1.005                 NB. pay interest
ci =: * & 1.02                  NB. charge interest
uc =: * & 1                     NB. unchanged
case =: (>: & 0) + (>: & 100)
case _50 0 1 100 200
PB =: ci ` uc ` pi @. case
PB _50
PB 0
PB 1
PB 100
PB 200
PB _50 0 1 100 200
(PB"0) _50 0 1 100 200

Recursion

define +/ as recursive function

empty =: # = 0:
first =: {.
rest =: }.
Sum =: (first + Sum @ rest) ` 0: @. empty
Sum 1 1 2

Ackermann’s function

Ack =: 4 : 0
if. x = 0     do. y + 1
elseif. y = 0 do. (x - 1) Ack 1
elseif. 1     do. (x - 1) Ack (x Ack y - 1)
end.
)
2 Ack 3
3 Ack 3

tacit Ackermann’s function

ack =: c1 ` c1 ` c2 ` c3 @. (#. @ (,&*))
c1 =: >: @ ]                    NB. 1+y
c2 =: <: @ [ ack 1:             NB. (x-1) ack 1
c3 =: <: @ [ ack [ ack <: @ ]   NB. (x-1) ack x ack y
2 ack 3
3 ack 3

^: Power

Verb applied multiple times over.

(+: ^: 3) 1

With arg _ find the fixed point

p =: 3 : '2.8 * y * (1 - y)'
(p ^: 0 1 2 3 19 20 _) 0.5

(f ^: g) y means f ^: (g y) y

(+: ^: %:) 16

iterating while

halve =: -:
even =: 0: = 2 & |              NB. returns 0 or 1
foo =: halve ^: even            NB. halve 0 or 1 times
(foo"0) i.10
w =: (halve ^: even) ^: _       NB. keep halving while even
w 48

equivalence with while.

The following are equivalent:

f =: -:
g =: 0: = 2 & |
w1 =: f ^: g ^: _
w2 =: 3 : 0
  while. (g y)
  do. y =. f y
  end.
  y
)
w1 48
w2 48

iterating a dyadic verb

x (u ^: w) y means ((x & u) ^: w) y

((3 & +) ^: 2) 0
3 (+ ^: 2) 0

generating tacit verbs from explicit

monad

e =: 3 : '(+/ y) % #y'
t =: 13 : '(+/ y) % #y'
e
t
e 1 2 3
t 1 2 3

dyad

ed =: 4 : 'y % x'
td =: 13 : 'y % x'
ed
td
(2 ed 6),(2 td 6)

“13 : body” evaluates body, but “3 : body” doesn’t

k =: 99
p =: 3 : 'y + k'
q =: 13 : 'y + k'
p
q
(p 6) ; q 6
k =: 0
(p 6) ; q 6

C =: @: 
g =: %: 
foo =: 13 : '(f C f y) , g y'
foo
f =: *:
foo 4

more on tacit

ex1

scale =: * & (5 % 4) 
scale 
scale 8
SCALE =: * & 5 % 4
SCALE

Second one is (* & 5) applied to (% 4). It’s explained by conjunctions having short right scope.

ex2

z =: 3 & + @: *: 
z 2

Adverbs and conjunctions have long left scope. That means that the left argument of @: is the entire 3 & +

names of nouns are evaluated

a =: 5
b =: 4
f =: * & (a % b) 
f

names of verbs are not evaluated

a =: 5
b =: 4
w =: * 
g =: w & (a % b) 
g

unknowns are verbs

When a new name is encountered, it is assumed to be a yet-to-be-defined verb.

h =: ytbd & (5 % 4) 
ytbd =: * 
h 8

A sequence of hitherto-unknown names is assumed to be a train of verbs:

ctof =: shift @ scale
shift =: + & 32
scale =: * & (9 % 5)
ctof
ctof 0 100
scale =: * & 2
ctof 0 100

how to protect agaist dynamic scope

method 1: wrap with explicit definition

CTOF =: 3 : 0
shift =. + & 32
scale =. * & (9 % 5)
shift @ scale y
)
CTOF 100

method 2: fix

ctof =: shift @ scale
shift =: + & 32
scale =: * & (9 % 5)
ctof
ctof f.

parametric functions

y =: lambda * x * (1 - x)
P =: 3 : 'lambda * y * (1 - y)'
x =: 0.6
lambda =: 3.0
P x
lambda =: 3.5
P x
tP =: 13 : 'lambda * y * (1 - y)'
tP
erase <'lambda'
tP =: 13 : 'lambda * y * (1 - y)'
tP
lambda =: 3.5
tP x

fix 1

Compromise “fully tacit”

tP =: (3 : 'lambda') * ] * (1: - ]) 
lambda =: 3.5
tP 0.6

fix 2

Compromise “exact equivalent”

lambda =: 3.5 " 0
tP =: lambda * ] * (1: - ]) 
tP 0.6
lambda =: 3.75 " 0
tP 0.6

Explicit Verbs

General Form

type : body

type

3

monadic or ambivalent verbs

4

strictly dyads

13

with expansion/freeze

type mnemonics

noun0
adverb1
conjunction2
verb3
monad3
dyad4
def:
define: 0

body

0

multiline definition, finish with )

PosDiff =: 4 : 0
larger =. x >. y
smaller =: x <. y
larger - smaller
)
3 PosDiff 4
embed LF
PosDiff =: 4 : ('la =. x >. y' , LF , 'sm =. x <. y' , LF , 'la - sm')
PosDiff
3 PosDiff 4
boxed list of lines
PosDiff =: 4 : ('la =. x >. y' ; 'sm =. x <. y' ; 'la - sm') 
PosDiff
3 PosDiff 4

Ambivalent Verbs

Has both monadic and dyadic case. Monadic case is written first, then a line of a solo colon, then dyadic case.

log =: 3 : 0
^. y
:
x ^. y
)
log 2.71
10 log 100

ex1: positive difference

PosDiff =: 4 : '(x >. y) - (x <. y)'
3 PosDiff 4
4 PosDiff 3

ex2: positive difference with mnemonics

PosDiff =: dyad def '(x >. y) - (x <. y)'
3 PosDiff 4

Destructuring

1

'day mo yr' =: 16 10 95
day , mo , yr

2

('day' ; 'mo' ; 'yr') =: 17 11 96
day , mo , yr 
N =: 'day' ; 'mo' ; 'yr'
(N) =: 18 12 97
day , mo , yr

ex1: roots of quadratic poly

rq =: 3 : 0
'a b c' =. y
((- b) (+ , -) %: (b ^ 2) - 4 * a * c) % (2 * a) 
)
rq 1 1 _6
rq 1 ; 1 ; _6

control structures

ex1

sum =: 3 : 0
if.
  length =. # y                 NB. T block
  length = 0                    NB. T block
do.
  0                             NB. B1 block
else.
  first =. {. y                 NB. B2 block
  rest =. }. y                  NB. B2 block
  first + sum rest              NB. B2 block
end.
)

ex2

ClaTePo =: 3 : 0
if. y > 80 do. 'too hot'
else.
	if. y < 60 do.  'too cold'
        else.           'just right'
	end.
end.
)
ClaTePo 70

select

branched if

class =: 3 : 0
t =. 4 !: 0 < y
if.     t = 0 do. 'noun'
elseif. t = 1 do. 'adverb'
elseif. t = 2 do. 'conjunction'
elseif. t = 3 do. 'verb'
elseif. 1     do. 'bad name'
end.
)
class 'class'
class 'oops'

equivalent select

class =: 3 : 0
select. 4 !: 0 < y
case. 0 do. 'noun'
case. 1 do. 'adverb'
case. 2 do. 'conjunction'
case. 3 do. 'verb'
case.   do. 'bad name'
end.
)
class 'class'
class 'oops'

select allows boxed list in case.

class =: 3 : 0
select. 4 !: 0 < y
case. 0     do. 'noun'
case. 1 ; 2 do. 'operator'
case. 3     do. 'verb'
case.       do. 'bad name'
end.
)
o =: @:
class 'o'
class 'oops'

while.

fact =: 3 : 0
r =. 1
while. y > 1
do. r =. r * y
    y =. y - 1	
end.
r
)
fact 5

whilst.

whilst. T do. B end.

means

B while. T do. B end.

for.

for_a. A do. B end.

means

for each item a in array A, execute block B.

Sum =: 3 : 0
r =. 0
for_term. y do. r =. r + term end.
r
)
Sum 1 2 3

a_index is also available similar to Python’s enumerate

f3 =. 3 : 0
r =. 0 2 $ 0
for_item. y do. r =. r , (item_index ; item) end.
r
)
f3 'ab' ; 'cdef' ; 'gh' 

Explicit Operators

operators generating tacit verbs

ex 1

Suppose we want an adverb A s.t. u A means u ” 0

A =: 1 : 'u"0'
f =: < A
f 1 2

ex 2

W =: 1 : '<"u'
0 W
z =: 'abc' 
0 W z
1 W z

ex 3

y =: 1 0 2 3
1 0 1 1 # y                     NB. dyad Copy
> & 0 y                         NB. select items greater than 0
(> & 0 y) # y
f =: > & 0 # ]                  NB. fork to select items >0
f y
B =: 1 : 'u # ]' 
g =: >&0 B
g 1 0 _2 3

ex 4

u THEN v is to be v @: u

THEN =: 2 : 'v @: u' 
h =: *: THEN <
h
h 1 2 3

ex 5

Count items greater than 0

foo =: # @: (> & 0 # ]) 
foo 5 0 _7 3

Generalize to a conjunction u C v is to be u @: (v # ])

C =: 2 : 'u @: (v # ])' 
f =: # C (> & 0) 
f 5 0 _7 3

ex 6

Previous conjunction as multiline

D =: 2 : 0
select =: v # ] 
u @: select
)
f =: # D (> & 0) 
f
f 5 0 _7 3
fix dependence on select with f.
E =: 2 : 0
select =. v # ] 
(u @: select)f.
)
E
g =: # E (> & 0) 
g
y =: 1 0 2 3
g y

Note that g unlike doesn’t have local names.

new definitions from old

smooth appending 0

Write a function that replaces each number on the list by the mean of its two neighbors, assuming 0 neighbor for first and last.

sh    =: |. !. 0                 NB. shift, entering zero
prev  =: _1 & sh                 NB. right shift
next  =: 1 & sh                  NB. left shift
halve =: -: 
smoo  =: halve @: (prev + next)
N =: 6 2 8 2 4
N
prev N
next N
smoo N

smooth circular

To have circular smoothing, we need sh to become |. (rotate).

SMOO =: 1 : ('sh =. u' ; 'smoo f.')  
rv =: |. SMOO
rv
smoo N
rv N 

operators generating explicit verbs

Suppose we want a conjunction u H v equivalent to

3 : 0
z =. v y
y u z
)

messy way

H =: 2 : 0
U =. 5!:5 < 'u'
V =. 5!:5 < 'v'
string =. 'z =. ', V , 'y', LF
string =. string , 'y ', U , ' z', LF
3 : string
)
foo =: + H *:
foo
foo 5

This is similar to

(defun H (u v)
  (read (format "(lambda(x) (%s x (%s x)))"
                u v)))
(setq foo (H "(lambda(x y)(+ x y))"
             "(lambda(x)(* x x))"))
(funcall foo 5)

neat way

K =: 2 : 0
z =. v y
y u z
)

bar =: + K *: 
bar
bar 5

This is similar to

(defun H (u v)
  `(lambda(x)
    (funcall ,u x (funcall ,v x))))

(setq foo (H (lambda(x y)(+ x y))
             (lambda(x)(* x x))))
(funcall foo 5)

adverb generating monad

Consider a monadic verb selecting items greater than 0:

e =: 3 : '(> & 0 y) # y'
y =: 1 0 2 3
e y

Generalize to form an adverb which selects items according to a supplied test-verb, i.e. a filter:

F =: 1 : '(u y) # y'
>&1 F y
<&2 F y

adverb generating explicit dyad

ex 1

Suppose u W is to be 4 : '(u x) + (u y)'

W =: 1 : 0
:
(u x) + (u y) 
)
(*: 2) + (*: 16)
2 (*: W) 16

ex 2

Suppose u T is to be =4 : ‘x (u”0 0) ” 0 1 y’, i.e. a self-made / (table).

T =: 1 : 0
:
x ((u"0 0)"0 1) y
)
1 2 3 + T 4 5 6 7

conjunction generating explicit monad

G =: 2 : 0
selected =. (v y) # y
u selected
)
y
# G (> & 0) y

conjunction generating explicit dyad

H =: 2 : 0
:
(u x) + (v y) 
)
(*: 2) + (%: 16) 
2 (*: H %:) 16

alternative names for argument variables

Arguments to operators can be named m and n instead of u and v to constrain arguments to be nouns.

executing the body (or not)

operator of first kind

display =: (1 !: 2) & 2
R =: 2 : 0
display 'hello'
select =. v # ] 
(u @: select) f.
)
f =: # R (> & 0)
f 1 0 2 0 3

operator of second kind

S =: 2 : 0
display 'hello'
selected =. (v y) # y
u selected
)
g =: # S (> & 0)
g 1 0 2 0 3

operators generating nouns

f =: 3 : '2.8 * y * (1 - y)' 
FFF =: 1 : '(u ^: _) 0.5'
p =: f FFF
p
where =: 2 : 'u'
mean =: sum % # where sum =: +/ 
mean 1 2 3 4 
(z + 1) * (z - 1) where z =: 7

operators generating operators

CS =: @: *: 
- CS
- CS 2 3
- *: 2 3

Suppose we need u K is to be @: u

K =: 1 : '@: u' 
L =: *: K
- L
- L 2 3

Gerunds

Gerund represents a list of verbs. It’s useful mainly for supplying a list of verbs as a single argument to an operator.

making gerunds

abs =: + ` - @. (< & 0) 
abs
abs _3
G =: + ` - ` abs
G

recovering verbs from gerund

Verbs packed into a gerund can be unpacked again with the built-in adverb “Evoke Gerund” denoted by (`: 6).

EV =: `: 6
f =: 'f' & , 
g =: 'g' & , 
H =: f ` , ` g
foo =: H EV
foo
foo 'o'

Individual verbs can be unpacked by indexing the boxed list H and the applying EV.

H
2 { H
vb =: (2 { H) EV
vb
vb 'o'
H
1 2 { H
tr =: (1 2 { H) EV
tr 'a'

gerunds as arguments to built-in operators

as argument to APPEND adverb

APPEND =: `: 0
sum =: +/ 
count =: # 
mean =: sum % count
G1 =: count ` sum ` mean
G1
foo =: G1 APPEND
foo
foo 1 2 3

(u`v`w...) APPEND y means (u y),(v y),(w y),...

G2 =: 2 2 $ G1
G2
G2 APPEND 4 5

as argument to AGENDA conjunction

abs =: + ` - @. (< & 0)
abs 6
abs _6

Here, @. takes a verb on the right. It can also take a noun on the right.

G =: + ` - ` % 
f =: G @. 0
f
1 f 1
G
h =: G @. 0 2
h
h 4
G
EV =: `: 6
(G @. 0 2) 4
((0 2 { G)) EV 4
T =: * (- 1:)
T 3
T 4
foo =: (* ` - ` 1:) @. (0 ; 1 2)
T
foo
foo 3

as argument to INSERT

If G is f`g`h and X is x0,1,x2,x3 then G/X is x0 f x1 g x2 h x3

ger =: + ` % 
ger/ 1 2 3
1 + 2 % 3

If the gerund is too short, it’s re-used cyclically. This means that a one-verb gerund is equivalent to a single inserted verb.

as argument to POWER conjunction

Recall power conjunction:

double =: +: 
(double ^: 3) 1

As a variation, the number of iterations ca be computed by a verb right-argument. The scheme is, for verbs u and v: (u ^: v) y means u ^: (v y) y

decr =: <: 
double ^: (decr 3) 3
(double ^: decr) 3

More generally, the right argument can be given as a gerund, and the verbs in it do some computations at the outset of the iteration process. u ^: (v1 ` v2) y means u ^: (v1 y) (v2 y)

Verb to compute a Fibonacci sequence:

u =: , sumlast2
sumlast2 =: +/ @ last2
last2 =: _2 & {. 

as argument to AMEND

recall } (amend)
'o' 1 } 'baron'
general version

Takes a gerund of three verbs: x (U`V`W) } y means (x U y) (x V y) } (x W y) That is the new items, the indexes and the “old” array are all to be computed from given x and y.

ex 1

Define a verb R to amend a matrix by multiplying its i‘th row by a constant k. The left argument of R is to be the list i k and the right argument is to be the original matrix. R is defined as the amend adverb applied to a gerund of 3 verbs.

i =: {. @ [                     NB. x i y is first of x
k =: {: @ [                     NB. x k y is last of x
r =: i { ]                      NB. x r y is (x i y)'th row of y
R =: ((k * r) ` i ` ]) } 

For example:

M =: 3 2 $ 2 3 4 5 6 7
z =: 1 10                       NB. row 1 times 10
M
(z i M) ; (z k M) ; (z r M)
z R M
(40 50) 1 } M

as argument to user-defined operators

ex1

Define adverb A to produce a fork-like verb: x (f ` g ` h A) y is to be (f x) g (h y)

A =: 1 : 0
f =. u @. 0
g =. u @. 1
h =. u @. 2
((f @ [) g (h @ ])) f.
)

To demonstrate A, here is a verb to join the first item of x to the last of y.

H =: {. ` , ` {:
zip =: H A
zip
'abc' zip 'xyz'
'abc' ({. @ [ , {: @ ]) 'xyz'
ex2: Abelson and Sussman accumulator

A combination of filter, map and reduce.

ACC =: 1 : 0
com =. u @. 0
map =. u @. 1
fil =. u @. 2
((com/) @: map @: (#~ fil)) f.
)

For example, to compute the sum of squares of odd numbers in a given list:

+/ *: ((2 & |) # ]) 1 2 3 4
(+ ` *: ` (2 & |)) ACC 1 2 3 4

Tacit Operators

adverbs from conjunctions

recall ” (rank)

<"0 'abc'

A conjunction takes two arguments. If we supply only one, the result is an adverb. For example, an adverb to apply a given verb to each scalar is ("0).

each =: " 0
< each
z =: < each 'abc'
z

The scheme is that for conjunction C and noun N, (C N) denotes an adverb such that x (C N) means x C N. Argument to be supplied the the conjunction can be a noun or a verb, on the left or on the right. Note that this is similar to the bond &, except & isn’t necessary because conjunctions don’t have a monadic case.

recall &. (under)

f =: 'f' & , 
g =: > 
z =: 'a' ; 'b' ; 'c'
z
(f &. g) z

Define EACH adverb to mean “inside each box”:

EACH =: &. > 
f EACH
z
f EACH z

compositions of adverbs

For adverbs A and B, the bident (A B) denotes an adverb: x (A B) means (x A) B

ex1: cumulative sums and products

cum =: /\ 
z =: 2 3 4
+ cum z
* cum z

ex2: generating trains

A =: * `                        NB. verb conjunction
B =: `: 6                       NB. conjunction noun
H =: A B                        NB. compound adverb - a hook maker
<: A
<: A B
h =: <: H
h
h 5

ex3: rewriting

It’s possible to rewrite the definition of a verb to an equivalent form by rearraning its terms. Suppose we start with a definition of the factorial function

f =: (* ($: @: <:)) ` 1: @. (= 0:) 
f 5

The idea now is to rewrite f to the form $: adverb by a sequence of steps.

step 1
A1 =: @. (= 0:) 
g =: (* ($: @: <:)) ` 1: A1
f =: (* ($: @: <:)) ` 1: @. (= 0:) 
g 5
f 5
step 2
A2 =: ` 1:
h =: (* ($: @: <:)) A2 A1
h 5
step 3
A3 =: (* `) (`: 6) 
h =: (* ($: @: <:)) A2 A1
i =: ($: @: <:) A3 A2 A1
i 5
step 4
A4 =: @: <: 
j =: $: A4 A3 A2 A1
j 5
step 5
A =: A4 A3 A2 A1
k =: $: A
k 5
m =: $: (@: <:) (* `) (`: 6) (` 1:) (@. (= 0:))
m 5
f 
m

Rearrangements

Permutations

ex1

y =: 'abcde' 
4 2 3 1 0 { y
p =: 4 2 3 1 0 & { 
y
p y
p p y
p p p p p p y
p ^: 6 y

The permutation (4 2 3 1 0) can be represented as a cyle of 2 and a cycle of 3

C. 4 2 3 1 0
C. 3 1 2 ; 4 0

First representation is called direct, second is called cyclic.

ex2: predefined collating sequences

Upper-case letters come before lower-case letters.

65 66 67 97 98 99 { a.

Complex numbers are ordered by the real part then the imaginary part.

n =: 0 1 _1 2j1 1j2 1j1
n /: n

With boxed arrays, the ordering is by the contents of each box.

The precedence is

first by type

numerical < empty < chars < boxed

[k =: (< 'abc') ; 'pqr' ; 4 ; '' ; 3
k /: k

second by rank

low rank < high rank

[m =: 2 4 ; 3 ; (1 1 $ 1)
(# @ $ @ >) m
m /: m
finally element by element

If they have the same rank, compare elementwise: 1 2 < 1 3, 3 3 < 3 3 3

a =: 2 3 $ 1 2 3 4 5 6
b =: 3 2 $ 1 2 5 6 3 4
c =: 1 3 $ 1 2 3
[u =: a ; b ; c
u /: u

ex3: user-defined collating sequences

Suppose we want to sort by abs.

x =: 2 1 _3
keys =: | x
x /: keys

Transpositions

The monadic verb |: will transpose a matrix, that is interchange the first and second axes.

Shifting

The items which would be brought around by cyclic rotation can instead be replaced with a fill-term.

A shifting verb is written (|. !. f) where f is the fill-item.

ash =: |. !. '*'                NB. alphabetic shift
nsh =: |. !. 0                  NB. numeric shift
y =: 'abcde'
y ; (_2 ash y) ; (1 ash y)
z =: 2 3 4
z ; (_1 nsh z) ; (2 nsh z)

Patterns of Application

Scanning

Prefix Scanning

<\ 'abcde'
+/\ 0 1 2 3
+./\ 0 1 0 1 0

Infix Scanning

In the expression x f \ y the verb f is applied to successive sections (“infixes”) of y, each of length x.

z =: 1 4 9 16
2 <\ z
3 <\ z

If x is negative, then the sections are non-overlapping, in which case the last section may not be full-length.

z =: 1 4 9 16
_3 <\ z
_2 <\ i.10

We can compute the differences between successive items, by choosing 2 for the section-length, and applying to each section a verb “second-minus-first”, that is, ({: - {.)

smf =: {: - {. 
smf 1 4
diff =: 2 & (smf\)
z =: 1 4 9 16
,. diff z

Suffix Scanning

(f \. y) applies f to successively shorter suffixes of y:

<\. 'abcde'

Outfix

(x f \. y) applies f to the whole of y with successive sections removed, each being of length x. If x is negative, then the removed sections are non-overlapping.

y =: 'abcde' 
2 <\. y
_2 <\. y

How to enter tables of numbers

Start with

T =: 0 : 0
1   2  3
4   5  6
19 20 21
)
$ T
+/ T = LF

T is a character-string with 3 embedded line-feed chars. Now cut T into lines. Then eval them with “.

[ TBL =: (". ;. _2) T
*: TBL

Punctuation

frets =: ' ? !.' 
t =: 'How are you?'
[ b =: t e. frets

Now the bitvector b can be used to specify the frets for cutting text t into words:

b < ;. _2 t

Consider cutting a numeric vector into intervals such that each is in ascending sequence.

Compute a bitvector by scanning infixes of length 2, applying >/ to each pair of items. Where we get 1, the second item of the pair is the beginning of a new interval. We make sure the first item of all is 1.

data =: 3 1 4 1 5 9
2 ]\ data
2 >/\ data
] bv =: 1 , 2 >/\ data
data ,: bv
bv < ;. 1 data

Lines in Files

First, create an example file.

text =: 0 : 0
What can be said
at all
can be said
clearly.
)
text (1 !: 2) < 'foo.txt'

Now read into a string and cut it:

string =: (1 !: 1) < 'foo.txt'
] lines =: (< ;. _2) string

Note that we rely here on LF for cutting. Windows has CRLF instead of LF. J follows the convention of the single LF regardless of the system. However CR have to be taken care of. Here’s how to strip it:

string =: (string ~: CR) # string

Secondly, depending on how the file of text was produced, we may not be able to guarantee that the last line is actually terminated.

tidy =: 3 : 0
y =. y , (LF ~: {: y) # LF      NB. append LF if not already there
(y ~: CR) # y                   NB. remove CR
)
(< ;. _2) tidy (1 !: 1) < 'foo.txt'

Tiling

x u ;. 3 y applies u separately to each of a collection of subarrays extracted from y. These subarrays may be called tiles. The size and arrangement of the tiles are defined by x.

y =: 4 4 $ 'abcdefghijklmnop'
spec =: > 2 2 ; 2 2             NB. offset, shape
spec < ;. 3 y

Tiling may leave incomplete pieces(“shards”) at the edges. They’re included or excluded with 3 or _3.

sp =: > 3 3 ; 3 3
sp < ;. 3 y
sp < ;. _3 y

Sets, Classes and Relations

Set Equal

seteq =: *./ @: (e. , e.~) 
1 2 3 seteq 3 1 2 1
1 2 3 seteq 1 2

Classes

Self-Classify

Consider finding frequency-distribution of letters.

y =: 'hook' 
~. y
(~. y) =/ y
= y

If we sum each row we obtain the counts, in the order of the letters in the nub.

y =: 'hook' 
= y
+/"1 = y

The counts can be paired with the letters of the nub:

y =: 'hook' 
~. y
(~. y) ;"0 (+/"1 = y)

Classification Schemes

Classify soil-type as acid, neutral or alkaline depending on pH.

classify =: ({ & 'ANL') @: ((>: & 6) + (> & 7))
classify 6
classify 4.8 5.1 6 7 7.1 8

The Key Adverb

data =: 7 5 6 4 8
] k =: classify data
k = 'A'
(k = 'A') # data

Now suppose we wish to count the items in each class.

data
[ k =: classify data
k #/. data
k </. data

The verb we apply can discover for itself the class of each separate argument, by classifying the first member:

u =: (classify @: {.) ; # 
data
] k =: classify data
k u/. data

The general scheme for the “Key” is: in x u/. y take y to be a list, and x a list of keys, and u a verb to be applied separately to each class.

] y =: 4 5 6 7 8
] x =: classify y
u =: < 
= x
(=  x) (u @ #) y
x u/. y

More letter counting

y =: 'LETTUCE'
= y
(~. y) ;"0 +/"1 (= y)

u =: {. ; # 
y u/. y

Relations

Suppose there are a number of publications, such as:

  • “Pigs” by Smith, on the subject of pigs
  • “Pets” by Brown, on cats and dogs
  • “Dogs” by Smith and James, on dogs

and we aim to catalog such publications. We can use two tables called relations.

first representation: tables of boxed strings

The authors-titles relation is:

] AT =: (". ;. _2) 0 : 0
'Smith' ; 'Pigs'
'Brown' ; 'Pets'
'Smith' ; 'Dogs'
'James' ; 'Dogs'
)

And the titles-subjects relation is:

] TS =: (". ;. _2) 0 : 0
'Pigs' ; 'pigs'
'Pets' ; 'cats' 
'Pets' ; 'dogs' 
'Dogs' ; 'dogs' 
)

A method is as follows. Consider all possible pairs consisting of a row at from table AT and a row ts from table TS. Each pair at,ts is of the form: author ; title ; title ; subject If title matches, i.e. item 1 matches item 2, then we extract author and subject, i.e. items 0 and 3.

test =: 1 & { = 2 & {
extr =: 0 3 & { 

These verbs can be plugged into a suitable conjunction to do the pairing. It writing this conjunction, we aim to avoid requiring the whole set of possible pairs to be present at the same time, since this set may be large. We also aim to avoid any duplicates in the result. Here is a first attempt.

PAIR =: 2 : 0
: 
z =. 0 0 $ '' 
for_at. x do. 
   for_ts. y do.
     if. u at , ts do. z =. z , v at , ts end. 
   end.
end.
~. z
)
join =: test PAIR extr
AT join TS

The join verb as defined above is slow, because the test and extr verbs are applied to a single x,y pair at a time - they are scalar computations. Performance will be better if we can give these verbs as much data as possible to work on at one time.

Here is a revised vector-oriented version of PAIR and join, which still avoids building the entire set of pairs.

VPAIR =: 2 : 0
: 
z =. 0 0 $ '' 
for_at. x do.
  z =. z , |: v (#~"1 u) |: at ,"1 y
end.
~. z
)
vjoin =: test VPAIR extr
AT vjoin TS

What are Symbols?

Symbols are for efficient computation with string data. They’re a distinct data-type, in the same way as characters, boxes and numbers. A symbol is a scalar which refers to a string. A symbol can be created by applying s: to a boxed string.

] a =: s: < 'hello'

Although it looks like the original string with ` prepended, it’s a scalar:

# $ a

The original string is stored in a data-structure, maintained automatically by the J system, called the symbol-table. Strings aren’t duplicated so if there’s two references to the same string, they’re equal.

b =: s: < 'hello'
b = a

Note that this is a scalar comparison and not a string comparison.

sAT =: s: AT
sTS =: s: TS
sAT vjoin sTS

Symbols are lexicographically ordered to reflect the ordering of the original strings. Hence tables of symbols can be sorted:

sAT
/:~ sAT

Measurements Compared

A utility verb giving time in seconds to evaluate an expression, averaged over 4 executions:

time =: (8j5 & ":) @: (4 & (6 !: 2))
AT =: 100 $ AT
TS =: 100 $ TS
sAT =: 100 $ sAT
sTS =: 100 $ sTS
t1 =: time 'AT join TS'         NB. scalar method, boxed strings
t2 =: time 'sAT join sTS'       NB. scalar method, symbols
t3 =: time 'AT vjoin TS'        NB. vector method, boxed strings
t4 =: time 'sAT vjoin sTS'      NB. vector method, symbols
3 3 $ ' ' ; 'strings' ; 'symbols' ; 'scalar' ; t1 ; t2 ; 'vector' ; t3 ; t4

Saving and Restoring the Symbol Table

Suppose that data is an array of symbols.

] data =: s: 2 2 $ 'hello' ; 'blah' ; 'blah' ; 'goodbye' 
i.2 3 4
s: 2 2 $ 'fooommmmm' ; 'blurg' ; 'blah' ; 'bar' 
s: 2 2 $ 'blah' ; 'bar' ; 'fooommmmm' ; 'blurg'

pdfs

sudoku

i =: ,((,|:)i.9 9),,./,./i.4$3
c =: (#=[:#~.)@-.&0
t =: [:(([:*/_9:c\])"1#])i&{+"1 1(>:i.9)*/[:i&=i.&0
r =: [:,`$:@.(0:e.,)[:;(<@t)"1
s =: 9 9&$@r@,
]m =: 9 9 $"."0'200370009009200007001004002050000800008000900006000040900100500800007600400089001'
s m
2 0 0 3 7 0 0 0 9
0 0 9 2 0 0 0 0 7
0 0 1 0 0 4 0 0 2
0 5 0 0 0 0 8 0 0
0 0 8 0 0 0 9 0 0
0 0 6 0 0 0 0 4 0
9 0 0 1 0 0 5 0 0
8 0 0 0 0 7 6 0 0
4 0 0 0 8 9 0 0 1

2 8 4 3 7 5 1 6 9
6 3 9 2 1 8 4 5 7
5 7 1 9 6 4 3 8 2
1 5 2 4 9 6 8 7 3
3 4 8 7 5 2 9 1 6
7 9 6 8 3 1 2 4 5
9 6 7 1 4 3 5 2 8
8 1 3 5 2 7 6 9 4
4 2 5 6 8 9 7 3 1

factorial

i.20
1 + i.20
*/ 1 + i.20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment