Hi,

Thanks a lot for your feedback! I also apologize for top posting, but that's how yahoo do replies  :(

What I'm trying to do here is to see if using C++20 we can have something as close as possible to a declarative language, QML ( https://en.wikipedia.org/wiki/QML#Syntax,_semantics ) is one of the best example in this area, that's why I'm using widgets as an example.

As you can see in the above QML example, you don't have to explicitly set all item "properties" as they have default values, therefor you don't have to worry that you didn't set the x value of the label as, in this particular case, it will default to 0.

Using designated initializes (e.g. https://github.com/bog-dan-ro/cppstd/blob/master/declarative_c++.md#v1-using-designated-initializers ), is the closest to "pure" declarative, is also very close to QML, but as I pointed, there are some problems which makes it not very usable.

Strangely, before I wrote the "object lambdas" proposal, first, I started with an example very very closed to yours :). 
As you can see "object lambdas" and your example  are very closed, the difference is that using the "object lambdas", makes the code look more declarative (quite close to designated initializes/QML), as you don't need to specify the methods object.

Having said that, IMHO "object lambdas" (a better name might be needed), a way to specify the "this" type and its value for lambdas, will make the C++ code  look and feel declarative.

Yours,
BogDan.

P.S. I'm going to add your example as the starting point for "object lambdas" proposal (mine didn't have the "requires std::invocable<F, Window&>").

On Tuesday, March 30, 2021, 01:17:17 AM GMT+3, Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:


On Sat, Mar 27, 2021 at 1:32 PM BogDan via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Hi again,

   I'm re-posting the link to the proposal as a simple text https://github.com/bog-dan-ro/cppstd/blob/master/declarative_c++.md as it was altered by mailman .


It seems like you're trying to invent a GUI-widgets API at the same time as a language feature. I recommend sticking to just the API or just the language feature. Design the API the way you want it, and then see if any new language feature could really improve it or not.
For example, take
and write that API using standard C++; you'd get something like this:

struct Window : std::enable_shared_from_this<Window> {
    template<class F> requires std::invocable<F, Window&>
    explicit Window(const F& setup) {
        setup(*this);
    }
};

auto window = std::make_shared<Window>([](auto& w) {
    w.width = 100;
    w.height = 10;
    w.children = {
        std::make_shared<Label>([](auto& label) {
            label.y = 10;
            label.text = "Some label";
        },
        std::make_shared<Button>([&](auto& label) {
            label.text = "Quit";
            label.clicked = [parent = w.shared_from_this()]{ parent->close(); };
        },
    };
};

Is that where we're starting from? Personally,
- I don't do much GUI-widgets stuff,
- I think that's a "clever" API,
- but I'm not sure I'd want to use it.
It seems to make too much stuff public, and permit too many things to go uninitialized — see how the first child sets its `y` coordinate but fails to set its `x` coordinate. We can kinda deal with this via the Builder pattern — we say that the `const F& setup` lambda actually receives a WindowBuilder object, not a Window directly, and then the Window itself is able to sanity-check the (all-public) state of the WindowBuilder before actually "committing" its changes (into private members of Window).  But still, this is very runtime-oriented — very far from what I personally mean when I say "declarative."  To me, "declarative" means that there's no runtime code — it's just a bunch of declarations, type-checked at compile time, and then if it compiles it's guaranteed to work correctly. Any solution that lets you set `label.y` without also setting `label.x` is the opposite of what I'd call "declarative."

So, I think you (having seen how one'd write that API in standard C++) should identify some concrete problems with the standard C++ solution, and then look for solutions to those problems. For example, it sounds like "too much stuff being public" is not one of the problems you're concerned with.
The ideal outcome is that you say "hmm, actually, I don't see any problems with the present-day-C++ API," and then we're done here. ;)

–Arthur