[Houdini] Minutes Berlin F2F 2018-04-09 Part II: Custom Layouts

=================================================
   These are the official Houdini Task Force
     minutes. Unless you're correcting the
      minutes, please respond by starting
 a new thread with an appropriate subject line.
=================================================


Custom Layouts
--------------

  - iank started by showing a demo of how he plans to have Custom
      Layouts be used. Demo code is here:
      https://github.com/GoogleChromeLabs/houdini-samples/blob/master/layout-worklet/masonry/masonry.js
      - iank plans to run benchmarking to figure out what speed
          improvement this introduces as well as to know if this is
          better handled through generators or through promises.

  - RESOLVED: Use the same worklet policy as Paint (with respect to
              selecting the global scopes: Issue #744)
  - RESOLVED: The instance is tied to the same policy as worklet
              swapping. (Issue #746)
  - RESOLVED: The lifetime of inputs and collections is the same as
              the policy for worklet swapping. (Issue #745)
  - RESOLVED: Accept the new parameter in
https://github.com/w3c/css-houdini-drafts/issues/747
              (Parameter is called LayoutOptions.sizing)
  - RESOLVED: No change on https://github.com/w3c/css-houdini-drafts/issues/748
              (Naming of LayoutFragment#inlineSize, blockSize)
  - The data returned in the LayoutConstraints object as defined by
      Houdini seems correct, even though there isn't compat on what
      produces the data and therefore data is different by browser.
  - RESOLVED: We will continue adopting generators for layout
              functions. (Issue #750: Generator vs. Promise design
              for the API)
      - Note that this resolution was intended to encourage further
          investigation around this topic and the group is open to
          re-investigating once there is more data.

===== FULL MINUTES BELOW ======

Agenda: https://github.com/w3c/css-houdini-drafts/wiki/Berlin-F2F-April-2018

Scribe: dael

Custom Layouts
==============

Demo
----

  iank: [shows demo] This was the simplest I could think of. There's
        a test class, 8 divs, display:layout.  It has a --padding
        property and a --columns property.
  iank: It's about 50 lines of code. [shows]
  iank: You can see we register the layout. We import properties
        --padding and --columns, we don't care about children.
  iank: Currently the constraints we're passing in has one useful
        thing. We're pre-calculating the inline size.
  iank: I added a thing where you can say you want the sizing to be
        1 and then you don't have to worry about sizing. Turns out
        to be useful because you don't have to worry about size.
  iank: The children all have style map, it contains nothing in this
        case. Only thing we have is the layout.
  iank: Next we're layout out all the children and forcing a fixed
        inline size on them.  It's fixed inline size/# columns.
        We're saying regardless of your max or min width you have to
        be this value.
  iank: Next thing is we've got all the fragments now, they have an
        inline size that we fixed it to. The block size,
        inline-offset and block-offset.  Everything is based on the
        parent's size.
  iank: We work through that and it returns the autoBlockSize. It
        takes the autoBlockSize and runs the sizing algorithm on
        it. Overflow is handled by the engine.
  iank: And that's it.

  smfr: Block and inline size is relative to the current layout.
  iank: Same with the inline offsets. It's relative to the current
        layout.
  iank: If we flip the direction or the writing mode, that works.
  iank: [shows flipping direction and writing-mode]
  Rossen: Awesome.

  smfr: How does validation work?
  iank: It works on the input properties as well as...basically it
        works with anything that changed in your inputs.
  iank: We've got the edges here that's the size of the box, the
        padding, etc. Anything in your style map or your children
        style map changes or you drop/add a child.
  Rossen: Is you made a content change you'd get call back with the
          same collection.
  iank: Yeah.

  iank: Edge case is if it contains size. All the standard
        validations.
  iank: We probably won't reach compat on number of times this is
        called and order. We've got different constraints.
  emilio: If you had the children with custom layout, can't you get
          into a situation where invalidating the children's style
          changes the parent and you get into a recursive situation.
  Rossen: No more then any CSS.
  emilio: Fair enough.

  iank: It is possible if trying to do perfect layout with a while
        looping. With this mode where you always have fixed inline
        size that's a little bit reduced.
  astearns: Is this what's in your github?
            https://github.com/GoogleChromeLabs/houdini-samples/blob/master/layout-worklet/masonry/masonry.js

  dbaron: With the invalidation it seems like you're doing normal
          layout validation less validating the input.
  iank: Exactly. When we recalc it goes through the properties and
        do style emulation.
  dbaron: To answer emilio in general in existing layouts there are
          cases where it invokes size on the child layout multiple
          times. As long as the parent knows how to handle any of
          the sizes you'll be fine.
  smfr: Can this run arbitrary script?
  iank: You're in sandbox. Everything is read only.
  smfr: On the main thread?
  iank: For us, yes. It's easier for that.
  iank: In a theoretical world you could have an engine with things
        that are asynchronous you could run this off the thread.
  flackr: Or you could parallelize.
  iank: Yeah.

  dbaron: Weirdest about this was how it uses generators,
          particularly where the non-final and final response have
          different semantics. For people seeing generators for this
          first time in this it's a horrible introduction.
  TabAtkins: It's using generators when it's semantically
             asynchronous.
  iank: Biggest problem I see...we can do either...biggest pro of
        generator is if other asynchronous things link into...if
        makes no sense to do a network request in the middle of
        layout. We're using promises for the engines that aren't
        able to handle it immediately.
  iank: We turned off things like dynamic import for worklets on
        thing link this.
  dbaron: Generator seems reasonable.
  iank: I'm fine either way. I want to do benchmarking and promise
        might work.
  dbaron: With generator each time it yields something the browser
          must process that before invoking again.
  iank: Yes. There's a layout fragment request. The engine processes
        that and next time it calls the generator it has to provide
        that. Promises have better error handling.

  majidvp: For your inputs is there a way to preserve the old ones
           and exit early?
  iank: You can't exit early. Fragments are only valid for one
        layout pass. Once the generator passes the elements get
        removed internally. If you try and invoke them later the
        engine says no, sorry.
  iank: What does make sense if...if you have from your style, if
        you've got something complex like manually passing something
        with a lot of overhead you can stash that on the instance.
  majidvp: The instance stays alive until the box?
  iank: Yeah, the box. Issue open for what is the lifetime for the
        issue, in this case the box.

  Rossen: Did you benchmark any of those?  If you just did normal
          block layout and you have the block size and you have 2d
          blocks, what's your expectation.
  iank: I would expect for simple block layout we'd be faster,
        that's my gut feeling, but I want to benchmark it.  If
        you're doing something very simple I expect this would be
        slightly faster.
  iank: This will be my performance test, my guess is custom layout
        is faster.
  iank: This is the amount of script, it's more complex then regular
        block layout. It depends on what outlining's cost is.
  Rossen: Cool.
  Rossen: If there's no more comments on the demo, we can move on to
          issues.

Need to select policy for selecting global scopes
-------------------------------------------------
  Github: https://github.com/w3c/css-houdini-drafts/issues/744

  iank: This one should be simple. Basically what is our policy for
        selecting global scopes? With paint API we set a policy that
        you must select between 2 and must not use more then 12
        times in a row. What would we say for layout.
  surma: Limit to 2000?
  iank: It's because you need "fewer" code you don't know where the
        state will be.
  dbaron: Because you want impl to be able to throw away that state.
          Webdev shouldn't debug against code that doesn't throw it
          away.
  surma: That's high.
  Rossen: That's why it's a not. If you're really constrained you
          can reuse it.

  Rossen: Why would layout have a different policy?
  iank: I don't think there's a reason. Same would be good.
  Rossen: I think this is how worklets works. Layout just follows.
  iank: Yeah. I think worklets is different because audio has
        different requirements. Whatever happens for the rendering
        type layouts.
  Rossen: Other opinions?

  smfr: If an author needs to do expensive computation it has to do
        it many times.
  iank: You can stash, but you have to be able to regenerate it.
  TabAtkins: You'll probably get some statements.
  smfr: So you'll have layouts that say every 30 times...
  Rossen: If you get called by 30 worklets with the same input you
          should work no matter the state of the layout.
  cbiesinger: We have the idea that some animations have a local
              state. The instance could provide a state object and
              if we construct we provide the state.
  iank: I think it's slightly different. With animation you want
        previous frame, but there's no reason you'd want that.
  smfr: There's a whole opportunity for custom layout like moving
        boxes.
  iank: That's fine if you feed the custom state.
  TabAtkins: If it depends on layout it will not let you cache as
             much.
  TabAtkins: [missed] The JS can send it straight in without
             redirecting through a custom property string.

  flackr: If we switch to worker2 and back to 1 is that the same
          instance?
  iank: That's the next issue.

  Rossen: Were there other reasons people believed we should have a
          different policy for worklets?
  dbaron: I wouldn't phrase it that way because worklets might be
          used more broadly,
  Rossen: Fair enough. No different policy the paint.

  RESOLVED: Use the same worklet policy as Paint

Lifetime policy for passed in objects, e.g. LayoutChild
-------------------------------------------------------
  github: https://github.com/w3c/css-houdini-drafts/issues/746

  iank: For a box with a layout instance it's tied to a lifetime of
        boxes. The box drops out of the tree.
  dbaron: This is the thing in the spec with a bunch of prose about
          these get cached by worklet and only cache is destroyed
          when box is dropped.
  iank: Yes. For example in our implementation if we have 2 layout
        level scopes both will have one instance. It lets you have
        expensive cached calculation = something
  iank: We could have a policy where we kill it every 1000 times and
        regenerate, but there's a value to keep them.
  dbaron: There's the same worry about layout global scopes...so if
          you're keeping worklet level every 1000 you'll get
          something after re-layout.
  iank: Yes. Is the global scope switching enough? Or do we want
        something more expensive.

  Rossen: Will you be allowed to reuse the worklet?
  iank: Yes. If you've got 2 boxes that run the same worklet, each
        will have its own instance.
  iank: A good example is 3. In our implementation we do specific
        caching on internals, you could do that here for layout
        reasons.

  fremy: Didn't we discussion a shared cache across worklets?
  iank: We did....
  Rossen: If what you want to share is the results...unless the read
          only cache is read/write that's okay. But then you will be
          producing a lot of generating. If it's read-only it has to
          be communicable. But that's a good first step.
  Rossen: In more complex layouts you have a ton of layout
          information you want to preserve between passes.
  iank: It's regenerateable.
  iank: That's why I prefer an instance that does live across many
        frames. Question is do we nuke this instance.
  Rossen: If I understand, the only cost we will have when we nuke
          the instance or somehow remove it, it's performant.
  iank: Yes. Should be cheap from our PoV to regenerate the state.
        That's the big question. This is somewhat edgecasey, but
        every minute need to recreate.
  Rossen: When we discussed 2+ worklets and all the costs, we did
          this for many reasons. Why should we change those for this
          case?  I would say for now carry the policy.
  iank: Policy doesn't require you to kill, just switch.
  iank: We're not wiping out a state we just have bad state.
  Rossen: My hope is anything you do that depends on global state
          should be discouraged. If we have an explicit reason we
          will care information on your behalf, that's fine. I don't
          see why this should be special unless we run into memory
          pressure. In that case you have to be prepared to
          regenerate.
  iank: Lifetime of the box unless UA needs to regenerate.
  iank: I'm also fine with that or just adding something
        preemptively.

  Rossen: If the stash will be not needed can't we make it explicit?
  iank: It is.
  Rossen: But if you have a stash that's necessary...if they have a
          stash where these are the things I spent 40 minutes
          calculating the perfect size and I want to preserve it...I
          can have all kinds of other garbage you shouldn't retain.
  iank: But people that have cached, we can always be there later.
  iank: Fine with tying lifetime to the box?
  TabAtkins: No worse then globals
  Rossen: What is lifetime of the box?
  emilio: Blink only destroys tree when display changes. So if you
          change display any parent box will be dropped.
  iank: Might be a reason why we nuke the instance every 1000 times.
        You drop the box on resizes?
  Rossen: Yeah.
  iank: May be why we drop periodically.

  iank: Reuse the instance no more then 1000 times as the policy?
  dbaron: How can you reuse more?
  iank: Global scopes changes, but don't tear down. Here we're
        saying you reached the max and we're going to tear it down
        and rebuild.
  dbaron: Might be good to have a sentence or two with explaining
          the algorithm.
  iank: Yeah.
  dbaron: As a reader if there had been 2 sentences explaining the
          algorithm I wouldn't have had to read the algorithm.
  iank: Reuse the layout instance no more than 1000 times, after
        that you must regenerate.
  Rossen: Or drop whenever you switch worklets.
  Rossen: Other suggestions? prop: The instance is tied to the same
          policy as worklet swapping.
  iank: Not explicitly.
  Rossen: If you switch event 1000 times you get it 1000 times.
  iank: I'm fine with that.
  Rossen: Let's see how it goes. If performance is decremented then
          let's discuss it. It's always easier to relax later.
  Rossen: Objections?

  RESOLVED: The instance is tied to the same policy as worklet
            swapping.

Lifetime for passed in arguments to layout, intrinsicSizes
----------------------------------------------------------
  github: https://github.com/w3c/css-houdini-drafts/issues/745

  iank: We've got a bunch of objects passed in. layoutChildren most
        interesting. You may want something similar as layout
        instance where you get passed the same child every time.
  Rossen: Or I can stash all the children and look them up.
  iank: But if you pass in new children you can't.
  dbaron: If you have this cache you need to define child ID
          carefully. If a child changes display type do you get a
          different child, if it changes overflow  do you get a
          different child?
  dbaron: Is this like, “do you have a different box type”?
  iank: Yes.
  dbaron: “Do you have a different box type” isn't interoperable.
          Blocks with and without scrollbars are different in Gecko.

  cbiesinger: Does the calculation matter on times when the child
              would change?
  iank: The reason you want to use this cache is similar to the grid
        example where from this current layout you want to
        calculate something based on the child's style.
  cbiesinger: You would need to store the old value for that case
  <dbaron> (cbiesinger was asking about the risk of a developer
           caching something that might not be valid after certain
           types of changes)
  iank: Right, but string comparison is cheaper then regenerating the
        object.
  smfr: Layout child isn't exposed to different custom layout, right?
  iank: Right. There's like 2 or 3 policies here. Like the others we
        can regenerate each time. There's also a question about passing
        in same style map.  We can start with regenerating each
        argument call and try to loosen.

  smfr: In the JS can't you say it's read only?
  iank: Yes, but you can use layout child as a key still.
  smfr: [missed]
  iank: Yes but this instance.
  smfr: Pure read-only is good. Caching should be like an API. You
        want the performance guarantee that when you run the code
        it'll go fast.
  iank: Cache has structure which is expensive.
  iank: We've made it faster, but it's not as quick.
  majidvp: You only have to clone the structure when moving global
           scope.
  iank: The object will always be alive. So you have to call every
        time.
  majidvp: You need to serialize and then destruct.
  iank: You have to serialize it out.
  majidvp: Cache is strictly there to help you cache the structure.
  iank: If you go back to you can twiddle things on the object then
        you can stay there.
  iank: That's why I'd like to keep this object for stashing state.

  smfr: Consistent but slow re-serialization or a faster but
        hiccupy. I'd prefer the consistent approach.
  iank: If we regenerate each time it depends on number of children but
        it can be much slower.
  iank: I can benchmark, but my hunch is creating them each time
        rather then trying to cache it'll be a substantial
        difference.
  smfr: You'll pay that in the long frame, though.
  iank: Yeah. But if you have something deeply bad you'll get it.

  smfr: I think these APIs are problematic if they're not
        performance guarantees. If the author wants to do a good job
        and they're penalized everything 39th frame...
  iank: That's why you may want to keep the instance around so when
        scope switching you get the guarantee. You've got an
        instance tied.
  smfr: 2 instances will have the author really confused.
  iank: If the author never recalcs from the complex thing then you
        get [missed]

  iank: What do you want to do?
  Rossen: Since you're the furthest in impl, what do we know so far
          in terms of requirements, expectations, and patterns.
  iank: We've got more people using it. We might give this to people
        and see if they run into issues.

  Rossen: To smfr's point and I sympathize, it should be fine to
          allow custom layout or paint to pass different information
          between passes.
  Rossen: We have a few issues. One of defining what the lifetime of
          the boxes are if this will tie in lifetime of other
          objects. This is the point dbaron was making. You'll
          regenerate boxes different times than Gecko. That's not to
          say the instances we keep should have same lifetime. That
          can be based on something else like a display property
          changing.
  Rossen: That will get us into trouble as custom properties are
          more common so we'll again be in a tight place for
          lifetime.
  Rossen: Other option is to say we have a policy that you need to
          redo everything at a certain time and that's a fine
          expectation.
  Rossen: I prefer to be as aggressive as possible on cleaning up
          and resetting. If the explicit stash is needed, define
          that, give that API, and let people stash something
          besides custom properties.
  Rossen: We don't penalize people running on an awesome device.  If
          we do have to have penalties we have information about
          what we need to keep.  Seems like the best compromise on
          both sides of the fence.
  iank: We can tentatively do that for now and see what happens.

  Rossen: If we want a resolution, not just a tentative what does it
          mean.
  Rossen: We can introduce and explicit cache which re-writes cache.
  iank: I don't think we want that yet.
  Rossen: Even better.
  iank: For now instances and layout children get nuked when we
        switch global scopes.
  smfr: Why not new children and instance on invocation?
  iank: I'm worried about performance. Invoking a constructor is a
        few ms each time.
  iank: Let's start with we nuke everything when switching global
        scopes.
  Rossen: Only thing we're adding is that input are also new
          instances.
  Rossen: smfr?
  smfr: I'd prefer the super clean APIs where everything is done
        internally. Authors won't be surprised. If we do anything
        else they will get confused.
  iank: Should we see if authors will get confused?
  smfr: If you can find some that are fresh.
  iank: We can do an origin question and find out.
  Rossen: Not per call?
  iank: Yep.
  Rossen: Objections to the lifetime of inputs and collections is
          the same as the policy for worklet swapping?

  RESOLVED: The lifetime of inputs and collections is the same as
            the policy for worklet swapping.

  <br type="lunch">

Review the LayoutOptions.sizing parameter
-----------------------------------------
  github: https://github.com/w3c/css-houdini-drafts/issues/747

  iank: This is...we had one layout option for the child display.
        This is one mode I think we should add that flips the type
        of sizing you default to.
  iank: As I was building examples it's really nice if you don't
        have to worry about your size. block-like is handled for you.
  iank: Like in my earlier demo you're always given a fixed size and
        you're given an auto block size.
  iank: Thing that makes it more custom is a manual sizing mode
        where you explicitly say the sizing.
  iank: If we use block-like initially it makes it a lot easier on
        impl to do it this way and less compat risk.
  iank: Is there any feedback?

  smfr: Minor objection to size as a word since it's height and width
  iank: This is the engine taking care of the size.
  smfr: But it's a scalar.
  dbaron: CSS is using block-size already.
  smfr: What happens with a discretionary of auto block-size?
  iank: In block-like it takes care of it for you. In some
        circumstances you'll get a fixed size like abspos and you're
        constraining the block.
  iank: I think for compat risk we'd want block-like as a default.

  Rossen: This sounds more like native layout. Sizing and
          positioning are parts of layout, but you're not talking
          positioning. Engine for layout more for native layout mode
          or something like that for the name.
  Rossen: Instead of 'sizing' to imply I want you to do layout on my
          behalf and the type of layout is block-like.
  iank: It's not simply layout. It's also the size of your fragment.
  iank: That's why I sort of....
  Rossen: ...Okay.
  iank: I'm fine calling it something else.
  Rossen: I see what your intention was.
  iank: With this sizing is block-like it's computed as if you were
        a block container and that's pre-computed.

  Rossen: So if you happen to be a flex-item all the flexing will be
          ignored?
  iank: If you're a flex-item the engine can work out ahead of time
        what your size is going to be. If there's flexing that fixed
        inline size will be increased by the flex amount. Inline
        synthesis is handled by the engine and all you need to do is
        the flex size and that follows the same rules as the block
        size.
  Rossen: I guess it's okay
  iank: You lose a little bit of power.
  iank: It also allows if we're defaulting like servo can do it's
        inline sizing pass at the moment. From what I've used it's
        much easier and a lot less work. What it gives you is what
        you want 95% of the time.
  Rossen: Was this edited in?
  iank: Yes.
  Rossen: Objections to accepting this new parameter?

  RESOLVED: Accept the new parameter in
https://github.com/w3c/css-houdini-drafts/issues/747

Naming
------
  github: https://github.com/w3c/css-houdini-drafts/issues/748

  iank: One feedback from Travis at TAG found it not saying
        border-box confusing.
  dbaron: Yeah.
  dbaron: As someone that works on layout code I'm used to knowing
          you have to work with border-box and you don't type it.
          Travis was looking at it further away from layout and he
          found it confusing.
  dbaron: I lean toward disagreeing, but if we change it should be
          sizes and positions.
  iank: Agree.
  iank: Unless webdev are really confused I'd lead toward us being
        shorter here.
  Rossen: If anyone goes to extent of understanding what layout
          fragment is I have a hard time believing that person would
          struggle.
  plinss: It's just knowing the difference of border and content
          box. Then what about box sizes and what do you do. Looks
          like it's more clarity.
  Rossen: Someone going through learning phases.
  Rossen: Objections to no change?

  RESOLVED: No change on https://github.com/w3c/css-houdini-drafts/issues/748

  iank: Any tag feedback we should discuss?
  dbaron: Let me see
  [discussion around next topic]

LayoutConstraints object - Are we ok with exposing information we
    don't have compat on?
-----------------------------------------------------------------
  github: https://github.com/w3c/css-houdini-drafts/issues/749

  iank: All engines have pretty good compat...what we'll pass
        through LayoutConstraints object...
  iank: When it's non-orthogonal writing modes we have pretty good
        compat on what we'll resolve inline percent and block
        percent to.
  iank: Problem is with orthogonal writing modes.
  iank: A few cases in the issue, we have nowhere near compat.
  iank: First example is what we resolve percent to.
  iank: Padding in this example is completely different on all
        engines.
  iank: Not arguing about who is right, I made lots of test cases
        yesterday and they're very simple.
  <gsnedders> iank: plz make sure all these tests are in WPT

  iank: Do we want to get compat here first? Go back and not expose
        this initially and just use layout sizing as block-like? Are
        we fine exposing this knowing that orthogonal won't be
        common?
  fantasai: I'm confused. Spec is clear.
  iank: No one follows spec.
  dbaron: Seems silly to remove the feature for that reason. It
          should be clear what the spec says should happen in that
          case.
  iank: Half the comments on the spec...like Size with percent size
        is one area of compat. For writing modes we only talk about
        available space.
  dbaron: I think, it might be worth thinking about which thing
          makes the most sense in the API. Do you want the thing
          based on the parent's writing mode or your own?
  iank: It looks at everything in your own writing mode, but all
        engines have different conversion.
  iank: Here's a good example where percent resolution for
        padding-left:10% varies. But the size you should resolve
        against isn't defined.
  fantasai: Flexbox issue.
  emilio: That was fixed recently in FF. If you test the nightly.
  iank: There's other cases here as well.
  iank: I'm fine with exposing all this, but it may be a while until
        we're toward compat.
  iank: Other option is strip LayoutConstraints and its just the
        fixed layout size and the engine handles it's quirks for you.

  majidvp: Is there a way inside the worklet to detect UA?
  iank: Only if you pass in a property.
  iank: Initially given the state of compat I'd only feel
        comfortable exposing the simple layout and forcing
        block-like on everyone.
  iank: Keep in mind this is only input going in. For giving inputs
        to reach children I think we can reach compat there.
  [silence]
  dbaron: I'm not convinced that the compat problems are that severe.
  dbaron: If Houdini specs are clear what these things mean people
          impl the Houdini bits can be clear.
  Rossen: You're saying code should work regardless of the inputs.
          If we need different inputs for different engines your
          code should do something right. It's to our benefit to
          work out compat bugs regardless of Houdini.
  dbaron: Gecko has a data structure with this in the parent vs
          other have in the child's writing mode. If the spec is
          clear you can do the right thing.
  iank: Yes. Engines can give you different things for different
        stuff.
  Rossen: So that's no change?
  iank: Yes. I need to write tests to make sure my interpretation is
        right.
  iank: Issue is not an issue.

Generator vs. Promise design for the API
----------------------------------------
  github: https://github.com/w3c/css-houdini-drafts/issues/750

  iank: From the author PoV...
  Rossen: The only difference is you added a *
  dbaron: You need an async in the second line.
  iank: True.
  iank: These are the pros and cons [further down the issue]
      Generator:
          Pro: May be faster wrt. bindings.
          Pro: More restrictive API, can't await on other APIs which
               might leak into the LWGS.
          Con: Less obvious error handling to for web developers.
          Con: Less obvious API as this pattern isn't common, and
               not many people use them (generators).
      Promise:
           Pro: More obvious error handling.
           Pro: Common pattern for developers.
  iank: If anyone else has something to add here, I'll come back to
        the next meeting with data.

  Rossen: Are generators broadly impl?
  iank: Yes.
  iank: Everyone does generators, though they haven't been used like
        this before.
  TabAtkins: We won't expose the functions you can't run.
  iank: We'll have to make sure in the future. We have to code with
        eyes open.

  fremy: You like this better because you can only allow some things
         to be sent?
  iank: It makes a tighter API. Promises are more familiar.
  fremy: Dev are familiar with converting in the background
  dbaron: After thinking about this, I'm feeling like the way devs
          interface with the engine here feels better described by
          generator and not promise.
  dbaron: I think because promises have this tie to an event loop
          thing where promises are running asynchronous on this
          micro-task. You're in the middle of this thing in the
          layout engine and it needs to call you many times.
  surma: I agree you're generating the list.
  TabAtkins: You're not though. We can call you fresh.
  surma: That's details. Conceptually it works as a generator.
  surma: I'm wondering if there's a place where scheduling with
         promises may become and issue and it wouldn't with promises.
  iank: I think there's work in FF to work promises at the right
        time. For the synchronous engines we would all the layout
        engine, make sure task queue is exhausted, make sure we've
        got a promise.
  surma: It makes more sense with generators even if it's 100%
         correct.
  dbaron: I think one of the weird things about generator is it
          produces the last thing at the end. You're using yield and
          return syntax to do much deeper things.
  TabAtkins: The yield at the top of the issue is not usefully
             yielding into the engine. It's saying do this layout
             and give me results. It's using a generator as an
             asynchronous iterator. It's possible, but not the
             preferred pattern.
  TabAtkins: It off doing it's own thing. If it was synchronous we
             wouldn't have to do this.
  surma: Both allow us to think about asynchronous and parallel
         layouts in the future?
  iank: Yeah.

  Rossen: I'm hearing mostly people leaning toward generators.
  TabAtkins: No.
  Rossen: Except TabAtkins.
  iank: We can also give two different versions and see what people
        expect.
  Rossen: TabAtkins would you object? Any objections?
  TabAtkins: I have weak objection and would like wider review.
  Rossen: Has there been review? TAG looked, did they say anything?
  Rossen: I went through Travis's comments and they were high level.
  dbaron: I don't remember this one.
  iank: I think notes from the TAG meeting are up.
  [everyone hunts meeting notes from TAG]
  dbaron: Minutes say "Travis: I have some review feedback to post
          to the issue."
  dbaron: We came back to it the next day, though.
  <dbaron> TAG minutes in
https://github.com/w3ctag/meetings/blob/gh-pages/2018/04-tokyo/04-06-minutes.md
  iank: [skim-reads]

  Rossen: There's a couple ways to get out. 1) We agree to adopt
          promise-based API 2) We stick with generators with a light
          objection from TabAtkins and then he can figure out if we
          should avoid it. If he comes back with reasons and we can
          change.
  TabAtkins: I'll bother Dominic.
  Rossen: Sticking with Generators will force the discussion.
  Rossen: Do we have people that object to promise-based APIs?
  TabAtkins: Performance aspect.
  iank: I want to do some benchmarking.
  iank: I think layout will be particularly sensitive to bindings.
  TabAtkins: My hope is we don't need to re-apply promises.
  iank: We might need special APIs.
  iank: I'll have everything hopefully done.
  Rossen: Prop: We will continue adopting generators for layout
          functions. TabAtkins will followup

  RESOLVED: We will continue adopting generators for layout
            functions.

Received on Thursday, 26 April 2018 00:28:21 UTC