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.
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]