[ANN] Breaking change: fixing the semantics of nested objects

In Rescript, for nested objects, there is some weird semantics due to historic reasons:

For example:

{ "x" : { y : 3 } }

is equivalent to

{ "x" : {"y" : 3 }}

So that you can not put a record inside a nested object, this is not a significant problem before we compiled record into objects. Now we compile records into idiomatic js objects, it is not unreasonable to put record into a structural object.

This weirdness comes due to some historical issues. We plan to make it more explicit in the next release:

{ "x" : {y : 3 }} // record inside structural objects now is possible
{"x" : {"y" : 3}} // nested structural objects

So if you use vanilla ocaml syntax, you have to be more explicit,
previously:

[%obj{ x = { y = 3}}]

If you do want a nested structural object, you have to write it this way:

[%obj{ x = [%obj{y = 3 } ] }]

Note the explicit form is always correct between the old and new versions.

It’s not fun to introduce breaking changes, but this corner case has to be cleaned up eventually, let me know if you find the migration difficult. Note you can use the explicit form right now without waiting for a new release and if you do forget it, the comipler will warn you so it should not trigger nasty bugs.

Question:

  • Can we only change the rescript syntax and preserve ocaml/reasonml syntax to avoid breaking changes?

I thought about this, but this would bring nasty bugs when convert ocaml/reasonml syntax to rescript syntax. This clean up should benefit reason/ocaml syntax users too.

11 Likes

That’s great news, I’ve already been bit by this syntax weirdness, good to see it corrected!

Yes great news! I think this is a fine breaking change because I am not aware of people using this feature When I stumbled upon it I was surprised and needed to unnest to work around it, that code still keeps working. I think it would be nice to also add this to the ReasonML syntax.

This is landed in master, should be available in next release

4 Likes