Skip to content

Latest commit

 

History

History
136 lines (121 loc) · 5.98 KB

README.md

File metadata and controls

136 lines (121 loc) · 5.98 KB

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 (&copy 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 vs scope.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, interfaces
  • Explicitly Pure and Impure Functions, => vs ->