Skip to content

Conversation

@kara
Copy link
Contributor

@kara kara commented Feb 14, 2018

Renames objectLiteral instructions to pureFunction because pipes will soon share the code. Also adds a test to the canonical spec for array literals that will not change.

@kara kara added action: review The PR is still awaiting reviews from at least one requested reviewer comp: ivy labels Feb 14, 2018
@kara kara requested a review from mhevery February 14, 2018 03:01
@mary-poppins
Copy link

You can preview 4f0f8cf at https://pr22214-4f0f8cf.ngbuilds.io/.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The header comment l12 as well as Function that returns an updated instance of the object/array are no more accurate.
This is intended to be used with any pure function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch; forgot about those comments

Copy link
Contributor

@vicb vicb Feb 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if argX or argValX makes more sense than latestValue now (thinking out loud)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm out of the 3, I think I like latestValue best. argX doesn't capture how we are getting the latest value of the binding out of data[]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need 2 p ?
{{ names[0] }}{{ names[1] }} could remove some noise ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, no real reason, just for organization. I can remove if you think it creates noise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: with no changes -> of constants (it could be an exp that doesn't change)

Copy link
Contributor

@vicb vicb Feb 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use bind0 for the sake of consistency and to save 1 byte.

c?$e0_arr$:$r3$.ɵNC;
$r3$.ɵb0($e0_arr$); 

Copy link
Contributor Author

@kara kara Feb 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we send the array to bind, then we are calling isDifferent every time in addition to bind, as well as storing the value unnecessarily in data[]. I think it makes more sense for it to be treated the same way a creation-time binding is treated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// template function
$r3$.ɵp(0, 'names', $r3$.ɵb0($e0_arr$);
// instructions.ts
export function bind0(value: any): any|NO_CHANGE {
  return creationMode ? value : NO_CHANGE;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the above as b() not b0(). Now your comment makes sense!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that having describe('array literals', ...) and describe('object literals', ...) does not really make sense any more but it is probably ok and related to our tests not being real unit tests ?
WDYT @mhevery

Copy link
Contributor Author

@kara kara Feb 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the names should stay, given that those are the actual template features we are testing in integration tests. pureFunctions wouldn't actually describe the scenario adequately.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine either way.

@mary-poppins
Copy link

You can preview 6696fc5 at https://pr22214-6696fc5.ngbuilds.io/.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have also discussed adding optional applyThis: any to the arg list.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we need pureFunction0. Imagine this binding {{ ['foo'].length + 1 }}. In this case you need to prevent new object re-creation so you need pureFunction0.

function create0() { return ['foo']; }
text(0, pureFunction(create0).length + 1);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applyThis ? pureFn.call(applyThis, latestValue): pureFn(latestValue)

see: https://jsperf.com/function-calls-direct-vs-apply-vs-call-vs-bind/6

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a use case for {{ ['foo'].length + 1 }}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: In lexer/parsere terminology peek does not change state and consume does. Your peekAndIncrementBinding is confusing since it seems to be peek (no side
effect) and than it has side-effect. Could you rename to consumeBinding. Also can you give it explicit return type of any

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed that returning NO_CHANGE is never correct. What is your plan here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NO_CHANGE :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bind(pureFn(exp)) could return NO_CHANGE so it is still not quite right.

I think this is what we are looking for:

return bind(exp) !== NO_CHANGE ? updateBinding(pureFn(exp)) : consumeBinding();

maybe this may be more readable:

return consumeBinding() === exp ? consumeBinding() : updateBinding(pureFn(exp));

PS: assuming we have updateBinding function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed the factory function would always return a new instance of array/object, but @mhevery points out that it could return a constant if used in pipes (for which we don't yet have tests).

@mary-poppins
Copy link

You can preview b775e05 at https://pr22214-b775e05.ngbuilds.io/.

@mary-poppins
Copy link

You can preview 510b76d at https://pr22214-510b76d.ngbuilds.io/.

@mary-poppins
Copy link

You can preview 70179a8 at https://pr22214-70179a8.ngbuilds.io/.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong. You can't use bind0 since a one time binding has to short circuit the evaluation of the expression. In this case value. So the original code was correct.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is a use case for this. If you want one time binding than we have to make sure that the value is never evaluated, otherwise this is pointless. The idea of one time binding is that the expression (not checking if it has changed) is expensive and hence needs to be short circuited.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good, but I am wondering if bind is the right method since it is more complicated than it needs to be. a simpler method may be faster.
return isDifferent(consumeBinding(), exp) ? updateBinding(pureFn(exp)) : consumeBinding();

Copy link
Contributor Author

@kara kara Feb 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but we'd also have to add some logic on top to make sure the binding value is saved for the exp alone (so that when we call consumeBinding, it already exists). e.g.

if (getCreationMode() || isDifferent(consumeBinding(), exp)) {
  updateBinding(exp);
  updateBinding(pureFn(exp));
} else {
  consumeBinding();
}

This essentially does the same thing as bind, but in two parts (updateBinding + isDifferent), so I think it's better to use bind.

@mary-poppins
Copy link

You can preview 6377d8b at https://pr22214-6377d8b.ngbuilds.io/.

@mary-poppins
Copy link

You can preview fb931de at https://pr22214-fb931de.ngbuilds.io/.

bindingUpdated(exps[i]) && (different = true);
}

return different ? checkAndUpdateBinding(pureFn(exps)) : consumeBinding();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry this needs to be pureFn.apply(null, exps). I thought we were arguing about signature of pureFunctionV which will get invoked more often. But for pureFn we should be consistent.

@kara kara added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Feb 16, 2018
@ngbot
Copy link

ngbot bot commented Feb 16, 2018

I see that you just added the PR action: merge label, but the following checks are still failing:
    failure missing required label: "PR target: *"
    pending status "google3" is pending
    pending status "ci/circleci: build" is pending
    pending status "ci/circleci: lint" is pending
    pending status "continuous-integration/travis-ci/pr" is pending

If you want your PR to be merged, it has to pass all the CI checks.

If you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help.

@kara
Copy link
Contributor Author

kara commented Feb 16, 2018

presubmit

@mary-poppins
Copy link

You can preview 4b41c96 at https://pr22214-4b41c96.ngbuilds.io/.

@kara kara added the target: major This PR is targeted for the next major release label Feb 16, 2018
creationMode && initBindings();

if (creationMode || isDifferent(data[bindingIndex], value)) {
data[bindingIndex++] = value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • only call initBindings() here;
  • assert that value is no NC (please also add the same assert in consumeBinding above for the returned value

@mary-poppins
Copy link

You can preview 778149f at https://pr22214-778149f.ngbuilds.io/.

@mary-poppins
Copy link

You can preview fc8bc18 at https://pr22214-fc8bc18.ngbuilds.io/.

@vicb vicb closed this in a73d530 Feb 17, 2018
vicb pushed a commit that referenced this pull request Feb 17, 2018
@kara kara deleted the pureFunction branch October 13, 2018 01:09
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker cla: yes target: major This PR is targeted for the next major release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants