Giter VIP home page Giter VIP logo

Comments (2)

geoffromer avatar geoffromer commented on May 27, 2024 1
fn! Test[... each statement:? Statement](condition:? bool, step:? i32) {
    while (condition) {
        ... each statement;
        step;
    }
}

var i: i32 = 0;

Test(i < 3, ++i) {
    Print("Ding!");
}

This example illustrates a few potential concerns with this proposal:

  • The value of condition:? bool isn't a bool, it's a piece of code that can be evaluated to produce a bool -- in other words, it's a callback.
  • It's easy for a reader to miss the fact that while (condition) actually invokes an arbitrary amount of code, because it looks like it's just reading a variable, and the difference depends on a single ? character, and in a more complex example that character might be quite far away.
  • Conversely, it's very easy for a reader to miss the fact that ++i might be evaluated more than once, and might not be evaluated at all.
  • It doesn't seem like statement needs to be a pack, and it's hard to think of examples that would benefit from working with a pack of statements in this way. It seems like we could just as well represent the whole block as a single statement.

Pulling all those observations together, here's my pitch: I think this proposal is really about lambdas. For example, in C++ we can already write your example like this:

void Test(std::function<bool()> condition, std::function<i32()> step, std::function<void()> statement) {
    while (condition()) {
        statement();
        step();
    }
}

i32 i = 0;

Test([&]{return i < 3;}, [&]{return ++i;}, [&]{
    Print("Ding!");
  });

This version addresses the concerns I raised above:

  • The callback types make it clear that they're callbacks.
  • The function calls in the body of Test are obvious to the reader, because they use familiar function-call syntax.
  • It's clear to the reader of the Test call that expressions like i < 3 aren't evaluated immediately, and may be evaluated more than once.
  • There's no need for variadics, even if we wanted to execute multiple statements in the loop.

However, it has some problems of its own:

  • std::function's type erasure has a run-time cost. We could avoid that by making Test a function template, but then we lose definition checking.
  • The lambda syntax adds a lot of boilerplate to the callsite of Test, making it hard to even see the application logic.
  • It's visually awkward that the loop body is nested inside both parentheses and curly braces.

The good news is that those problems seem solvable. In fact, Carbon has solved the first one already: Test can be a generic function defined in terms of the Call interface. That just leaves the other two. For those, I think we need two things:

For example, if we use Rust's lambda syntax and Swift's approach to trailing closures, your example could be:

fn! Test[Cond:! Call(()) where .Result = bool, Step:! Call(()) where .Result = i32,
         Statement:! Call(()) where .Result = ()]
      (condition: Condition, step: Step, statement:Statement) {
    while (condition()) {
        statement();
        step();
    }
}

var i: i32 = 0;

Test(||i < 3, ||++i) {
    Print("Ding!");
}

from carbon-lang.

chandlerc avatar chandlerc commented on May 27, 2024

This issue is really proposing a full new feature. If a new feature makes sense, it should be proposed with Carbon's proposal process.

We also agree with @geoffromer 's observations, so it would seem good if and when exploring this to consider things like a lambda-based approach.

As to whether it makes sense to work on this type of metaprogramming (macro-like constructs that expand to control flow), the leads don't think expanding our metaprogramming facilities matches the current priorities of the Carbon project. If and when its a better fit for the priorities, we'd definitely be interested in proposals to advance this area, but right now we're focused on getting the critical path to 0.1 ironed out.

from carbon-lang.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.