> 1. A hard, enforced separation between stateless functional code and stateful procedural code
> 2. Reactivity as a first-class citizen
Hell yes, I'm in. These two features are interesting enough to try by themselves, I don't even care about the details.
The next most important thing is that JS/TS FFI just works, so I really hope it does.
However going the other way - calling Bagel from JS/TS - has been on the roadmap from day one and should work pretty seamlessly. Bagel already compiles to TS in fact, including type info.
Wish you all the best with Bagel!
Aside from the traits (typeclasses), most of the inspiration actually comes from OCaml/ML rather than Haskell. The philosohpy is also way closer to the pragmatism of OCaml. I think Rust wouldn't be as popular as it is right now if IO needed a monad, like in Haskell. This would have been too much for a single language. I also don't think that monadic IO is the way. Maybe effects system will bring a more usable way of typing effects (Koka, OCaml soon), but I doubt that they'll come to Rust.
Your idea of having functions that don't have effects and procs that don't return, reminds me of https://en.m.wikipedia.org/wiki/Command%E2%80%93query_separa... - so there's some prior work there for reassurance and reference.
First class reactivity would be extremely useful - I've thought the same thoughts as you around how reactivity is only partially solved with the current generation of UI libraries (or moreso with RxJS, but the syntax is full of baggage) so I wish you every success with solving it more comprehensively.
I have heard of Eiffel though I don't know much about it. I am honestly surprised this concept hasn't been explored more, given how long it appears to have been around.
{
if (cond) set {a: 1},
for (x of values) set {[x.name]: x},
b: thisob.x,
c: {d: thisob.c},
}
enhanced data transfer, dest.{a, b, [key]} = src
default values, var x = arg ?? 1
optionality and mandatoryness, var x = f?(…)?.info![key] ?? "<not found>"
scope objects and flow control in these, function foo(a=1, b=2) {
scope bar {
let c = 3
scope {
let c = 4
log(a, b, bar.c, c)
baz(scope.this) // a, b, c, bar
baz(scope.arguments) // a, b
break bar
function environments, global.{*} = {a:1, b:2}
var t = proxify({a:3, b:4}, global)
withenv (t) foo() // 3 4
function foo() {
console.log(a, b)
}
and so on. It seems everyone jumps on to “new same language” train when there is so much to do in what’s already not done.