jtye: a direct k for javascript tests

k core (k.js) bytes
parser (parse.js) bytes

about

jtye/k is k for javascript.

i write more js these days, mainly for ui and cross platform.
my style evolves to more functional. that's mostly fine but sometimes annoying.

compare: let sum=(f,x)=>x.reduce((a,x)=>f(a,x),0)
why not:                                over(add)

core

the core adds 50 primitive functions and 3 helpers which work on numbers arrays and strings. the functions can be used directly in javascript.

the helper functions rec and atomic can be used to extend the language with more vector functions, e.g.

sin=rec(Math.sin),cos=rec(Math.cos),pow=atomic(Math.pow)

parse

let's add a parser, that transforms k source to js which uses our primitives.

bytecode, virtual machine? we don't need this, we can just use javascript's eval.
see the test's output (in green) what the parser compiles k code to.

ref

+ type   add   ' each prior bin `js`
- neg    sub   / over right join dec
* sqr    mul   \ scan left split enc
% sqrt   div   inv idiv mod
& flip   min              
| rev    max                 atom 
< up     less                atomic
> down   more                   rec
= freq   eql        
~ not    match           
. value        parse
! til    dict  token key where
@ first  at    amend
? uniq   find  rand
^ sort   cut             while()[;;]
# count  take            if()[;;;;;]
_ floor  drop            do[]while()
, list   cat             for(;;)[;;]
$ string             try[]catch(e)[]

adverbs

there are only 3 adverb symbols ' / \ ' is each or prior(for :+-*%&|<>=~), / \ are over and scan. derived verbs from each over and scan are available in variadic form and may also take more than 1 argument. the verb's arity should match the number of arguments: e.g. f'[a;b;c] is triadic each. x/y x\y is is encode/decode for numbers and join/split for strings. x'y is binary search.

ambivalence

primitives are fixed at compile time if possible, e.g. 1-2 is sub, while -x is neg. by themselves, e.g. (-;+) or f:- they default to dyadic, e.g. sub but not neg. this is also true when used in derived +/ which is over(add). the exception is each: -' compiles to ambivalent each((x,y)=>y===undefined?neg(x):sub(x,y)) derived verbs themselves, are monadic by default +/ is sum not add-each-right. the dyadic form is chosen at compile time for x+/y. this is resolved at runtime using variadic forms. compositions however are always dyadic: 1+- is {1+x-y} to simulate a monadic train, append dex(:) e.g. 1+-:

js escape

everything between backticks is compiled verbatim to js and parsed as a noun:
f`x.slice(-3)` compiles to  at(x.slice(3),f)

structural todo

while(1>x)[]
do[]while(1>x) (maybe not)
[]=>{b;l;o;c;k}
for(a;b;c)[]
for(`let i in a`)
if()[]         (no else)
try[]catch(e)[]
$[a;b;c]

web use

<script src="k.js"></script>
<script src="parse.js"></script>
example.. e.g. interactive page in k

standalone

see:mk, todo click to download. or compile to native: qjsc(6mb)
jtye/k (in //parse out \doc)