1. Duangle
  2. Liminal
  3. nonelang


nonelang /

Filename Size Date modified Message
276 B
added distribution script
1.1 KB
added license
4.8 KB
small change to README.md
538 B
- new globals have to be registered with __global before use
43 B
removed llvmapi
457 B
organizing source directory to match system directory


The Best Programming Language is None

None (a backronym for None's Only Nested Expressions), also called Nonelang for clarity, is a young, powerful, convenient, extensible and performant programming language and infrastructure. It is developed alongside our game in production, NOWHERE (we have a Patreon going if you would like to support us).

Here are some reasons to use None for your next production:

  • Built on top of LuaJIT and LLLua for multi-stage programming features and friction-free interoperability with Lua and C libraries.
  • Combines the power of Scheme with the convenience of Python, Lua or Javascript and the performance of C.
  • Offers both dynamically typed managed memory for high level control and fast prototyping of ideas and statically typed manual memory management for highly performant inner loops.
  • Both a code generator and compiler (with embedded LLVM and clang). Ship it with your product for deep modding support or use it to build independent binaries.
  • Embeddable in your LuaJIT projects.
  • Uses symbolic expression syntax, a data interchange format lighter than JSON.
  • Use programmable macros (hygienic and plain) to quickly draft your own domain specific languages, from state machines over config files to shader languages.
  • Symmetric code serialization: automated processing, reformatting and conversion of source code is trivial compared to C++.
  • Realize your own ideas for syntax sugar. A class system, struct-of-arrays syntax, a using keyword and many more useful features are already provided.
  • Open Source MIT licensed, so you can ship in whatever way you like.

This is why you might not want to use None:

  • You run Windows (support is in progress).
  • You really need a tutorial and reference documentation to dive in (documentation is in progress).
  • You're just fine with the performance, the expressivity, the introspection features and the convenience level of the language you use.
  • You prefer to use mature languages with a metropolitan infrastructure.
  • You need an interactive graphical debugger (we might get one, eventually).


Click here for a short example, demoing syntax and basic language features.


Documentation is early work in progress and hosted at readthedocs.org.


If you want to run None from source, you'll need an installation of LuaJIT. Compilation features depend on LLLua.

To run the None command line interpreter, launch the none.sh or none.bat scripts in the root directory without arguments.

There are also examples in the lib/none/testing folder you can look at.

You can use None as a module in your LuaJIT project, but search paths must be prepared. See src/none/launcher.lua for details.

Help & Support

If you have issues or questions, you can always write a mail. We also run the #nonelang IRC channel on Freenode.

Frequently Asked Questions

Where can I find None bindings for my favorite library?

Most of the time you won't need specific bindings for None, if there's already a binding for LuaJIT available. Even better yet: because LLLua embeds clangs parser, you can often directly include C headers and call into shared libraries without requiring bindings.

Why would one need to choose between a dynamic or static function? Why not always use static functions, as they should be faster?

There are two good reasons for this. The first reason is that dynamic functions in None take the role of generics or templates in other languages like C++. Think of it as a scriptable live compiler. The second reason is that dynamic functions are great for prototyping. During prototyping, you only want to think about the particular problem you want to solve, without having to consider type signatures and data model at the same time. Only later when the solution works and performance is a requirement can you then transition the function to a static one. As the notation for both styles is nearly identical (minus the signatures) and functions of both modes can cross-call each other transparently, scaling from dynamic to static code is straightforward.