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

Let record types have a constructor. #3136

Open
lrhn opened this issue Jun 7, 2023 · 2 comments
Open

Let record types have a constructor. #3136

lrhn opened this issue Jun 7, 2023 · 2 comments
Labels
request Requests to resolve a particular developer problem

Comments

@lrhn
Copy link
Member

lrhn commented Jun 7, 2023

The only way to create a record value is a record literal. If you want some other function to create a record for you, you need to wrap that up as a function, (int v1, String v2) => (v1, v2).

I think it could be useful to allow record types to be considered as having a const unnamed generative constructor, which can be torn off. Or called, if that's considered useful.

That would allow more easily creating a function which creates a record from arguments in the same order.

It may also be useful for using record types in places where a constructor is expected (potentially #2967), and if we add any future features which work on types with constructors, records would fit in (say if we ever allow calling constructor through type parameters, or let them have static interfaces).

Allowing a constructor to be torn off, from a specific record type, should not change the analysis of which record shapes are used by a program, although it would probably consider the shape used, even if the constructor is never called. (Unless the tear-off itself can be tree-shaken.)

It's not trivial to access the constructor directly, since you can't write (int, int).new (it's not in the grammar).
The workaround would likely be having a typedef typeof<T> = T; and do typeof<(int, int)>.new. That's a reasonable enough workaround, and the type-alias could be useful in other ways too.

Calling it as, say, a super-constructor of an inline class would work directly.
(And if you have a typedef Tuple2<T1, T1> = (T1, T2); you can do Tuple2(v1, v2) and get the normal type inference applied.)

@lrhn lrhn added the request Requests to resolve a particular developer problem label Jun 7, 2023
@munificent
Copy link
Member

If you want some other function to create a record for you, you need to wrap that up as a function, (int v1, String v2) => (v1, v2).

Is that so bad?

If we ever allow spreading records into argument lists, I could see us also offering some syntax for the opposite: capturing a parameter list as a record. If we did that (let's say the syntax is foo), then it would be:

(int v1, String v2) => foo;

@frmrgr
Copy link

frmrgr commented Jun 27, 2023

I think it would be nice to have this feature. Currently instantiating big records is a bit annoying, as a typo in a field name, or accidentally passing a wrong type (int? instead of a int) somewhere makes IDE highlight the entire (...) expression instead of the wrong part. So the solution is to write out the instantiating function manually (#2528), but nobody got time for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
request Requests to resolve a particular developer problem
Projects
None yet
Development

No branches or pull requests

3 participants