@katlyn generic as can be :neofox_floof: it's still in theory & planning but i'd like to make something somewhere between a mix of Jai and Kotlin, essentially a quite low level language with a syntax more typical of a high level language.
There are a couple neat features that I plan on having, one is automatic callsite syntax variants for functions, where a function definition func(a, b) can be called in any supported syntax style; procedural (func(a, b)), OOP (a.func(b)), infix if it has exactly 2 arguments (a func b), etc.
Functions are first-class members (now that i've touched a language with it, I can't stand any language without it) and can appear in any place any other variable may appear
Here's a bit of sample for my ideas so far
//Syntax not final
numberOfBoops: Int = 1234 //Mutable variable declared and re-declared with = operator
numberOfBoops = 999999 //Cannot redeclare type
millionBoops = numberOfBoops + 1 //Type specification optional; when not specified, type will be inferred as narrowest type returned by expression (here, Int)
billionBoops: Int := 1000000000 //Immutable declarations use := operator
billionBoops = 1 //Compile error, cannot reassign immutable declaration
PI: Double #const := 3.14159265359 //'const' declarations may be optimized by compiler to inline at use-sites instead of appearing in heap memory
TAU #const := PI * 2.0 //Type is optional for all declarations; will be inferred as the narrowest type of the expression (here being a Double)
myCoolNumber: Int //uninitialized variable, must be initialized before appearing in any read position
main := () { /*statements*/ } //skeleton of function declaration syntax. No return type
getCoolNumber := () -> Int { return 420 } //function with return type
myCoolNumber = getCoolNumber() //initialize previously uninitialized variable, now it can be used
plus := (a: Int, b: Int) -> Int { a + b } //function with parameters and return type; 'return' may be omitted if last expression of function scope is of return type
myCoolerNumber := myCoolNumber plus 69 //infix call to 'plus'. Immutable declarations can be made from mutable expressions
myCoolestNumber: Int #const := myCoolerNumber + 1337 //Compile error, const declarations can only be constructed with literals and other const expressions
fold := <T, E>(elements: Iterable<E>, initial: T, op: (T, E) -> T) -> T { //function declaration with generic types T and E
accumulator = initial //Function parameters are always immutable, redeclare 'initial' with mutable variable
itr := elements.iterator() //function 'iterator := <E>(Iterable<E>) -> Iterator<E>' defined in Iterable class
while(itr.hasNext()) {
item := itr.next() //Immutable variables can be defined once per iteration of any scope ({}) so 'item' may be immutable here
accumulator = accumulator op item //Infix notation of 'op' function
}
return accumulator
}
sum := (values: Iterable<Int>)[fold, plus] -> Int { //optional brackets is a closure: if present, only variables in wider scope listed inside brackets may be referenced (here being the 'fold' and 'plus' function)
return values.fold(0, (acc, next){acc plus next}) //anonymous function provided as 'op' first-class function parameter to 'fold' function. Parameter types and return type inferred by 'fold' declaration
}