What: a close descendant of K (and Goal) with implicit multi-core/GPU acceleration.
Why: fun?
How: Python prototype, then “for real” in CUDA/C++ (or perhaps Zig or Odin?)
Dream: fast DSL for data-intensive kernels hosted in a distributed system environment like Gleam.
K is a vector language descended from APL, with hints of lisp.
- Expressions evaluate right-to-left.
- Operators have equal precedence, so
a*-b+c
isa*(-(b+c))
. - Some operators are heavily overloaded based on number and type of their arguments.
For example
*
has just two meanings (for*x
andx*y
) but!
has 7 variants. These overloaded meanings are usually (but not always) related. - Iterators like
'
(each)/
(reduce) and\
(scan) take the place of for/while loops.
1+2 3 4 /no-nonsense vectors
3 4 5
+\(1 2;3 4;5 6) /iterators modify verbs. "\" is "scan"
(1 2
4 6
9 12)
-1_(+9(|+\)\1 1)1 /first 9 fibonacci numbers
1 1 2 3 5 8 13 21 34
{-1_(+9(|+\)\1 1)1}[] /as above, but as a function
{-1_(+x(|+\)\1 1)1}[9] /parameterized with default first arg "x"
f:{-1_(+x(|+\)\1 1)1}[9] /save function to the name "f"
f'2 8 9 /apply "f" to each (') item in vector 2 8 9, producing a list of results
(1 1
1 1 2 3 5 8 13 21
1 1 2 3 5 8 13 21 34)
Most Ks have:
- 1-dimensional vectors, nested lists, dictionaries
- an interpreter
- eager evaluation
- simple scoping rules (names are exclusively local or global)
- basic interaction with the host system
\cd
to change directory without leaving the interpreter- run commands on the host system like
\ls
,\pwd
- built-in file and socket I/O
- a method for loading/executing other K scripts
- dynamic typing:
- no user-defined types
- atomic types: integer, float, string, symbol (“booleans” use integers 0 and 1)
- 1-d homogeneous vectors of any of the atomic types
- implicit numeric promotion:
1+2.0
is3.0
- heterogeneous lists containing any type
- dictionaries with atomic type keys and values of any type
- mutable variables (but operations do not mutate their arguments)
- arithmetic operations defined for single values as well as collections.
1+2
is3
,1+2 0 3
is3 1 4
- structural operations on collections.
(1 2),`a`b
is(1;2;`a;`b)
- right-to-left evaluation, no operator precedence:
2*3+4
is2*(3+4)
- partial application or “projections” instead of closures:
{x+y+z}[1;;3]
is{1+x+3}
There are multiple K dialects with slightly different features. Element is a direct descendant of ngn/k, but there are some differences.
Planned features:
- [ ] implicit hardware acceleration by default
- [ ] small data processed on one CPU
- [ ] big irregular data processed on multiple CPUs
- [ ] big regular data processed on GPU
- [ ] lexical scope
- [ ] closures
- [X] string data type (distinct from “list of char”) as in goal
- [ ]
x:y
declare immutableb:1; b::2
(error,b
is immutable!) - [ ]
x::y
declare/update mutable variable:a::1; a::2
(ok,a
is mutable) - [ ] append
::
to an operator for update-in-place semantics:a::1; a+::2; /a is 3
- [ ]
(a+b;a:1;b:2)
is valid in K but not in Element. In Element,e1;e2
is two expressions evaluated left to right, and a list(e1;e2)
captures the result of each of those expressions. To replicate the K behavior usea:1;b:2;(a+b;a;b)
or2_(a:1;b:2;a+b;a;b)
.
Aspirational features:
- [ ] module system:
require x
,provide x
- [ ]
\cd
etc. provided by REPL, not runtime
Compile for GPU with NVIDIA’s nvcc
compiler:
cd element/src && make
./element
Or for CPU with g++
:
CPU=1 cd element && make
./element
- chemistry puns: K is potassium, CUDA (Cu) is copper
- vector languages deal with “elements of a vector” frequently
- naming is hard
This project is in the experimental, pre-alpha stage. Some doctest tests exist, but no coverage goals yet.
[0/3]
- [-] prototype implementation
- [X] lex/scan/tokenize
- [X] parse
- [ ] semantic analysis
- [ ] type inference
- [ ] type checking
- [ ] name binding
- [ ] other errors (arity, unused)
- [-] codegen
- [X] tree-walk interpreter
- [X] simple arithmetic
1+2
- [X] array arithmetic
1 2+3 4
- [ ] type inference
- [ ] variable names and lexical scope
- [ ] composition/projection
(2+)1
- [ ] iterators
+/1 2 3
- [ ] structural functions
3#"hi""world"
- [-] hardware accelerated implementation
- [X] lex/scan/tokenize
- [ ] parse
- [ ] semantic analysis
- [ ] optimization
- [ ] codegen
- [ ] stable release(s)
- [ ] pick a version numbering system (and stick to it)
- [ ] formal grammar
- [ ] standard library
- [ ] package management
- [ ] documentation, playground, tutorials