diff options
author | JJ | 2023-07-10 05:56:44 +0000 |
---|---|---|
committer | JJ | 2023-07-10 06:39:32 +0000 |
commit | fbe825e6d74a08b1a4ffada6c9a0934d7fb0d19f (patch) | |
tree | d741eeba0c0676bc6ee06458dcd6baa59e44e9a2 | |
parent | 86f59f9ebb36c322bedd89dde1e4bf813f0f6372 (diff) |
basic usage w/o examples
-rw-r--r-- | BASIC.md | 119 | ||||
-rw-r--r-- | README.md | 19 |
2 files changed, 129 insertions, 9 deletions
diff --git a/BASIC.md b/BASIC.md new file mode 100644 index 0000000..aa984ac --- /dev/null +++ b/BASIC.md @@ -0,0 +1,119 @@ +# Basic Usage of Puck + +```puck +``` + +Mutable variables are declared with `var`. +Immutable variables are declared with `let`. +Compile-time evaluated immutable variables are declared with `const`. + +Comments are declared with `#`. +Documentation comments are declared with `##`. +Multi-line comments are declared with `#[ ]#` and may be nested. + +Type annotations on variable declarations follow the name with `: Type` and are typically optional. The compiler is quite capable of variable inference. + +The type system is comprehensive, and complex enough to [warrant its own document](TYPES.md). + +```puck +``` + +Functions are declared with the `func` keyword, followed by the function name, followed by an (optional) list of parameters surrounded in parenthesis, followed by a type annotation. Functions may be prefixed with one or more of the following modifiers: +- `pub`: exports the function for use by external files +- `pure`: denotes a function as a "pure function", lacking side effects, i.e. IO or nondeterminism or parameter mutability +- `async`: marks a function as asynchronous which may only be called by other asynchronous functions or with the `await` keyword +<!-- - `total`: idk --> +<!-- - more?? converter?? idk todo --> + +<!-- There is an explicit ordering of these prefixes: everything << `pub` << `pure`. `pub` and `pure` are idk what i'm going for here is `async` and everything else should be macros providable by libraries. so `async` functions can be rewritten to use cps, etc depending on what you do, `await` is just a function that converts an `async T` to a `T`, `suspend`, `resume` are functions, etc. --> + +A list of parameters, surrounded by parentheses and separated by commas, may follow the function name. These are optional and a function with no parameters may be followed with `()` or simply nothing at all. More information on function parameters (and return types) is available in the [type system overview](TYPES.md). + +Type annotations on function declarations follow the name and parameters (if any) with `: Type` and are typically required. The compiler is not particularly capable of function type inference (and it is good practice to annotate them anyway). + +Uniform function call syntax (UFCS) is supported: and so arbitrary functions with compatible types may be chained with no more than the `.` operator. + +<!-- All assignments may be overridden, but overriding values outside of shadowing (assigning the value of an immutable parameter to a mutable variable) will be a compiler warning. --> + +```puck +``` + +Boolean logic and integer operations are standard and as one would expect out of a typed language: `and`, `or`, `xor`, `not`, `shl`, `shr`, `+`, `-`, `*`, `/`, `<`, `>`, `<=`, `>=`, `div`, `mod`, `rem`. Notably: +- the words `and`/`or`/`not`/`shl`/`shr` are used instead of the symbolic `&&`/`||`/`!`/`<<`/`>>` +- integer division is expressed with the keyword `div` while floating point division uses `/` +- `%` is absent and replaced with distinct modulus and remainder operators +- boolean operators are bitwise and also apply to integers and floats +- more operators are available via the standard library + +Term in/equality is expressed with `==` and `!=`. Type in/equality is expressed with `is` and `isnot` (more on this in the [types document](TYPES.md)). Set logic is expressed with `in` and `notin`, and is applicable to not just sets but collections of any sort. + +String concatenation uses `&` rather than overloading the `+` operator (as the complement `-` has no natural meaning for strings). Strings are also unified and mutable. More details can be found in the [type system overview](TYPES.md). + +```puck +``` + +Basic conditional control flow is standard via `if`, `elif`, and `else` statements. + +There is a distinction between statements, which do not produce a value but rather only execute computations, and expressions, which evaluate to a value. Several control flow constructs - conditionals, block statements, and pattern matches - may be used as both statements and expressions. + +The special `discard` statement allows for throwing an expression's value away. On its own, it provides a no-op. All (non-void) expressions must be handled: however, a non-discarded expression at the end of a scope functions as an implicit return. This allows for significant syntactic reduction. + +```puck +``` + +Three types of loops are available: `while` loops, `for` loops, and infinite loops (`loop` loops). While loops take a condition that is executed upon the beginning of each iteration to determine whether to keep looping. For loops take a binding (which may be structural, see pattern matching) and an iterable object and will loop until the iterable object is spent. Infinite loops are, well, infinite and must be manually broken out of. + +There is no special concept of iterators: iterable objects are any object that implements the Iterable interface (more on those in [the type system document](TYPES.md)), that is, provides a `self.next()` function returning an Optional type. For loops desugar to while loops that unwrap the result of the `next()` function and end iteration upon a `None` value. While loops, in turn, desugar to infinite loops with an explicit conditional break. + +The `break` keyword immediately breaks out of the current loop. +The `continue` keyword immediately jumps to the next iteration of the current loop. +Loops may be used in conjunction with blocks for more fine-grained control flow manipulation. + +```puck +``` + +Blocks provide arbitrary scope manipulation. They may be labelled or unlabelled. The `break` keyword additionally functions inside of blocks and without any parameters will jump out of the current enclosing block (or loop). It may also take a block label as a parameter for fine-grained scope control. + +All forms of control flow ultimately desugar to continuations: https://github.com/nim-works/cps/tree/master/docs + +```puck +``` + +Exhaustive structural pattern matching is available, particularly useful for tagged unions, and discussed in detail in the [types document](TYPES.md). This is frequently a better alternative to a series of `if` statements. + +```puck +``` + +I am undecided on how the import/module system will work and particularly how it will play into the type system. UFCS *will* be supported. todo + +```puck +``` + +Compile-time programming may be done via the previously-mentioned `const` keyword: or via `static` blocks. All code within a `static` block is evaluated at compile-time and all assignments made are propagated to the compiled binary. As a result, `static` blocks are only available in the global context (not within functions). + +Compile-time programming may also be intertwined in the codebase with the use of the `when` statement. It functions similarly to `if`, but may only take a static operation as its parameter, and will directly replace code accordingly at compile-time. The `else` statement is overloaded to complement this. + +```puck +``` + +Metaprogramming is done via compile-time introspection on the abstract syntax tree. +Two distinct language constructs of differing complexity are provided: templates for raw substitution, and macros for direct manipulation of the abstract syntax tree. These are complex, and more details may be found in the [metaprogramming document](METAPROGRAMMING.md). + +```puck +``` + +Error handling is typically done via explicitly matching upon Optional and Result values (with the help of the `?` operator), but such functions can be made to explicitly throw exceptions (which may then be caught via `try`/`catch`/`finally` or thrown with `raise`) with the help of the `!` operator. This is complex and necessarily verbose, although a bevy of helper functions and syntactic sugar are available to ease the pain. More details may be found in [error handling overview](ERRORS.md). + +```puck +``` + +Threading support is complex and regulated to external libraries (with native syntax via macros). OS-provided primitives will likely provide a `spawn` function, and there will be substantial restrictions for memory safety. I haven't thought much about this. + +Async support is complex and relegated to external libraries (with native syntax via macros). More details may be found in the [async document](ASYNC.md). It is likely that this will look like Zig, with `async`/`await`/`suspend`/`resume`. + +Effects are complex and relegated to external libraries (with native syntax via macros). More details may be found in the [effects document](EFFECTS.md). + +```puck +``` + +Details on memory safety, references and pointers, and deep optimizations may be found in the [memory management overview](MEMORY_MANAGEMENT.md). This intertwines deeply with the [type system](TYPES.md). @@ -45,21 +45,22 @@ Why not Koka? ## How do I learn more? - The [basic usage](BASIC.md) document lays out the fundamental grammar of Puck. -- The [syntax](SYNTAX.md) document provides a deeper look into the syntax choices. +- The [syntax](BASIC.md) document provides a deeper look into the syntax choices made. - The [grammar](GRAMMAR.md) document provides a formal grammar for Puck, which the parser is based upon. -- The [type system](TYPES.md) document gives an in-depth analysis of Puck's extensive type system, and its relationship to classes and other abstractions. -- The [memory management](MEMORY_MANAGEMENT.md) document gives an overview of Puck's memory model: which is considered a mashup of the models pioneered by Lobster, Rust, and Nim. -- The [effect system](EFFECTS.md) document gives a description of Puck's effects system: and how it ties into asynchronous code and exceptions. +- The [type system](TYPES.md) document gives an in-depth analysis of Puck's extensive type system. <!-- and its relationship to classes and other abstractions. --> +- The [memory management](MEMORY_MANAGEMENT.md) document gives an overview of Puck's memory model. <!-- which is considered a mashup of the models pioneered by Lobster, Rust, and Nim. --> +- The [metaprogramming](METAPROGRAMMING.md) document explains how using metaprogramming to extend the language works. <!-- and write more powerful code works. --> +- The [asynchronous](ASYNC.md) document gives an overview of the intertwining of Puck's asynchronous support with other language features. +- The [effect system](EFFECTS.md) document gives a description of how Puck's effect handler system works. - The [interop](INTEROP.md) document gives an overview of how the first-class language interop system works. -- The [metaprogramming](METAPROGRAMMING.md) document explains how using metaprogramming to extend the language and write more powerful code works. -- The [syntax](SYNTAX.md) document provides a more detailed look at the syntax of the language. - The [modules](MODULES.md) document provides a more detailed look at imports and how they relate to the type system. - The [roadmap](ROADMAP.md) provides a clear view of the current state and future plans of the language's development. - The [standard library](STDLIB.md) document provides an overview and examples of usage of the standard library. -- The [extended library](EXTLIB.md) document provides an overview and examples of usage of the _extended_ standard library. -<!-- - The [asynchronous](ASYNC.md) document gives an overview of the intertwining of Puck's asynchronous support with other language features. --> +- The [extended library](EXTLIB.md) document provides an overview and examples of usage of the _extended_ library. -Note that all of these documents (and parts of this README) are written as if everything already exists. Nothing already exists! You can see the [roadmap](ROADMAP.md) for an actual sense as to the state of the language. I just found writing in the present tense to be an easier way to collect my thoughts. +These are best read in order. + +Note that all of these documents (and parts of this README) are written as if everything already exists. Nothing already exists! You can see the [roadmap](ROADMAP.md) for an actual sense as to the state of the language. I simply found writing in the present tense to be an easier way to collect my thoughts. ## Acknowledgements |