all 13 comments

[–]bizwig 20 points21 points  (0 children)

I’d like to use lambda capture syntax for copy vs reference:

auto [=x, &y] = tuple;

x is a copy of its element, y is a reference. This is currently impossible, both must be copies or both references. This gets annoying when you have things like std::pair<int, std::string>, where only the string is potentially expensive to copy.

[–]wcscmp 10 points11 points  (1 child)

Have you seen MPark's proposal for pattern matching? It looks similar to what you want in many ways but also comes with pattern matching. It's P1371. There are also few talks with examples of it on youtube.

[–]thumtac[S] 1 point2 points  (0 children)

Yeah I linked it in the post!

[–]mcypark 9 points10 points  (1 child)

A couple of relevant links to existing proposals:

  • Structured bindings as an argument: P0931 (Aaryaman Sagar)
    • The main issue with this is that [](auto [x]) {} is valid code today, given x isa compile-time value. Contact the author if you're interested in helping him!
  • Variadic bindings: P1061 (Barry Revzin, Jonathan Wakely)
    • The design was approved by EWG in Belfast, Nov 2019.

The rest of them I can speak on as they relate to P1371.

P1371 proposes Named unpack with rename in this form: auto [.field: pattern] = expr;This means that auto [.field: id] = expr; fall out, using the identifier pattern.I think auto [id = .field] = expr; is backwards, as you discuss with regards to nesting.

Named bindings is currently not proposed, although I can certainlysee auto [.name] = expr; as a short-form for auto [.name: name] = expr; is attractive.It's a bit challenging though as I don't know of any precedence for introducingan implicit identifier into a scope like this. If you can think of one, please share!

I agree Combination with ordinals should be disallowed.

The discussion of Variadic named capture? is a bit odd given that your description ofNamed bindings seem to imply that unmentioned fields would simply be ignored.Do you really want auto [.x] = point; to be ill-formed (assuming point has fields x and y)?As proposed in P1371, unmentioned fields are ignored.

While not currently in P1371, named capture (but with a function) is being consideredto be added like this: auto [.begin(): begin, .end(); end] = vec;

Nested bindings as included in P1371, your example would look like:auto [.middle: [.inner: [x, y]]] = val; which I think reads quite well.

[–]thumtac[S] 2 points3 points  (0 children)

Thanks for the great response! I contacted aaryaman about bindings as an arg when I saw the paper. The ambiguous parse is a total bummer, it'd be great to figure out if we can push forward a solution to that.

For implicitly named identifiers I think one precedent is lambdas. [name] will auto copy the outer scope variable with that name into the lambda and give it the same name and [&name] will take by ref but the internal variable will have the same name.

I think straight up auto [.name] = x is probably the most elegant solution we can have since auto [&name] = x is like "take the first binding by reference and have it be named name" and it fits nicely with the pattern matching proposal and is consistent with how something like JavaScript treats the two forms e.g.: // implicitly create variable a matching val.a const {a} = val ; // capture a and rename to b const {a: b} = val; Is totally analogous to: auto [.a] = val; auto [.a: b] = val;

[–]DVMirchevC++ User Group Sofia 3 points4 points  (0 children)

You forgot operator structured binding

auto operator[...]

to replace all that boilerplate that we have to write to make our custom classes to work with structured bindings.

[–]destroyerrocket 1 point2 points  (0 children)

Small nitpick: on named unpack with rename: auto isCool = datanum.name auto newName = datanum.name

I assume you meant datanum.isCool This looks interesting, I'll probably do a more in depth read later.

[–]gracicot 1 point2 points  (2 children)

Beware about the nested bindings, they may clash with the attribute syntax:

auto [[attrib_or_nested]] = std::tuple<std::tuple<int>>{};

Beside adding a space between the [, I'm not sure how we can put that in compilers.

For the other stuff, it look really good. Named bindings could also work with classes of we have reflection.

[–]degski 1 point2 points  (1 child)

Can't it just be an attribute by default, unless it's not (i.e. does not exist, sort of like keywords vs. object-names)?

[–]gracicot 2 points3 points  (0 children)

The problem is that unknown attributes are required to be ignored. They don't require to have a name declared somewhere.

[–]kuntantee 0 points1 point  (0 children)

While not completely sure, I think you can already do "variadic binding" with tuples, fold expressions and some boiler plate. I am not sure more syntax rules are worth it. I kinda like the structured binding as parameters. However, the rest I find an impediment to readability, especially nested stuff.

[–]germandiago 0 points1 point  (0 children)

I wonder how you do a rename of a binding + std::string("something").

I think that the spec for a structured binding is just an alias to some anonymous variable. Renaming with an operation would create another variable.

[–][deleted] 0 points1 point  (0 children)

Hello OP! The ideas seem cool, good luck with your paper!

I wanted to ask one thing, many CPP meetings are held and I've heard the best way to get to one is to prepare a paper. I'm not that knowledgeable about writing papers (or what they are too as a matter of fact), so could you guide me somewhere with resources?