Make std.get handle default lazily#265
Conversation
| uniqArr(pos, ev, sortArr(pos, ev, arr.force, keyF.force), keyF.force) | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Bug in nearby code below the fold:
sjsonnet/sjsonnet/src/sjsonnet/Std.scala
Lines 927 to 959 in 877f5aa
In mergePatch I think we want to do force on the members before the isInstanceOf checks, e.g. force after we call .valueRaw? Unless there's some invariant whereby we can never get lazy values there.
There was a problem hiding this comment.
I think we also need this in avg and sum:
sjsonnet/sjsonnet/src/sjsonnet/Std.scala
Lines 1530 to 1544 in 877f5aa
There was a problem hiding this comment.
Probably not required in
sjsonnet/sjsonnet/src/sjsonnet/Std.scala
Lines 1588 to 1590 in 877f5aa
primitiveEquals as long as the shorthand builtin continues to force its args.
There was a problem hiding this comment.
Perhaps required in uniqArr after function application? It looks like ev.equal doesn't force its arguments.
sjsonnet/sjsonnet/src/sjsonnet/Std.scala
Lines 1742 to 1767 in 877f5aa
There was a problem hiding this comment.
Bug in nearby code below the fold:
sjsonnet/sjsonnet/src/sjsonnet/Std.scala
Lines 927 to 959 in 877f5aa
In mergePatch I think we want to do
forceon the members before the isInstanceOf checks, e.g. force after we call.valueRaw? Unless there's some invariant whereby we can never get lazy values there.
Isn't there a bug here:
val lValue = if (l.containsVisibleKey(key)) l.valueRaw(key, l, pos)(ev) else null
val rValue = if (r.containsVisibleKey(key)) r.valueRaw(key, r, pos)(ev) else null
if (rValue.isInstanceOf[Val.Null]) { // if we are not removing the key
if (lValue != null && rValue == null) {
rValue is never null?
There was a problem hiding this comment.
I think we also need this in
avgandsum:sjsonnet/sjsonnet/src/sjsonnet/Std.scala
Lines 1530 to 1544 in 877f5aa
forall calls .force
There was a problem hiding this comment.
Perhaps required in
uniqArrafter function application? It looks likeev.equaldoesn't force its arguments.sjsonnet/sjsonnet/src/sjsonnet/Std.scala
Lines 1742 to 1767 in 877f5aa
all callers of uniqArr and sortArr call force
There was a problem hiding this comment.
Isn't there a bug here:
val lValue = if (l.containsVisibleKey(key)) l.valueRaw(key, l, pos)(ev) else null val rValue = if (r.containsVisibleKey(key)) r.valueRaw(key, r, pos)(ev) else null if (rValue.isInstanceOf[Val.Null]) { // if we are not removing the key if (lValue != null && rValue == null) {rValue is never null?
I think you omitted a ! in the quoted code?
From
sjsonnet/sjsonnet/src/sjsonnet/Std.scala
Lines 925 to 928 in 877f5aa
rValue could be null if right doesn't contain that key. An null.isInstanceOf[Val.Null] will be false, so its negation would be true hence a need to check for rValue nullness in that condition.
There was a problem hiding this comment.
yeah a typo
JoshRosen
left a comment
There was a problem hiding this comment.
I took a careful look at the stdlib updates, paying special attention to whether we have .force calls in the right places. I specifically focused on places where we do .isInstanceOf or match on Vals.
I spotted a couple of potential bugs, some of which were pre-existing issues (e.g. inconsistency in forcing the results of function application or object field retrieval prior to comparison) and others which are new in this PR.
This looks good overall pending fixes to the places noted above.
Basically,
should not execute default unless needed.
In the current implementation, builtins evaluates all arguments by default. This change changes that. Now Builtins have to force arguments when they need it.