From 43266d898bcd01b1a8ea8ff4f3d412046a1a2144 Mon Sep 17 00:00:00 2001 From: Andrew Segavac Date: Mon, 30 Dec 2019 20:58:27 -0700 Subject: [PATCH] updated readme --- README.md | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f59dfdb..6bbed62 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ 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): -* is compiled with a run-time (llvm for convenience + c compatibility) +* is compiled with a run-time (llvm for convenience + c/rust compatibility) * is garbage collected * uses async-await for all IO, with a built-in multi-core scheduler * supports algebraic data types (Result type for errors, Maybe/Optional type for nullables) -* supports parametric polymorphism +* supports parametric polymorphism (generics) * uses struct+traits, rather than classes or stuct+interfaces * has a rich standard library (http server, actor model) * is immutable by default @@ -46,22 +46,20 @@ async func main(args: Array) Int32 { ## Mutability -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 `copy` trait, or simply create a new one with the same data. +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. ``` -let mut foo := Dict{ - 'eggs': 12, - 'bananas': 2, -} -// fine -foo.insert('grapes', 2) +let mut foo = Dict() // constructors always return a mutable reference +foo.insert("eggs", 12) +foo.insert("bananas", 2) +foo.insert("grapes", 2) let bar = foo // bar is not mutable -bar.insert('apples', 4) // fails with compiler error +bar.insert("apples", 4) // fails with compiler error -let mut baz = bar.copy() -baz.insert('apples', 4) // fine +let mut baz = bar.clone() +baz.insert("apples", 4) // fine ``` Methods on a struct must specify if they mutate the struct. @@ -72,7 +70,7 @@ impl Dict { // mutate self here } - func get(self: Dict, key: Key) { + func get(self: Dict, key: Key) Optional { // no need for `mut` } } @@ -90,31 +88,31 @@ The boring standard library solves this by using parametric polymorphism. Contex ``` type HTTPRequest = async func(Ctx, http.Request, mut http.Response) -pub func tracing_middleware(handler: HTTPRequest){ +pub func tracing_middleware(handler: HTTPRequest) HTTPRequest { return async func(ctx: Ctx, req: http.Request, resp: mut http.Response) { - with tracing.NewSpan(ctx, 'request_duration') { + with tracing.Span(ctx, "request_duration") { await handler(ctx, req, resp) } } } -pub func auth_middleware(handler: HTTPRequest, scope: Str){ +pub func auth_middleware(handler: HTTPRequest, scope: Str) HTTPRequest { return async func(ctx: Ctx, req: http.Request, resp: mut http.Response) { if ctx.has_scope(scope) { await handler(ctx, req, resp) } await resp.set_status(403) - await resp.write('missing scope') + await resp.write("missing scope") } } -pub func cancel_middleware(handler: HTTPRequest){ +pub func cancel_middleware(handler: HTTPRequest) HTTPRequest { return async func(ctx: Ctx, req: http.Request, resp: mut http.Response) { if !(await ctx.is_cancelled()) { // check cancel token await handler(ctx, req, resp) } await resp.set_status(400) - await resp.write('cancelled') + await resp.write("cancelled") } } ``` @@ -123,18 +121,22 @@ for the above examples, you would pass a context type that implements all three ## Monadic function modifiers -Boring uses function modifiers to implement functionality like `async/await` and `coroutines`. These function by rewriting the AST prior to compilation. The table below describes the modifiers currently available. +Boring uses function modifiers to implement functionality like `async/await` and `coroutines`. These function by [rewriting the code into a state machine](https://tmandry.gitlab.io/blog/posts/optimizing-await-1/) prior to compilation. The table below describes the modifiers currently available. |Type|Change To Return Type|Introduces to Scope| |---|---|---| -|async|`Promise`|await| -|coroutine|`FirstReturnType,func(Next,Params)...`|yield| -|errors|`Result`|?| +|`async`|`Promise`|`await`| +|`coroutine`|`FirstReturnType,func(Next,Params)...`|`yield`| +|`error`|`Result`|`?`| ## Import System -Similar to python, folders/files represent the `.` seperated import path though relative imports are *not* supported. Exported values must be marked with `pub`. All imports take the form: +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: ``` import package.path as local_name + +pub struct MyStruct { + id: Int +} ```