OMG, another programming language? Are you serious with this??
- Do you unapologetically prefer low-level systems programming in C, but just wish it had a few modern "creature comforts" regarding syntax and safety checks?
- Do you like the Rust and Ada brochures, but when you get down to writing programs in them, just do not experience the joy of creation? Do you find that there is too much friction to do most of basic things?
- Want to easily create, use, and extend modules (packages)?
Strictly Typed
- Strict type checking including for value type aliases (e.g. if typedefs of ints in C were new strictly checked type names).
- Variables maintain their type information at runtime and are not ellided by the compiler.
A variable's type may be tested with the
isoperator e.g.(something is str) - Subtyping and discriminated union types for polymorphism and covariant return types but without inheritance.
- 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 are not "just pointers" and may be value compared using the standard
equality operator,
==
Modules
- Code may be freely associated with a module, by name, by placing a module declaration in a file.
- Modules create python-style namespaces, so the function fun in the io
module may be called with
io.fun()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.
Examples
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:
- The prototype for the
main()function for any program (entry). - Constant and variable global declarations.
- Type names for intrinsic types like integers, booleans, and strings.
- Variadic function arguments. E.g.
print() - String value comparison using
== - Simple iteration over arrays using
foreach (element in array)
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:
- Numeric types have a prefix and the number of bits in the representation:
- The u prefix indicates an unsigned integer
- The i prefix indicates a signed integer
- The f prefix indicates a floating point number
unitis a unit type (used likevoidin C)anyis a variant that includes all defined types (including user-defined); it can be approximately thought of asvoid*in C but with the corresponding type information intact.stris the built-in string type.
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
- Globals and functions defined in
_langare always in scope, and are referenced without the_langprefix. And yes, this means you can add to the language (or global scope, if you will) this way, but discretion is advised. - Files without a module declaration are implicitly associated with the
_appmodule.
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.
...
- Assignment operator overloading. "Move" and "forward" semantics.