# 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?.(]*(s.<)),:(: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?.((s.<)+(s.(<<))),:] / 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 *it@<:{."it / get most frequent l 3 ``` ## Make multiplication table ``` *\.;.!.9 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81 ``` ## Duplicate zeroes keeping the same shape ``` dzks:##]#.(>0=) dzks 1 0 2 3 0 4 5 0 1 0 0 2 3 0 0 4 ``` # 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 s. monadic selfref1 monadic reference to current function or rhs of bind s. 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 i. dyadic foreign call external function (lhs is array of arguments), e.g. .5i.'libm.so:dd:sin' 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: - [x86_64](https://files.txlyre.website/d/software/jk/latest_linux_x86_64/jk) - [aarch64](https://files.txlyre.website/d/software/jk/latest_linux_aarch64/jk)