Skip to content

Make inline vals transparent #8850

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

Closed

Conversation

nicolasstucki
Copy link
Contributor

@nicolasstucki nicolasstucki commented May 1, 2020

Inline vals aim to be a replacement of final vals with inferred literal types. They inline by having a literal type as a return type.

In inline def terms, this is equivalent to transparent inline def returning the constant which is also stable.

inline val x = 3
transparent def y: Int = 3

Therefore, such a definition of an inline val is always a transparent inline.

/*transparent*/ inline val x = 3

If we define inline vals as always being transparent inline vals, then the constant type becomes an implementation detail rather than a restriction. This would imply that the following inline val are allowed.

inline val a: Byte = 1
inline val b: Short = 2
inline val c: Int = 3

Note that with literal types it is impossible to directly implement a and b as those need a type annotation to infer their type, but the type would be widened.

New inline val definition:

  • An inline val is transparent
  • An inline val is final or abstract
  • The RHS of an inline val must be a pure constant value

Advantages

  • Aligns better with inline defs
  • Can define constant Byte and Short

The proposed implementation would just reuse the same literal constant mechanism but modify slightly type inference for inline vals. When we type an inline val we use the return type
to type/infer the type of the RHS, but then if the return type is not a constant, the return
unwidened type is replaced by the type of the RHS.

inline val x: Int = 3
// typed as
inline val x: 3 = 3

@nicolasstucki nicolasstucki self-assigned this May 1, 2020
@nicolasstucki nicolasstucki changed the title Make inline val transparent Make inline vals transparent May 1, 2020
@nicolasstucki nicolasstucki force-pushed the make-inline-vals-transparent branch from be35601 to 49d67b1 Compare May 1, 2020 07:31
@sjrd
Copy link
Member

sjrd commented May 1, 2020

I don't think I buy the "align with defs" argument. You can already achieve the equivalence with a def that returns a literal type, which is what the val does:

inline val x = 3
inline def x: 3 = 3

The argument for Byte and Short is somewhat interesting, but to me still feels like a workaround for the fact that we don't have literal Bytes and Shorts, and hence no literal types for them.

So overall I'm not in favor of this change.

@nicolasstucki
Copy link
Contributor Author

nicolasstucki commented May 1, 2020

@sjrd then there is a second question. Should it work like this if we explicitly write a transparent inline val?

transparent inline val x: Int = 3

Or should transparent val be disallowed or ignored?

@sjrd
Copy link
Member

sjrd commented May 1, 2020

It shouldn't be ignored. Either forbid it, or make it work like you described. If have no strong feeling between those two options.

@nicolasstucki
Copy link
Contributor Author

To forbid or support it, we need to be able to know it was transparent. But as we drop the transparent modifier when we desugar we do not have any way to know if the definition is transparent or not. As I argued many times we should keep this information, we did not do it to use up flags.

Inline vals aim to be a replacement of final vals with inferred literal types.
They inline by having a literal type as a return type.

In inline def terms, this is equivalent to transparent inline def returning the constant which is also stable.
```
inline val x = 3
transparent def y: Int = 3
```

Therefore, such a definition of an inline val is always a transparent inline.
```
/*transparent*/ inline val x = 3
```

If we define inline vals as always being transparent inline vals, then the constant type becomes an implementation detail rather than a restriction. This would imply that the following inline val are allowed.
```
inline val a: Byte = 1
inline val b: Short = 2
inline val c: Int = 3
```
Note that with literal types it is impossible to directly implement `a` and `b` as those need a type annotation to infer their type, but the type would be widened.

New `inline val` definition:
* An `inline val` is `transparent`
* An `inline val` is `final` or `abstract`
* The RHS of an `inline val` must be a pure constant value

Advantages
* Aligns better with inline defs
* Can define constant `Byte` and `Short`

The proposed implementation would just reuse the same literal constant mechanism but modify slightly type inference for inline vals. When we type an inline val we use the return type
to type/infer the type of the RHS, but then if the return type is not a constant, the return
unwidened type is replaced by the type of the RHS.

```
inline val x: Int = 3
// typed as
inline val x: 3 = 3
```
@nicolasstucki nicolasstucki force-pushed the make-inline-vals-transparent branch from 49d67b1 to f5c758f Compare May 1, 2020 14:27
@nicolasstucki nicolasstucki force-pushed the make-inline-vals-transparent branch from 1f01f71 to 1b8d719 Compare May 1, 2020 16:19
@odersky
Copy link
Contributor

odersky commented May 3, 2020

I have not seen a strong reason to change what we have here. It makes things more complex for no apparent gain.

@nicolasstucki nicolasstucki linked an issue May 3, 2020 that may be closed by this pull request
@nicolasstucki nicolasstucki mentioned this pull request May 25, 2020
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

Successfully merging this pull request may close these issues.

Keep transparent modifier
3 participants