Open mununki opened 10 months ago
Also same happends:
let c = Ok(None)
let fc = v =>
switch v {
| Ok(v) => {x: ?v}
| Error(_) => {}
}
Js.log(fc(c)) // {x: undefined}
c/1013 = [0: 0a]
fc/1014 =
(#fn_mk
(function v/1015
(switch* v/1015
case tag 0:
(let (v/1016 =a (field:var/0 v/1015)) (makeblock [x] v/1016))
case tag 1: (let (match/1027 =a (field:var/0 v/1015)) [0])))))
It seems inevitable as per lambda output. Both as y
and Ok(v)
are making the new assignment to the variable which means that the compiler doesn't know y and v are the same to the original variables b and c.
Here's a shorter code that demonstrates the issue:
type item = {
x?: int
}
let x1 = None
let x2 = if Math.random() < 2.0 { None } else { Some(3) }
// {}
Console.log({x: ?x1})
// {x: undefined}
Console.log({x: ?x2})
My take on this issue is that since Rescript is a functional language, it should usually be true that "equals can be substituted for equals."
So I think the correct way to handle this would be that whenever x: ?y
is used in a record constructor, the compiler needs to generate slightly more verbose js:
let rec = { };
if (y) { rec.x = y; }
More succinctly, this could be accomplished using spread syntax:
let rec = {
...(y ? {x: y} : {})
};
Here's a demonstration of how js code generation can be changed to omit None
optional fields, regardless of whether the compiler can tell at compile-time that they are None
: https://github.com/rescript-lang/rescript-compiler/compare/master...ellbur:rescript-compiler:object-with-spreads
It's a bit messy because I'm not familiar with the rescript code, and I'm not that good with ocaml. If this seems like something that would be useful, I'm happy to clean it up.
As I was working on this, I had a couple thoughts:
Record_regular
/ Record_optional
is per-record rather than per-field. I suppose for more finely tuned js-interop, it should be per-field.{ x?: t }
could have the same representation as { x: option<t> }
, and a per-field annotation like @omitWhenNone
could be created when omitting from the runtime representation is desired.
lambda