updated readme
This commit is contained in:
75
README.md
75
README.md
@@ -1,25 +1,56 @@
|
||||
# Boring Lang Proposal
|
||||
|
||||
**NOTE: This repo is a work in progress as I learn compiler writing, I may abandon this.**
|
||||
**NOTE: The rust code in the repo is temporary abandoned while I finish the python POC, this will eventually be moved to rust**
|
||||
# Boring Lang
|
||||
|
||||
The Boring Programming Language (Boring-Lang) is an attempt to create an easy, productive, general purpose programming language that makes as few interesting choices as possible while still being in line with modern concepts in programming languages.
|
||||
|
||||
The language (wish list):
|
||||
The language:
|
||||
* is compiled with a run-time (llvm for convenience + c/rust compatibility)
|
||||
* has managed memory (via weak pointers and automatic reference counting)
|
||||
* uses async-await for all IO, with a built-in multi-core scheduler
|
||||
* has managed memory (via strong/weak pointers and automatic reference counting)
|
||||
* uses async-await for all IO, with a built-in multi-core scheduler (tokio)
|
||||
* supports algebraic data types (Result type for errors, Maybe/Optional type for nullables)
|
||||
* supports parametric polymorphism (generics) with higher kinded types
|
||||
* uses struct+traits, rather than classes or stuct+interfaces
|
||||
* has a rich standard library (similar scale to python or go)
|
||||
* is immutable by default
|
||||
* is sandboxed by default
|
||||
|
||||
It's a middle-ground of Rust, Golang, Swift, Typescript, and Python. The goal is not to break any new ground in PL theory, or even create a language anyone likes, but rather to create a language with as few deal-breakers as possible for maximum day-to-day industrial programming ergonomics.
|
||||
|
||||
This language is under active development, progress will be marked here as the language is developed.
|
||||
|
||||
- [x] Functions
|
||||
- [x] Int Literals
|
||||
- [x] Float Literals
|
||||
- [x] Block expression
|
||||
- [x] Return keyword
|
||||
- [x] Normal assignment
|
||||
- [x] Structs
|
||||
- [x] Define
|
||||
- [x] Literal
|
||||
- [x] Getter
|
||||
- [x] Setter
|
||||
- [x] Type Aliases
|
||||
- [ ] Methods
|
||||
- [x] Declaration
|
||||
- [ ] Use
|
||||
- [ ] Traits
|
||||
- [ ] Generics
|
||||
- [ ] Basic
|
||||
- [ ] Higher kinded types
|
||||
- [ ] Control Flow
|
||||
- [ ] If
|
||||
- [ ] While
|
||||
- [ ] For
|
||||
- [ ] Enums
|
||||
- [ ] Lambdas
|
||||
- [ ] Async-Await
|
||||
- [ ] Imports
|
||||
- [ ] Visibility
|
||||
- [ ] Const / Mut
|
||||
|
||||
It's basically a middle-ground of Rust, Golang, Swift, Typescript, and Python. The goal is not to break any new ground in PL theory, or even create a language anyone likes, but rather to create a language with as few deal-breakers as possible for day-to-day industrial programming.
|
||||
|
||||
## Http Server Example
|
||||
|
||||
```
|
||||
```rust
|
||||
import net.http as http
|
||||
import logging as logging
|
||||
import json as json
|
||||
@@ -54,7 +85,7 @@ async fn main(args: Vec[Str], os: OS): I32 {
|
||||
|
||||
All variables are immutable by default, to make them mutable use the `mut` keyword. Once a variable becomes immutable it cannot become mutable again. If you need it to become mutable, either implement the `clone` trait, or simply create a new one with the same data.
|
||||
|
||||
```
|
||||
```rust
|
||||
let mut foo = Dict[String, Int32].new(); // constructor returns a mutable reference
|
||||
foo.insert("eggs", 12);
|
||||
foo.insert("bananas", 2);
|
||||
@@ -70,7 +101,7 @@ baz.insert("apples", 4); // fine
|
||||
|
||||
Methods on a struct must specify if they mutate the struct.
|
||||
|
||||
```
|
||||
```rust
|
||||
impl Dict[Key: Hashable, Value] {
|
||||
fn insert(self: mut Self, key: Key, value: Value) {
|
||||
// mutate self here
|
||||
@@ -91,10 +122,10 @@ Context is an exceptionally useful feature in golang, but a common complaint is
|
||||
|
||||
The boring standard library solves this by using parametric polymorphism. Context is by default an empty object passed through the chain, and each function/set of context parameters is an additional trait condition applied at compile time.
|
||||
|
||||
```
|
||||
type HTTPRequest[Ctx: Context] = async fn(Ctx, http.Request, mut http.Response)
|
||||
```rust
|
||||
type HTTPRequest[Ctx: Context] = async fn(Ctx, http.Request, mut http.Response);
|
||||
|
||||
pub fn tracing_middleware[Ctx: Tracing](handler: HTTPRequest[Ctx]) HTTPRequest {
|
||||
pub fn tracing_middleware[Ctx: Tracing](handler: HTTPRequest[Ctx]): HTTPRequest {
|
||||
return async fn(ctx: Ctx, req: http.Request, resp: mut http.Response) {
|
||||
with tracing.Span(ctx, "request_duration") {
|
||||
await handler(ctx, req, resp);
|
||||
@@ -102,7 +133,7 @@ pub fn tracing_middleware[Ctx: Tracing](handler: HTTPRequest[Ctx]) HTTPRequest {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn auth_middleware[Ctx: Auth](handler: HTTPRequest[Ctx], scope: Str) HTTPRequest {
|
||||
pub fn auth_middleware[Ctx: Auth](handler: HTTPRequest[Ctx], scope: Str): HTTPRequest {
|
||||
return async fn(ctx: Ctx, req: http.Request, resp: mut http.Response) {
|
||||
if ctx.has_scope(scope) {
|
||||
await handler(ctx, req, resp);
|
||||
@@ -112,7 +143,7 @@ pub fn auth_middleware[Ctx: Auth](handler: HTTPRequest[Ctx], scope: Str) HTTPReq
|
||||
};
|
||||
}
|
||||
|
||||
pub fn cancel_middleware[Ctx: Cancel](handler: HTTPRequest[Ctx]) HTTPRequest {
|
||||
pub fn cancel_middleware[Ctx: Cancel](handler: HTTPRequest[Ctx]): HTTPRequest {
|
||||
return async fn(ctx: Ctx, req: http.Request, resp: mut http.Response) {
|
||||
if !(await ctx.is_cancelled()) { // check cancel token
|
||||
await handler(ctx, req, resp);
|
||||
@@ -129,7 +160,7 @@ for the above examples, you would pass a context type that implements all three
|
||||
|
||||
Similar to python, folders/files represent the `.` seperated import path, but relative imports are *not* supported. Exported values must be marked with `pub`. All imports take the form:
|
||||
|
||||
```
|
||||
```rust
|
||||
import package.path as local_name
|
||||
|
||||
pub type MyStruct struct {
|
||||
@@ -143,7 +174,7 @@ pub type MyStruct struct {
|
||||
|
||||
`if` is an expression in boring-lang, with the last expression in a block being the return value.
|
||||
|
||||
```
|
||||
```rust
|
||||
let a = if true {
|
||||
4
|
||||
} else {
|
||||
@@ -160,7 +191,7 @@ Conditions do not require parenthesis and *must* evaluate to the Boolean type.
|
||||
|
||||
Boring-lang supports `for` and `while` loops, with `for` having an `async` variant. `while` loops require an expression of Boolean type, while `for` loops require an expression that implements the `Iter` or `AIter` traits.
|
||||
|
||||
```
|
||||
```rust
|
||||
let mut i = 0;
|
||||
while i < 100 {
|
||||
i = i + 1;
|
||||
@@ -179,7 +210,7 @@ async for result in paginated_list {
|
||||
|
||||
`continue` and `break` work similar to other languages.
|
||||
|
||||
```
|
||||
```rust
|
||||
while true {
|
||||
break; // do nothing
|
||||
}
|
||||
@@ -201,7 +232,7 @@ for i in range(100) {
|
||||
|
||||
return async with db.transation(ctx) as t {
|
||||
await t.insert(ctx, record); // returns result type
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### `return`
|
||||
@@ -218,7 +249,7 @@ let result = match number {
|
||||
1 => 'foo',
|
||||
3 => 'bar',
|
||||
_ => 'baz',
|
||||
}
|
||||
};
|
||||
|
||||
// result = 'bar'
|
||||
```
|
||||
|
||||
26
notes.txt
26
notes.txt
@@ -30,29 +30,3 @@ class TypeUsage:
|
||||
|
||||
if / match return never if all blocks return never;
|
||||
blocks propagate never except at the function level;
|
||||
|
||||
|
||||
TODO:
|
||||
* ~Float Literals~
|
||||
* ~Block expression~
|
||||
* ~Return keyword~
|
||||
* ~Normal assignment~
|
||||
* ~Structs~
|
||||
* ~Define~
|
||||
* ~Literal~
|
||||
* ~Getter~
|
||||
* ~Setter~
|
||||
* ~Type Aliases~
|
||||
* Methods
|
||||
* ~Declaration~
|
||||
* Use
|
||||
* Traits
|
||||
* Generics
|
||||
* Enums
|
||||
* Arrays
|
||||
* Strings
|
||||
* Lambdas
|
||||
* Async
|
||||
* Imports
|
||||
* Visibility
|
||||
* Const / Mut
|
||||
|
||||
Reference in New Issue
Block a user