j + k = jk (just kidding)

txlyre 96583e02f8 upd readme; fix unique hai 2 semanas
.gitignore dcd441be2a initial hai 3 semanas
build.sh 1c72f02b09 fix at; add laminate; add e. i.; upd help; fix format hai 3 semanas
jk.c 96583e02f8 upd readme; fix unique hai 2 semanas
readme.md 96583e02f8 upd readme; fix unique hai 2 semanas

readme.md

jk

jk is a recreational tacit array programming language inspired by J and K (so j + k = jk).
this is an implementation of the jk interpreter in C. Requires libgc (a.k.a. bdwgc) to build.

Examples

Compute factorial

    fac:*/!. / analytic
    fac 5
120
    facr:<.;1?.(]*(f.<)),:(:1) / recursive
    facr 5
120
    / or simply use *.
    *.5
120

Compute Nth fibonacci

    fib:*x?:(+\|)!2 / iterative
    fib 10
55
    fib"!.10
1 1 2 3 5 8 13 21 34 55
    fibr:<.;1?.((f.<)+(f.(<<))),:] / recursive
    fibr"!.10
1 1 2 3 5 8 13 21 34 55
    / or just +.
    +.!.10
1 1 2 3 5 8 13 21 34 55

Remove consecutive duplicates

    rcd:]&.(1~:".)
    rcd 'abobaabuuss'
abobabus

Check if an array is palindrome

    ispal:]=:|
    ispal 'aboba'
1
    ispal 'hi'
0

Count occurences

    occs:?,"(#"]@#:)
    occs 'abracadabra'
a 5
b 2
r 2
c 1
d 1
    occs 'Hello World!'
H 1
e 1
l 3
o 2
  1
W 1
r 1
d 1
! 1

Quick reference (also available in the interpreter itself)

/ comment
5+5 / also comment
5+5/not comment (no whitespace before /)
nil udf                   / special, nil and undefined
'a'%2                     / = nan, nan used to denote illegal numeric operation
+1 2 3                    / = udf, attempt to transpose flat vector, udf/undefined used to denote illegal operation
5 5.5 -5 42               / number (double-precision floats)
1`000 1`000`000           /
.5 .429                   /
0xff 0o4 0b0101           /
nan inf                   /
'a' 'b' 'g'               / chars (bytes)
4t.0                      / 0 NUL byte
(4t.0),:(4t.16),:(4t.22)  /
1 2 3                     / numbers array
'hello world!' 'bla''bla' / quote, array of chars
,'a'                      / 1-char string
,1                        / 1-elt array
()                        / unit, empty array
1,:(5+5),:1 2 3           / strand, mixed array literal
-1                        / negative num literal
- 1                       / application of - negate to 1
-1 -2 -3                  / array of negative nums
- 1 2 3                   / application of - negate to an array of nums
5-5                       / array of numbers 5 and -5
5- 5                      / 5 minus 5
+                         / verb
5+5                       / dyadic expr
#1 2 3                    / monadic expr (no left side)
+/ *;.                    / adverb
+;1 -;* +^:^.             / conjunction
:x+y                      / function literal
:1                        / function that always yields 1
x:123                     / bind name
sq:*;.                    /
fac:*/1+!                 / bind function
f:x+y                     /
f:-x                      / overload function by arity
f 5                       / = -5
5 f 5                     / = 10
*/!.                      / hook, fgx -> f(g(x)), xfgy -> f(g(x, y))
+/%#                      / fork, fghx -> g(f(x), h(x)), xfghy -> g(f(x), h(y))
1+!                       / over, nfgx -> f(n, g(x)), xnfgy -> f(n, g(x, y))
1+                        / bond, nfx -> f(n, x), xnfy -> f(n, f(x, y))

:  monadic const         create a function that always yields x
:  dyadic  bind          bind y to symbol x
:: monadic unbind        unbind symbol x
:: dyadic  obverse       insert inverse for x
+  monadic flip          transpose matrix
+  dyadic  plus          add numbers
+. monadic fibonacci     compute xth fibonacci number
+. dyadic  gcd           compute gcd(x, y)
+: monadic sin           compute sin(x)
+: dyadic  combine       combine digits of x and y, same as 10_.(10_:),(10_:)
-  monadic negate        negate number
-  dyadic  minus         subtract numbers
*  monadic first         yield first element of x
*  dyadic  times         multiply numbers
*. monadic factorial     x!
*. dyadic  lcm           compute lcm(x, y)
*: monadic double        x * 2
*: dyadic  replicate     repeat y x times
%  monadic reciprocal    1 / x
%  dyadic  divide        divide numbers
%. monadic sqrt          compute square root of x
%. dyadic  root          compute xth root of y
%: monadic halve         x % 2
%: dyadic  idivide       same as % divide, but result is always integer
!  monadic enum          [0, x)
!  dyadic  mod           modulo of numbers
!. monadic iota          [1, x]
!. dyadic  range         [x, y] (also works for chars and even if x > y)
!: monadic odometer      !:10 10 is 0 0,:0 1,: ... 1 0,:1 1,: ... 9 8,:9 9
!: dyadic  chunks        split y into x-sized chunks
^  monadic exp           e^x
^  dyadic  power         raise number to a power
^. monadic nlog          ln(x)
^. dyadic  log           log(y)/log(x)
=  monadic permute       generate permutations of x
=  dyadic  equals        test whether x and y are equal
=. monadic occurences    count occurences of elts, =.'Hello World!' is 0 0 0 1 0 0 0 1 0 2 0 0
=. dyadic  mask          mask one array in another, 'abxyzabayxxyabxyk'=.'xy' is 0 0 1 1 0 0 0 0 0 0 2 2 0 0 3 3 0
=: monadic classify      assign unique index to each unique elt, =:'Hello World!' is 0 1 2 2 3 4 5 3 6 2 7 8
=: dyadic  match         same as = equals, but rank 0, so compares x and y as whole
~  monadic not           logical not, nil udf () 0 4t.0 are not truthy, everything else is truthy
~  dyadic  notequals     test whether x and y are not equal
~. monadic sign          sign of x, -1 for negative, 0 for 0, 1 for positive
~. dyadic  insert        insert x between elts of y, 0~.1 2 3 is 1 0 2 0 3
~: dyadic  notmatch      rank 0 version of ~ notequals
<  monadic pred          x - 1
<  dyadic  less          test whether x is lesser than y
<. monadic floor         round x down
<. dyadic  lesseq        test whether x is equal or lesser than y
<: monadic gradedown     indices of array sorted descending
<: dyadic  nudgeleft     shift elts of y to the left filling gap with x
>  monadic succ          x + 1
>  dyadic  greater       test whether x is greater than y
>. monadic ceil          round x up
>. dyadic  greatereq     test whether x is equal or greater than y
>: monadic gradeup       indices of array sorted ascending
>: dyadic  nudgeright    shift elts of y to the right filling gap with x
,  monadic enlist        put x into 1-elt array
,  dyadic  join          concat x and y
,. monadic enfile        same as , enlist but with infinite rank, ,.1 2 3 is (,1),:(,2),:(,3)
,. dyadic  enpair        put x and y into 2-elt array
#  monadic count         yield count of elts of x
#  dyadic  take          take x first elts of y (or last if x < 0)
#. monadic where         #.0 0 1 0 1 0 is 2 4
#. dyadic  copy          repeat each elt of x by corresponding number in y, 5 2 3 3#.0 2 2 1 is 2 2 3 3 3
#: monadic group         #:'mississippi' is (,0),:1 4 7 10,:2 3 5 6,:8 9
#: dyadic  buckets       group elts of y into buckets according to x, e.g. 0 -1 -1 2 0#:a b c d e is (a,.e),:(),:(,d)
_  monadic nub           mark all unique elts of x, e.g. _'abracadabra' yields 1 1 1 0 1 0 1 0 0 0 0
_  dyadic  drop          remove first x elts of y (or last if x < 0)
_. monadic unbits        _.1 0 1 is 5
_. dyadic  unbase        10_.4 5 6 is 456
_: monadic bits          _:5 is 1 0 1
_: dyadic  base          10_:4242 is 4 2 4 2
?  monadic unique        distinct elts of x, same as ]#._
?  dyadic  find          find all indices of x in y
&  monadic flatten       flatten an array, same as ,//.
&  dyadic  minand        get min of two numbers (logical and for 0/1s)
|  monadic reverse       reverse an array
|  dyadic  maxor         get max of two numbers (for 0/1s is same as logical or)
|. monadic round         round x
|. dyadic  rotate        rotate array x times clockwise (-x for counterclockwise)
|: monadic depth         find max depth of x, |:,,,y yields 3
|: dyadic  windows       yields all contiguous x-sized subarrays of y
@  monadic abs           |x|
@  dyadic  at            pick elts from x by indices from y
@. monadic shuffle       shuffle elts of x
@. dyadic  member        check whether x is in y
@: dyadic  indexof       yield index of x in y or #y if x not in y
{  monadic head          first two elts of x, same as 2#
{  dyadic  bin           bin search, e.g. 1 3 5 7 9{8 9 0 yields 3 4 -1
{. monadic tail          last elt of x
{: monadic prefixes      prefixes of x, same as |}.\.
{: dyadic  shl           x << y
}  monadic behead        all elts of x except first, same as 1_
}  dyadic  xor           x ^ y
}. monadic curtail       all elts of x except last, same as -1_
}: monadic suffixes      suffixes of x, same as }.\.
}: dyadic  shr           x >> y
[  monadic factors       compute prime factors of x
[  dyadic  left          yield x
[. monadic bnot          ~x
[. dyadic  bor           x | y
[: monadic primes        find primes in range [2, x]
[: dyadic  parts         split y into x parts
]  monadic same          yield x (i.e. identity)
]  dyadic  right         yield y (i.e. right argument)
]. monadic sort          sort x ascending, shortcut for ]@>:
]. dyadic  outof         the number of ways of picking x balls from a bag of y balls, e.g. 5].10 is 252
]: monadic unsort        sort x descending, shortcut for ]@<:
]: dyadic  explode       split y by delim x
`. monadic symbol        cast x to a symbol
`. dyadic  apply1        apply x to y
`: monadic square        x ^ 2
`: dyadic  apply2        apply x to y (y is 2-elt array of args)
$  monadic shape         yield shape of x
$  dyadic  reshape       reshape y to shape x
$. monadic repr          yield string repr of x
$. dyadic  format        format y by template x, e.g. '{0}+{1}*{-1}+_'$.1 2 3 4 is 1+2*4+1
$: monadic eye           identity matrix of size x
$: dyadic  implode       join y inserting x between

p. monadic print         print x
P. monadic println       print x and a \n
f. monadic selfref1      monadic reference to current function or rhs of bind
f. dyadic  selfref2      dyadic reference to current function or rhs of bind
F. monadic read          read file (x=0 to read stdin)
F. dyadic  write         write file (y=0 to write to stderr)
t. monadic type          type of x, array=0, verb=1, symbol=2, number=3, char=4, nil=5, udf=6
r. monadic deal          yield random elt of x
r. dyadic  roll          roll xdy (note: y is 0-based, so >xr.y for 1-based)
e. monadic eval          eval expression, yields udf on parse error
i. monadic import        load and eval source file
y. monadic system        exec system command (yields output)
y. dyadic  system2       exec system command with input
E. monadic exit          exit with exit code
L. dyadic  tackleft      prepend x to y
R. dyadic  tackright     append x to y

f"         each          >"1 2 3 yields 2 3 4
xf"        merge         1 2 3,"a b c yields (1,.a),:(2,.b),:(3,.c)
f".        eachprior     -".1 2 2 3 5 6 yields 1 0 1 2 1
xf".       eachpriorwith 0-".1 2 2 3 5 6 yields 1 1 0 1 2 1
f/         fold          +/1 2 3 yields 6
xf/        foldwith      1+/1 2 3 yields 7
f\         scan          +\1 2 3 yields 1 3 6
xf\        scanwith      1+\1 2 3 yields 1 2 4 7
f/.        converge      1;_/.1 2 3 yields ()
f\.        converges     1;_\.1 2 3 yields 1 2 3,:2 3,:(,3),:()
xf/.       eachright     1-/.1 2 3 yields 0 1 2
xf\.       eachleft      1-\.1 2 3 yields 0 -1 -2
f":        rank          #":1 2 3$1 yields 3 3, #":inf 2 3$1 yields 1 1 1,:1 1 1
xf":       rank2         1 2 3 *:":1 1 2 3 yields (,1),:2 2,:3 3 3
n`         amend         'gw'0 3`'cross' yields 'grows'
f&.        filter        >;0&.-2!.2 yields 1 2, basically shortcut for ]#.f
f/:        span          =;' '/:'x y z' yields (,'x'),:(,'y'),:(,'z')
xf/:       stencil       3+//:!10 yields 3 6 9 12 15 18 21 24, shortcut for f"x|:
f;.        reflex        *;.5 yields 25, 5%;.2 yields 0.4

f;g        bond          */;!.5 yields 120, +;1 5 yields 6, 5;- 1 yields 4
f?.x       pick          >;5?.((2*),:<)"3 6 yields 6 5
f?:F       while         <;5?:>0 yields 5
n?:f       repeat        5?:*;2 1 yields 32
f&:F       if            1+&:+2 yields 2
f;:F       monaddyad     -;:+5 yields -5, 1-;:+5 yields 6

inverse of a function f is a function ~f that undoes the effect of f

f::~f  obverse  define inverse ~f for f

f-:x       inverse       ~fx
xf-:y      inverse2      (~fx)~f~fx
f^:Fx      under         ~FfFx
xf^:Fx     under2        ~F(Fx)f(Fx)

Prebuilt binaries

There is prebuilt ELF executables with statically linked libgc for x86-64 and aarch64 Linux: