Compare commits
1 commit
main
...
move-notic
Author | SHA1 | Date | |
---|---|---|---|
Alex Bethel | ed4e98891c |
133
README.md
133
README.md
|
@ -1,134 +1,3 @@
|
||||||
<!--
|
|
||||||
|
|
||||||
Please keep this document correctly word-wrapped at 70 columns and
|
|
||||||
with no trailing whitespace or blank lines at the end! Merge requests
|
|
||||||
with modifications to this document will be not be accepted until it
|
|
||||||
is formatted correctly! ~~abb
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Drim
|
# Drim
|
||||||
|
|
||||||
Drim is a programming language designed to have the very high-level
|
Drim is now hosted at [[https://codeberg.org/gkgoat/drim]].
|
||||||
ergonomics and provable correctness of a purely functional language,
|
|
||||||
while maintaining speed using strictly-controlled, deterministic
|
|
||||||
memory management. The language is capable of compiling to C (and
|
|
||||||
possibly other languages in the future), allowing for maximum
|
|
||||||
portability without having to write a new backend for the compiler for
|
|
||||||
every possible target; also, the compiler and tooling will eventually
|
|
||||||
be rewritten in Drim to allow for maximum portability.
|
|
||||||
|
|
||||||
Syntactically, the language primarily resembles a mixture between
|
|
||||||
standard ML and Rust; the language always ignores whitespace.
|
|
||||||
|
|
||||||
Drim is licensed under the GNU General Public License, version 3 or
|
|
||||||
later. See the `LICENSE` file for details.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```
|
|
||||||
// Calculates the nth fibonacci number.
|
|
||||||
def fibonacci (n: U32) : U32 = match n {
|
|
||||||
0 => 0,
|
|
||||||
1 => 1,
|
|
||||||
n => fibonacci (n - 2) + fibonacci (n - 1),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Prompts the user for a number n, and prints the Fibonacci numbers up
|
|
||||||
// to n.
|
|
||||||
def fibPrompt = do {
|
|
||||||
print "Enter a number: ";
|
|
||||||
num <- read <$> getLine;
|
|
||||||
sequence_ (print . fibonacci <$> (0 .. num));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Program entry point.
|
|
||||||
def main : IO ()
|
|
||||||
= fibPrompt;
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that type annotations are always optional; here they're given for
|
|
||||||
`fibonacci` and `main` for illustrative purposes, but omitted for
|
|
||||||
`fibPrompt` (for which the compiler infers the return type `IO ()`).
|
|
||||||
|
|
||||||
## Tools
|
|
||||||
|
|
||||||
This repository contains the following tools:
|
|
||||||
- `drimc-rs`, the Stage-1 Drim compiler, written in Rust. This can be
|
|
||||||
used as a binary with a fairly standard compiler CLI, or as a
|
|
||||||
library for use in other Rust programs.
|
|
||||||
|
|
||||||
The following tools do not exist yet, but are planned:
|
|
||||||
- `drimc`, the main Drim compiler written in Drim. This program
|
|
||||||
supports a superset of the behavior of `drimc-rs`, and exposes a
|
|
||||||
library that can be used by other Drim programs in addition to a the
|
|
||||||
compiler CLI.
|
|
||||||
- `drim`, the interactive Drim interpreter, a wrapper around `drimc`.
|
|
||||||
- `drimd`, the Language Server Protocol (LSP) server for Drim code
|
|
||||||
support in editors, supporting definition peeking and lookup,
|
|
||||||
renaming variables and modules, etc.
|
|
||||||
- `drimfmt`, the standard formatter for Drim code; all Drim code used
|
|
||||||
in this repository must be formatted with `drimfmt`, and its use is
|
|
||||||
recommended for other projects.
|
|
||||||
- `drimdoc`, the documentation generator.
|
|
||||||
- `drim-mode`, an Emacs mode for editing Drim code, supporting syntax
|
|
||||||
highlighting, automatic indentation, some basic keybindings for
|
|
||||||
common tasks, Emacs-side LSP integration for communicating with
|
|
||||||
`drimd`, and a collection of `yasnippet` snippets for inserting
|
|
||||||
common Drim constructs.
|
|
||||||
- `drim-vsc`, Visual Studio Code plugins and tools for editing
|
|
||||||
AlexScript code.
|
|
||||||
- `drim-vim`, tools and configuration files for optimizing Vim
|
|
||||||
and Neovim for editing Drim code.
|
|
||||||
|
|
||||||
## Language features
|
|
||||||
|
|
||||||
The language is mostly influenced by Rust and Haskell: it has strict
|
|
||||||
safety requirements and borrow-checked memory management like that of
|
|
||||||
Rust, but its syntax and type system are similar to those of Haskell.
|
|
||||||
|
|
||||||
Some features the language will most likely have:
|
|
||||||
- All functions are pure by default; side effects are chained together
|
|
||||||
using an `IO` monad.
|
|
||||||
- Despite the language's purity, expressions will be strictly
|
|
||||||
evaluated to provide more programmer control.
|
|
||||||
- Different monads represent different levels of safety, and can be
|
|
||||||
converted using functions marked as `UNSAFE`. The intention is that
|
|
||||||
code can be audited by manually checking that all the `UNSAFE`
|
|
||||||
transformations are sound, and code that contains no `UNSAFE`
|
|
||||||
function calls are guaranteed to satisfy varying definitions of
|
|
||||||
soundness:
|
|
||||||
- The `IO` monad represents computations that might have side
|
|
||||||
effects on the real world. If a computation of type `IO` is known
|
|
||||||
by the programmer to not have side effects on the real world, then
|
|
||||||
it can be converted to a pure computation using the standard
|
|
||||||
library function `UNSAFE_assertPure : IO a -> a`.
|
|
||||||
- The `MemoryUnsafe` monad represents computations that might read
|
|
||||||
from or write to memory that is not allocated correctly: for
|
|
||||||
example, `readPtr`, which reads from a raw pointer, is of type
|
|
||||||
`MemoryUnsafe a` because the pointer is not known to be valid. If
|
|
||||||
a computation has been confirmed to be safe by the programmer, it
|
|
||||||
can be converted to an `IO` computation using
|
|
||||||
`UNSAFE_assertMemorySafe : MemoryUnsafe a -> IO a`.
|
|
||||||
- Further safety monads may be added in the future.
|
|
||||||
- The language achieves good performance by guaranteeing a number of
|
|
||||||
optimizations:
|
|
||||||
- Since the language uses a linear type system, garbage collection
|
|
||||||
is not done; instead, values are stored on the stack unless
|
|
||||||
explicitly declared to be on the heap, and heap-stored values are
|
|
||||||
cleaned up at deterministic points as calculated at compile time.
|
|
||||||
- Functions of type `Fn t -> t` are optimized into functions that
|
|
||||||
operate on pointers to `t`, i.e., notionally, `Fn (*mut t) -> ()`,
|
|
||||||
where `*mut t` is a mutable pointer to a type `t`.
|
|
||||||
- Types that contain an optional, non-null pointer like `Option (Box
|
|
||||||
a)`, `Option (Ref a)`, etc., are optimized into nullable pointers.
|
|
||||||
- Since the language has no loops, the compiler guarantees
|
|
||||||
optimization of tail-call recursion to loops on all functions, as
|
|
||||||
is standard in functional languages.
|
|
||||||
|
|
||||||
## Compilation
|
|
||||||
|
|
||||||
When invoked with no flags, Drim by default compiles source code
|
|
||||||
directly to code that is valid C and C++, then calls the system C
|
|
||||||
compiler to generate an object file, then calls the system linker to
|
|
||||||
generate an executable file.
|
|
||||||
|
|
Loading…
Reference in a new issue