OMG, another programming language? Whyyy??

Strictly Typed

  • Strict type checking including for value type aliases (e.g. if typedefs of ints in C were new strictly checked type names)
  • Subtyping and discriminated union types for polymorphism without inheritance, and covariant return types
  • Data and functions are freely associated; no classes
  • Data structures have no visibility modifiers (no data hiding)
  • No inheritance

Better Array Types

  • Strings and arrays have known, fixed lengths and may be queried with the built-in function len()
  • Strings and arrays are not "just pointers" and may be value compared using the standard equality operator, ==


  • Code may be freely associated with a module, by name, by placing a module declaration in the file
  • Modules create python-style namespaces, so the function fun in the io module may be called with in other modules
  • Directory structure and filenames do not dictate the module namespaces (unlike in python).

Crescent is for C-like imperative programming but with modernized syntax and program organization.

Development Maturity Level: Pet Project

But, there’s a website? This website, like the language, is a work-in-progress. This site shares the current thinking about various language constructs and philosophies. It’s a way to keep track of things. It just happens to be in the open.


Basic Main Function

Here’s a bit more than just printing “Hello, World!”

const pl_name str = "Crescent";
var verbose bool = false;

fn main(args str[]) i32 {
    print("Hello, World!");
    print("Programming language: ", pl_name);
    print("Number of arguments: ", len(args));

    foreach (arg in args) {
        print("Argument: ", arg);
        if (arg == "-v") {
            verbose = true;

    return 0;

This simple program demonstrates several language attributes:

Pre-defined Types (Intrinsics)
module _lang;

type unit;
type any;
type bool;
type u8;
type u16;
type i16;
type u32;
type i32;
type u64;
type i64;
type f32;
type f64;
type str;

These types are pre-defined by Crescent but are also declared in the _lang module for documentation purposes (at least for the moment). If you are familiar with C or Rust the names will be familiar, if not:

You can declare a variant type in Crescent with type type_name; These ones just happen to have compiler-provided constructors. For instance, bool is a variant type (tagged union) of two unit types,true and false.


The source code in every file is associated with some module. The module association may be declared with module module_name;. There are two specially handled modules: _lang, and _app

Modules do not have data-hiding features and cannot be "sealed". Crescent does however have annotations and an annotation may be used to declare globals and function names as "private" but this merely keeps the corresponding code from being included in generated user (API) documentation. It also serves as an indicator to those modifying or extending a module to tread carefully.



Sins to be Avoided