Short post on partial application in Ember templates

:wave:

My team and I had a discussion about partial application when working with Octane. I was inspired to write a short post about it on my personal blog. shameless self-promotion

If you have questions, critiques, or other feedback do respond here. I distrust 3rd party commenting solutions so prefer to discuss things in community spaces.

Thanks!

1 Like

Nice.

One way I like to explain fn by showing people how it would be implemented by itself in Javascript:

function fn(callback, ...presetArgs) {
  return function(...remainingArgs) {
    return callback(...presetArgs, ...remainingArgs);
  }
}
3 Likes

Thank you for posting that explanation @ef4! I had found {{fn}}'s definition but am not fluent in TypeScript. Yet.

I appreciate that simple explanation showcasing modern JavaScript.

Oh yeah, the implementation actually follows a pretty similar shape to my short example. To make the analogy, you need to compare with this whole block.

The main difference is that the real fn is written as an internal helper, which gives it direct access to the glimmer references. So where a user-authored helper just receives its arguments directly, an internal helper receives references that it needs to call .value() on to get their actual values. This makes internal helpers less pleasant to write, but also lets them do fancier things when deciding how to update efficiently.

1 Like

Such as performance optimizations? Or why I do not have to worry about the runtime performance of using {{fn}} in my application.

For fn it’s not a performance issue, it’s more about keeping track of what context we’re in so we can give good assertions.

But an example of a performance reason to work directly with references is the get helper. If you wrote your own:

function get(obj, key) {
  return obj[key];
}

you have a problem with making it update at the right time. You need some way to tell glimmer that your output depends on obj[key] changing, not obj changing and not key changing.

That’s what references can do natively, so the real implementation of get constructs a new reference out of its arguments, and that reference can reflect to glimmer exactly when it has changed and therefore downstream things need to rerender

1 Like