RFC: change the default unbox configuration to be unboxed by default

Hi all,

This is the proposal to change the default unbox configuration, currently:

type t = A (int)
type t = {a : int} 

These are boxed by default, to unbox it, it requires the attribute @unboxed.
I am planning to change the default behavior so that we have unboxed by default, and the user has to add @boxed attribute to preserve the old behavior. (Note that @boxed attribute is not a new attribute, it already exists there)

The major motivation is not for performance, but for the convenience of some special encoding. For example, we have rank-2 polymorphism with records:

@unboxed
type t = {
  id : 'a . 'a => 'a
}

It will also make Avoir cyclic function when returning itself? - General - ReScript Forum (rescript-lang.org) easier, with unboxed by default, it can be written as is:

type rec func<'a, 'b, 'i> = ('i) => result<'a,'b,'i>

and result <'a,'b,'i> = Val (('b, func<'a, 'b, 'i>))

Let me know if I miss anything, thanks – Hongbo

4 Likes

I think it’d be more confusing for the JS interop - and could cause people to accidentally make breaking changes

7 Likes

I think I agree that this may create confusion. In the case of records, it would break any bindings for JS objects with only one field.

That’s not a concern for variants, but I also don’t see how this makes higher-rank polymorphism easier. On the ReScript side, you would still have to write code exactly the same as before. The only difference would be the JS output.

3 Likes

Hi, thanks for the feedback. After some thoughts, the benefits may be not worth the breakge.
Note the good thing is that after such experiment, I found several edge cases in the compiler and have it fixed fix several edge cases between optimizer and recursive values by bobzhang · Pull Request #5294 · rescript-lang/rescript-compiler (github.com)

10 Likes

Amazing to see this RFC process work so well. :raised_hands:

6 Likes