diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..f61dfdb --- /dev/null +++ b/README.md @@ -0,0 +1,85 @@ +# FWD + +`fwd` is a toy language where the idea is that functions/procedures can never +return values, instead all computation happens "forward" by heavily utilizing +closures. + +## Why? + +Informally: Objects have a lot of context to keep track of, are all references +valid, who owns what, etc. and there have been lots of approaches to control +this complexity. This is yet another experiment, based on the idea that we could +syntactically specify which scope an object is valid in. + +Effectively, imagine that instead of being handed an object and a bunch of rules +about how you're allowed to use it, you just specify what code to run and let +some implementer ensure that the context is safe for it. + +Eventually I should probably write a better explanation, but this is good enough +for now. + +## How? + +Functions don't return values, instead they take some amount of closures to +execute. One pretty central feature of `fwd` is how these closures are expressed +syntactically, namely that they can be expressed outside of the function +argument list. As an example, + +``` +give_me_some_object() => obj1; +insert_something(obj1) => obj2; +do_something_with(obj2); +``` + +`=>` can be thought of as a closure operator, and in this case the body of the +closure is the rest of the function, so +``` +give_me_some_object(|obj1|{ + insert_something(obj1, |obj2|{ + do_something_with(obj2); + } +}); +``` + +It's possible to specify the exact scope for a closure as well: +``` +check_cond(x) => a1 { + /* cond was true */ +} => a2 { + /* cond was false */ +} +/* runs after check_cond, not 'within' it */ +``` + +This 'scoping' in combination with move semantics seems like an easy way to +syntactically specify both ownership and lifetime of an object, +no need for lifetime annotations or extra stuff like that. +At least hopefully, this is still a very rough idea and I wouldn't be surprised +if I have an excessively optimistic view of this. Will have to play around with +the compiler as I develop it. Presumably I'll also want references, but they are +as of yet unimplemented. + + +## Examples + +See `examples/`. Currently there's just `uniq.fwd`, which filters out non-unique +lines from its `stdin`. + + +## Current state + +The 'meat' of the project is still unimplemented, that being proper move semantics. +There's an initial parser and a small generator for C++ so that I can quickly +get up and running and test out programs. There's also `lib/fwdlib.hpp` which +acts as a bridge between C++ and `fwd`, and any functions that start with `fwd_` +are actually just C++ functions. This way I can start experimenting with the +language even in a very crude state, and I don't have to implement containers or +generics myself. At the moment I also kick pretty much all type checking to C++, +eventually I'd probably like to take care of it at a higher level. + +## Future + +If (big if) this experiment turns out to be useful on some level I'll probably +slowly try to make it more self-reliant. My target would be systems programming, +possibly even embedded systems, though I don't yet know if this 'paradigm' is +powerful enough or if I might need some escape hatches like `unsafe` in Rust. |