This is a living document for NAL (Not A Language).
NAL shall be a language with the mindeset of C but safe and syntactically improved. Simpler, more readable, more streamlined. More restrictive but more straight-forward.
Goto GitHub to find this document.
Feel free to contribute. Discussions are what this is all about. It's fun to dream things!
Target groups
- Target groups: Application programmers, Embedded programmers. Programming beginners.
- Not a target group: System programming. Too complicated. No chance this will ever work completely safe.
Iron rules
- keywords do never contain underscores.
- keywords are always lowercase only.
Quality goals
- The language may improve over time with different versions. The language hasn't got the urge to be backwards compatible but strives to do so.
- Compiler error messages must be easy to read.
- Forward declarations not necessary. Someting like C-Header files including comments which are right before defined symbols will be automatically generated upon compilation. Needs proper definition of what is a "header" comment.
- Includes shall be detected or found by the compiler automatically. Requires common rules on how to find implementation/header files. Maybe belongs to the build system. Needs further thinking.
- PIMPL must be prevented. Having no header files would already guarantee this.
- Try to recuce special characters like
!~\<>@|&^./?_%
as much as possible! If a further version adds extensions, better break an old functionality than adding a new character.
- No implicit constructors, desctructors, converters, ... What you code is what you get.
- Do not allow insecure methods. scanf is one of the culprits.
Things to throw away from C
New Concepts
- Range
for
bleed
Keyword
- OOP
- Ownership
- Parameters passed to a method/function are const by default. All parameters can be made non-const by using the
mutable
keyword. If changing a variable and passing it back to the calling scope is required, use the bleed
keyword.
- Parameter passing:
- simple types like i32, f64, letter, .... are passed as values.
- Objects are passed as pointers and are dereferenced automatically in the inner scope.
- For a later version: Add yield and coroutine functionality. Needs a lot of research still as I do not really know anything about it, but it sounds very fascinating.
Other topics
- Namespaces. There are two levels. One is the module which can be defined by the module keyword in one file. Another is based on the project system. One defines in a configuration file what modules belong to what package. Loaded packages can be in a custom namespace.
- Discarded: Type and variable declaration/definition was proposed to put the variable first, then the type. But it introduced lots of syntactical problems.
- Discarded: Can we omit the semicolon. Is optional in other languages, but might server better readability. Maybe only omit it for declarartions inside of a struct/class. Discarded because it helps to keep the code deterministic.
Type-System
- Strong typing.
- New type: "byte" ?
- New integer types: i8, i16, i32, i64, ... u8, u16, u32, u64, ...
- New keyword "letter" for characters. Preferably UTF-8
- New types "f32" and "f64" which repalce float and double.
- New type "bool", new keywords "true" and "false"
- Make array a native type (name under discussion. Some like vec but its frowned upon my most. Namespaces are problematic here as well). Proposition for syntax: array[i32, 6] whereas i32 is a type and 6 is the number of elements in the array. An array is fixed size.
- Type of index variable is size_t in C needs a counterpart in NAL. Needs a printf formatter %i.
- Make string a native type. Suggestion: Use UTF-8 as default. Can be extended later.
- About structs: Replace it with OOP concept.
- All types are automatically typedef'd.
- Casts are NOT allowed. Except: dynamic casts using something like [someObject CastType]. Requires classes to store some kind of a type id given at runtime. Objects are casted automatically to their base type if the base type is requested. Basic types like f32 need converter methods like .toI32().
- Templates are not needed. Extending classes with Interfaces is better. Needs discussion.
- Initialization is the same as the assignment operator. Therefore
i = i32(5)
is the same as i32 i(5)
- nullptr exists. nullptr must be compatible with any object type. Required for dynamic casts.
- Add index/iterator type. Proposition:
[]
.
Other ideas
- Function overloading could be cool. Easy to do with name mangling. But adds complexity. Maybe in a later version.
- Disallow standard parameters.
- No ascii mode for file input or output.
- Promote using less
{}
. Probably not a good idea to remove them all. Make them optional where useful.
- Variables are NOT initialized automatically.
- The operators
&=
|=
and ^=
should be extended to boolean values.
- The operators
&&
and ||
are to be replaced with &
and |
. Due to strong typing, that should not be an issue
- The operators
==
might be replaced with =
. Might.
- Assignment operators have no return value. So no
a = b = c
possible.
- Add named parameters. Optional. Sytax with colons: instead of .dots
- Variable shadowing is an error, not a warning. In constructors, the dot operator helps distinguishing between parameter and member.
- Disallow void*. Add customType with runtime code generation with declareWithType.
- No templates otherwise. Think about it. Have no real idea yet how.
- Variadic initialization. Needs discussion. Probably not
- Variadic arguments ... are not allowed anymore. Define built-in printf.
- exception handling?
- build system included in compiler. Builds "makefiles" automatically. Manages all dependencies of a project.
- compilerflags: target like x86_64-unknow-linux-gnu
Examples submitted by viewers:
Syntax examples of why Rust is worse than C: Link.