I am designing a programming language and I want to give everything the ability to return a value. For example, if I use a block as a right-hand side value, I can assign it to a lvalue:sum := {    if (a < 0) { a := -a; }    if (b < 0) { b := -b; }    return a + b;};Also, if and while statements could return a value, and there is no need for something like a ternary operator then.After a bit of research, I have found that Rust is capable of doing this. And this is great for language design, because it significantly reduces the number of language constructs needed. You don't really need a do-while loop, as that's just a while loop with a braced condition:do {    foo();} while (a > 0);Is equivalent to:while {    foo();    return a > 0;}{}Also, with ignored variable bindings, you can create continue and break statements for loops:// Break_ := while (a > 0) {    if (a == 5) {        return ();  // Empty tuple    }    a += 1;};// Continuewhile (a > 0) { _ := {    if (a == 5) {        return ();  // Empty tuple    }    a += 1;};}I like the idea of having less language constructs, because the language is expressive enough to do this without labeling and goto statements.But as I was thinking about this, two things popped into my head:Are these just very abstract lambda expressions?How could the 'return destination' be labeled so we can return from a very nested expression even right out to the function? I think I would probably need some extra notation for that.
Return destinations for an expression-oriented programming language
programming languages;language design
1) In a sense, yes. Guy Steele wrote the Lambda papers, where he reduced many different constructs to lambda expressions, in a compositional way. He used the lambda abstractions of Scheme for this, but the construction is general.2) You should read about continuation passing style. Scheme, for instance, uses  call with current continuation call/cc to achieve what you describe: returning from a deeply nested location.call/cc is probably not the most convenient notation, but it works, and can be used with any expression. E.g.(call/cc (lambda (k)  (+ 1 (if (some-condition) 10 (k 2)))Above, if the condition is true, the if evaluates to 10, which is added to 1, so that the whole result is 11. If it is false, (k 2) is evaluated, returning to the point call/cc was used with result 2. Note that this skips the (+ 1 ..) part. You can nest call/cc arbitrarily, providing many return points as wanted.