Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Record and Tuple creation should be recursive. #378

Open
caikan opened this issue May 14, 2023 · 5 comments
Open

Record and Tuple creation should be recursive. #378

caikan opened this issue May 14, 2023 · 5 comments

Comments

@caikan
Copy link

caikan commented May 14, 2023

Record and Tuple are both deeply immutable, and there will never be a situation where mutable objects are passed in nested structures.
So our syntax can be simplified as follows:

// before
const record = #{
  a: 1,
  b: 2,
  nested: #{
    tuple: #[1,2,3],
  },
}

// after
const record = #{
  a: 1,
  b: 2,
  nested: {
    tuple: [1,2,3],
  },
}

We can make #expression as a syntax suger of createRecordOrTuple(expression),

functoin createRecordOrTuple(data) {
  if (data && data[Symbol.iterator]) {
    return Tuple(...data)
  }
  if (data instanceof Object) {
    return Record(data)
  }
  return data
}
@ljharb
Copy link
Member

ljharb commented May 14, 2023

Why would there never be such a situation, where someone attempts or intends to do that?

@acutmore
Copy link
Collaborator

I think this is a duplicate of #375

Applying the construction recursively could slow down creating the values, as the original mutable object would be created and then the 2nd record/tuple gets created. Having explicit syntax at the construction site makes this easier to avoid.

For an example like:

#{ p: [2,4] }

It looks like it is easy to optimise out the creation of the array and infer that the inner value should be a tuple but with indirection it becomes harder:

const getArr =  () => [2,4];
#{ p: getArr() };

More analysis is required to optimise out the array. This could lead to surprising performance differences between very similar code.

It may also result in errors, when invalid values are used; being thrown later due to the delay in converting the array/object to a tuple/record. Making it harder to spot the source of the invalid value.

@caikan
Copy link
Author

caikan commented May 14, 2023

I think that if recursive creation is not supported, it will not prevent people from trying to create nested Record/Tuple, but it will just make the code writing more cumbersome:

const getArr =  () => [2,4];
#{ p: #[...getArr()] };

@ljharb
Copy link
Member

ljharb commented May 14, 2023

Sure. But it will make the code reading more clear, which is always more important than how hard it is to write.

@caikan
Copy link
Author

caikan commented May 14, 2023

Since it is deeply immutable, nested data must be converted to immutable. I don't think the more cumbersome way of writing it would make the code clearer to read.
Also I wish this syntactic sugar could be used for any expression, not just object/array literals.
I actually thought it would be more convenient to use # at the end of the expression:

const [head, ...rest] = [1,2,3]#
console.log(rest# === [2,3]#)

console.log(someObj.getSomeValue()# === targetTuple)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants