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

RFC: Explicit type parameter instantiation #90

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Kampfkarren
Copy link
Contributor

Rendered

TL;DR -- Adds support for calling f<<T>>() where f is a function that takes a type parameter T, similar to Rust's turbofish (f::<T>()) or C++'s f<T>(). This is done at the expression level, so f<<T>> is valid as a value.


This is either a parameterized function call of `f(c)` with `a` and `b` as types, or a return of two values--`f << a`, and `b >> (c)`.

Because there would be no ability to add bitwise shifts to the language, it is unlikely that any bitwise operators would be added, as it would be a stark omission.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we see a RFC that basically puts the final nail in the coffin for bitwise ops? Time and time again, people want to see it, but bit32 is better because it guarantees better performance characteristics anyway.

@aatxe
Copy link
Contributor

aatxe commented Jan 21, 2025

High-level nitpick but can we call this RFC: Explicit Type Instantiation or RFC: Explicit Type Parameter Instantiation

Comment on lines 94 to 96
-- Saving `f<<T>>` as a variable to called later
local e = f<<T>>
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to lead with this, or something else similar to be clear that the proposal is allowing the expression prefixexp '<<' TypeList '>>' as its own expression, and not just function calls having an optional new piece of syntax.

local moneyBinding = React.createBinding:<number>()
```

The downside of these is that they blur the lines between runtime and static, in the sense that `React.createBinding.` starts out as a runtime concept, followed by the purely static `<number>`. As for `:`, it carries the baggage of `x:y()` which will perform a runtime mutation of the function call in the form of adding on `self`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not describe this as a runtime mutation. It's very confusing. There's no mutation happening, x:y() is just syntactic sugar for x.y(x).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm not sure the right way to say what I want to say--what I want to say is that : is inherently more "interesting" than .


The downside of these is that they blur the lines between runtime and static, in the sense that `React.createBinding.` starts out as a runtime concept, followed by the purely static `<number>`. As for `:`, it carries the baggage of `x:y()` which will perform a runtime mutation of the function call in the form of adding on `self`.

There is also not necessarily a reason that we have to provide symmetrical operators, so something like `f!T, U()` is reasonably parseable, but is not obviously better.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also asymmetrical operators have the drawback of being even more Different:tm: from other instances of type application syntax in languages. This is something where you're providing a collection of arguments, and culturally, folks have decided that collections are grouped with symmetric brackets of some sort.

@andyfriesen
Copy link
Collaborator

I'm honestly inclined to go for ::<> as the syntax so we don't close the door to ever adding bitshifting operators.

The ambiguity issue is real, but I think this is obscure enough that we can ask people to use whitespace to differentiate between foo::<T>() and foo :: <T>() -> ()

@Kampfkarren
Copy link
Contributor Author

Intentionally adding an ambiguous syntax for the sake of potentially adding something that has been denied in the past makes me really uneasy 😕

@aatxe
Copy link
Contributor

aatxe commented Jan 24, 2025

I'm honestly inclined to go for ::<> as the syntax so we don't close the door to ever adding bitshifting operators.

The ambiguity issue is real, but I think this is obscure enough that we can ask people to use whitespace to differentiate between foo::<T>() and foo :: <T>() -> ()

Given the cultural opposition to significant whitespace in our community, I think we have to categorically rule out this possibility, even if it's unlikely to actually affect anyone.

I also think the long-standing arguments against bitshift operators are quite strong. We do not have integers, they are not useful without integers, and the identity of the language would have to change pretty dramatically for us to add separate integers, I'd say.

@Kampfkarren Kampfkarren changed the title RFC: Parameterized function expressions RFC: Explicit type parameter instantiation Jan 28, 2025
@andyfriesen
Copy link
Collaborator

I talked with @aatxe and @vegorov-rbx about this offline. I'm convinced. Let's go forward with the syntax f<<T>>()

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

Successfully merging this pull request may close these issues.

4 participants