Awesome
kara - powerful, native compiler project
Kara is a statically typed, LLVM-based programming language. It's designed to be fast and easy to use.
During a recursive benchmark to recursively calculate the first 500000 prime numbers, Kara with -O3
performed about 90x faster than Python, and over 2x as fast as Java on my MacBook Pro 2015.
This project is also about bringing many frustrations I've encountered with other languages to rest. In many other languages, there are plenty of clean or performant solutions that are just too bulky or confusing to realistically use.
Case in point, a std::variant
error bubbling is 4x faster than a similar Coroutine solution, but so much more verbose that it's impractical to use. With kara I plan to keep the speed but cut out verbosity to make for a peaceful developer experience.
Design Goals
- Beginner-friendly, code should be readable and extendable.
- For ease of mind, more complex features should be a combination of simpler features.
- Fast, native code. Abstract common patterns quickly.
- Encourage self documentation through various interactive builtin types.
Progress
Until 1.0
.
Variables
-
let
/var
name
=value
- Explicit Type After Name
- Implicit Type Deduction
- Mutability Checking
Types
- Declaration
type Name { field1 Type1, field2 Type2 }
- Aliasing
type Name = OtherType
- Type Construction
TypeName(field1: value1, field2: value2)
- Explicitly uninitialized types for constructors
- References for use in constructors
&out Type
- Map to Result Syntax,
let z TypeName = (field1: value1, field2: value2)
- Enums,
enum { A, B, C }
- Enum With Data
enum { A => Type, B => +(a: Type1, b: Type2), C }
Builtins
- References
&T
- Unique Pointers
*T
- Shared Pointers
*shared T
- Dynamic Arrays
[T]
- Hybrid Arrays (sso)
[T,50]
- Fixed Size Arrays
[T:50]
- Unbounded Sized Arrays
[T:expr]
- Unbound Arrays (unsafe)
[T:]
- Contiguous Array Iterators
[T::]
- Dynamic Array Iterators (for lists)
[dyn T::]
- Maps
[K -> V]
- Variants
T1 | T2 | T3
- Tuples
T1 & T2 & T3
- Optionals
?T
- Partials
?partial T
- Bubbling Optionals
!T
- Bubbling Optionals With Error Type
!T | E1 | E2
- Function Pointers
fun ptr (T1, T2, T3) ReturnType
- Function Type + Captures
fun (T1, T2, T3) Return Type
- Ranges
(1..<3)
- Named Tuples
type { a TypeA, b TypeB }
Functions
-
=>
For Implicit Return - Type Deduction for Implicit Return
- Implicit
()
on Function Declaration - Function Overloading By Type
- Function Overloading By Parameter Name
- Template Input Type
^T
, infer from parameters -
fun
keyword in code body
Experience
- Arithmetic Operators
- Statements,
return
/break
/continue
- Control
if
/for
- VLA for Unbounded Sized Arrays
let x [T:expr]
- Copy Suggestion References for Unknown Lifetimes (
© T
or&temp T
) - Match Statement
match x { 1 => value1, 2 => value2 }
- Match Statement Fallback on
operator==
- Match Statement for Unpacking of Variant or Bubbling Optionals
- Undefined Special Value
let x int = undef
- Universal Function Call Syntax,
f(x, y)
=x.f(y)
- Implicit
()
on Expressions,f()
=f
- Implicit Referencing (in place of error)
&expr
- Implicit Dereferencing (in place of error)
@expr
- For/In Loop
- Implicit Destruction
- Custom Destroy Methods
-
block { ... }
To Run Code in New Scope -
exit { ... }
To Run Code at End of Scope - Lambdas
(param1, param2) => { body }
- Explicit Discarding of Information,
= undefined
- Comments
//
and/*
*/
- Ternaries
condition ? yesValue : noValue
- Optional Unpacking (
a ?? b
for default,a!
for force unpacking) - Advanced Optional Unpacking,
a ?? return 0
,a ?? skip
,a ?? panic
- Variable Shadowing in Same Scope
- New Operator
*[char:50]
- Compound Operator
\
,a as b\.c
=(a as b).c
- Result Packing Operator
where (a = b, c = d) f(a, b, c, d)
- Declaration for Mutable References,
takeOptions(let opts)
- Discard for Mutable References
giveOptions(let)
- Select Levels through Keywords
global.f
vsscope.f
- Casting with
as
,a as T
- Parameter Casting (in place of inheritance),
a as T from fieldOfTThatWouldContainA
-
--strict-pointers
safety (no "output" of function contains unowned reference) - Great Refactor (better compiler)
- Split BuilderResult/Unresolved, infer for unpack
- Operations (Call, Add, etc.) Independent of BuilderScope
- Chain Expanding for Alloca, Malloc, Move, Copy, etc. + Predicate
- Reorganize Headers and Source Names and Locations to Something Sane
- Namespace Builder
Standard Library
- Stdin + Stdout
- File IO
- FS Reading
- Memory Managed String Type
Interop
-
import
other Kara Files - C header Interop
- Objective-C header Interop
- LLVM JIT
--interpret
- Binary Output on Major Platforms (macOS, Windows)
- Language Server or Syntax Suggestion Platform
- C Var Args Support
Beyond 1.0
- WebASM interop
- Lifetime Checking (work began here)
- Data Structures as Builtins (BST maps, sets, etc.)
- STL Algorithms,
std::copy
,std::reverse
,std::find
,std::find_if
... - Some Async Construct
- Split Keyword, Separate Future Operations into a callback,
split
- Extra IR Layer, statically infer types of
any
after first assign - Extend Keyword for grouping functions with similar parameters
extend (a int) { f(b int) => a + b }
- Dynamic Dispatch by Type,
interface
s - Explicitly Pure and Impure Functions,
=>
vs->