Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Variadics syntax#4735

libbooze started this conversation inLanguage design
Dec 22, 2024· 1 comments· 4 replies
Discussion options

Hi everybody!

After watching "How Designing Carbon C++ Interop Taught me About C++ Variadics & Bound Members - Chandler Carruth" variadics
syntax does not feel intuitive to me. For context I am C++ dev.

First of all apologies for potential misunderstandings since I could not get the examples from slides working on godbolt.

There are few issues here that make syntax weird for me:

  1. return IntSum(... each param * each param); screams Cartesian Product to me, not square every item in pack
  2. ... *each value -=min; feels wrong because my expectation is that dereference operates on pointer appearing immediately after*.
  3. using both... andeach seems to heavy although I prefer nicer syntax compared to obscure C++ one, and I think Swift has even more verbose syntax

I have some ideas what would be nicer syntax but don't want to mention them since I know too little about language grammar, i.e. what options are available without making parsing a nightmare.

You must be logged in to vote

Replies: 1 comment 4 replies

Comment options

First of all apologies for potential misunderstandings since I could not get the examples from slides working on godbolt.

No problem, and yeah, this isn't yet implemented.

There are few issues here that make syntax weird for me:

  1. return IntSum(... each param * each param); screams Cartesian Product to me, not square every item in pack

FWIW, I do understand this confusion, but I'm not sure how we can address it. Most of the variadics approaches I've seen suffer from this, and all I really know to do is document and teach it so people don't accidentally fall into the wrong mental model.

  1. ... *each value -=min; feels wrong because my expectation is that dereference operates on pointer appearing immediately after*.

We have talked about requiring more parentheses to help reduce confusion here:*(each value). I think the current plan is to see how the current approach plays out in practice a bit. This is easy for us to revise based on feedback around specific precedence problems that are observed.

  1. using both... andeach seems to heavy although I prefer nicer syntax compared to obscure C++ one, and I think Swift has even more verbose syntax

Yeah, we're just trying to find the right balance.

We've seen in C++ a ton of reasons why havingsome syntactic marker for the expanded entity clarifies things, and the best syntax we saw for it came from Swift (huge props there). We thought we could minimize the syntactic weight of the whole construct by taking C++'s..., but it's still a balance.

We could look at other balances, but I think here too it would be useful to get a bit more code written in Carbon before we spend a lot more time trying to tweak the exact syntactic balance. What we have seems reasonable solid and teachable, and so our current priority is to get more implemented and get code written using this. We should be able to then revisit some of these purely syntactic questions pretty easily based on feedback and user experience and any new ideas that folks have.

You must be logged in to vote
4 replies
@libbooze
Comment options

Thank you for reading and replying.

I agree that there needs to be more feedback before making changes, this was just one user initial impression report. I fully understand that Swift user X might like it, Py user Y might want* to do expansion, etc.

If you give another talk related to this(even if it not a full talk, i.e. lightning talk) would be nice to see potential changes and more complicated examples, I will write using C++ terminology since that is my primary language:

  • syntax for pack of types where each is same type and all arestd::unsigned_integral vs pack of types where they are not necessarily same but all arestd::unsigned_integral
  • using delimiter type to separate packs that are of same/indistinguishable type, e.g. cart(1,2, delim, 3,4,5) to produce (1,3), (1,4)... (2,5) where delim is some tag type to split input args into to 2 packs. This is not possible in C++, so would be interesting to see it working.

P.S. not related to Carbon itself, but for me style of slides in this video was quite nice, arrows really made it easy to follow.

@geoffromer
Comment options

If you're interested in a deeper dive into Carbon variadics,this talk may be of interest (but note that it uses slightly different notation and terminology, because it's a little older). Plus of course there's thelanguage proposal anddesign doc. Both the talk and the docs have examples of packs where each element has the same type (Min, which is also in Chandler's talk) and packs where the elements can have different types (StrCat).

As for your cartesian-product-with-delimiter example, there are a couple of problems. First, the signature of the function would need to be something likefn cart(... each x: i32, _: DelimType, ... each y: i32), but we don't allow multiple pack expansions in a single parameter list, because in general there's no way to tell where one expansion ends and the next begins. However, you can achieve the same effect in a slightly different way, by having the function take two variadic tuples:fn cart((... each x: i32), (... each y: i32)), which would be called likecart((1, 2), (3, 4, 5)). Seehere for more about that.

The other problem is that we don't have a way to write the body (or return type) of a cartesian-product function, because we don't support nesting pack expansions. We're open to allowing that in the future, but it raises some difficult design questions, particularly about the ergonomics of the feature, so we'd need to have some clear, practical motivating use cases to evaluate the solution against. Seehere for a little more about that.

@libbooze
Comment options

If you're interested in a deeper dive into Carbon variadics,this talk may be of interest (but note that it uses slightly different notation and terminology, because it's a little older).

Very interesting, nice design to useeach also for type constraints.
I still feel syntax is a bit too verbose, as explained in my original comment, but tbh after just 1 or so hour of listening about it in above talk I kind of got used to it, so I guess learning it is not as hard as I expected. 🙂
One thing that was asked during the talk and I agree is that marking nonempty pack without trick withfirst would be very nice. I know you mentioned you discussed that but found no nice syntax for it, but I must say that doing division by(1 + Count() ) looks quite ugly. I presume one can alwaysstatic_assertCount in the body, but it is not in the signature, so may not be great for users and there is an issue that from what I understand you do not have nice way to doheadof/tailof on pack soMin might anyway be unimplementable without explicitfirst.

Again nothing you need to focus on now, I fully agree with Chander policy to first get some more feedback, but would be nice to keep this in mind for the future.

When this is on godbolt I will try to play around a bit and see if I can implement in usercodeheadof/tailof(whereheadof will fail compile when passed 0 args) so thatMin can be implemented withoutfirst. I know head/tail hints at recursion, that is not what I am talking about, I would be happy to just do initialization of result with head and then do loop/for over tail without recursion.

Once again thank you for the responses, if you know when this will approximately land on godbolt please let me know.

@CJ-Johnson
Comment options

@libbooze You may find this issue and the linked doc interesting:#5093

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Labels
None yet
4 participants
@libbooze@chandlerc@geoffromer@CJ-Johnson

[8]ページ先頭

©2009-2025 Movatter.jp