tc39/proposal-record-tuple

Consider terser syntax - skip # inside tuple/record literal for nested tuples/records

callionica opened this issue ยท 6 comments

I had a quick look through closed issues and didn't see anything nor did I see this addressed in the spec:

Why does the syntax still require # when tuples/records are nested? Since arrays/objects are not allowed within tuples/records, there would be no ambiguity if # were not required on nested tuples/records.

Has this been considered?

Yes, it's been considered. If you had:

const r = #{ a: { b: 1 } };
assert(typeof r.a === 'record');

and then copy-pasted the inner braces out, you'd get an object instead of a nested record, which is confusing. Additionally, you might expect to be creating a mutable object, and be surprised to find out the nested thing was a record instead.

Thanks for the quick reply.

I expect to use tuples/records quite a lot, and I expect that I would feel that the # is visual noise and busywork.

If # were not required and I were to copy a nested record with nested records and wanted another record, I would have to add at most 1 #.
When # is required, if I were to copy a nested record with nested records and wanted a mutable tree, I've got to delete a bunch of #s.

If I want to copy the structure down level (older browsers, json, whatever), I'm also going to have to get rid of the #s (or add them if going the other way).

I think the surprise/confusion thing would be extremely short lived unlike the extra characters I'm going to be typing, so please consider this a vote for the terser syntax.

Reading is far more important than writing, so it's not really a problem that you'd have to type a # - what is a concern is that someone who reads the code understands what it means.

Hi @callionica thanks for checking out the proposal.

While for small examples it may seem clear where the nested records and tuples are, a key detail is that the values can be arbitrary expressions:

const rec1 = #{ prop: {} }; // potentially 'trivial' to see that the inner prop value should be a record not an object

const rec2 = #{
  prop: condition ? f({}) : {} // <- but what happens here? 
  //                  ^^    ^^
  //                  |      ^ - should this be a record
  //                  ^ - and/or this?
};

Ah, yes, that's more compelling. It would be weird & limiting to disallow object/array literals from appearing in expressions within records and more complex rules that could make it work would likely be hard for humans to deal with. You have convinced me that nested tuples/records need the #. Thanks!

@callionica thank you for the comments, they are much appreciated.

I'll go ahead and close this issue.