At the risk of vanity, here are Ki's influences.


Ki's variant structs are Ada's discriminated records, and ranges come from Ada too. Python, of course, has ranges but they're not specific types like Ada's ranges. The loop keyword is also from Ada.


Ki is largely a reaction to C, and because Ki primarily compiles to C its constructs were always conceived in a C context. Many C programmers say they can see the assembly that would be generated by C code, and while that's at least a little suspect these days, we designed Ki while always considering what the underlying C code would look like.


While I fought it, Ki's parameterized types and functions are essentially C++'s templates. Static functions are also from C++, despite being pretty common (Java, Python, etc.). Unique, shared and weak pointers as well as references are from C++, even though they're used to implement Rust's memory model.


var comes from JavaScript. === and !== are also from JavaScript and replace is and is not from Python.


Go's zero-values are the basis of Ki's default values in structs. Ki's const declarations were inspired by Go's. And, again while I fought it, Ki eventually adopted Go's "name type" ordering for struct fields, functions, and variable bindings, which is reversed from C. Ki's types are similar to Go's types as well.


Ki's component was inspired by experience working with Lua. Ki's primitive/type/component datatype system is designed to associate functions with data, which is "composition over inheritance", or really "functionality instead of taxonomy". Most languages that take this approach use "interfaces" (Go, Java) or "traits" (Rust); Ki calls these "components".

I settled on components over inheritance after implementing a widget system in Lua using a traits library. While it was lightweight and refreshing to think in terms of functionality instead of category or hierarchy, I was frequently frustrated that my traits required fields that my underlying data structures were missing. Thus :requirements in components was born.

Ki's mod comes from explicitly exporting tables as modules in Lua.


The for-in loop comes from Python. Python's list of special methods (__iter__, __contains__ and so on) was extraordinarily helpful. Ki's generators and list comprehensions come from Python, as does self.

Python's properties inspired get, set, and pred; I wanted these badly when working with Lua. I'm somewhat sympathetic to the argument that field accesses are cheap, so field accesses that aren't cheap shouldn't look like field accesses, but the alternatives are either a mishmash of convenient field accesses and inconvenient get_* and set_* everywhere, or

Projects tend to bend towards getters and setters anyway, and with this reality in mind, Ki's get, set, and pred allow for convenience, flexibility, and consistency, at the cost of some potential surprise, which can easily be avoided with basic documentation.


Ki's memory model is essentially Rust's. There are some slight differences but for the most part, Rust did the (astonishing) legwork here.