Re: Unordered setsmaps, for when ordering is hard/expensive/unwanted?

On Mon, Sep 2, 2013 at 1:03 AM, Brendan Eich <brendan@secure.meer.net> wrote:
>> Tab Atkins Jr. <mailto:jackalmage@gmail.com>
>> September 2, 2013 12:37 AM
>> 1. The property name->value map returned by getComputedStyle(). (As I
>> said, for normal CSS properties it's actually an object, not a Map,
>> for legacy reasons, but the same point holds, since there's still an
>> observable order.) There's an ordering for the individual properties
>> that enter the CSS cascade process, but not for the output of the
>> cascade, which is what gCS returns. For custom properties
>> specifically, defining an alternative order is expensive - we have to
>> define and invoke unicode-aware sorting solely to provide a
>> predictable order for the properties, which seems distasteful.
>
> Why do we have to do any lexicographic sort? CSS may underspecify the output
> of the cascade as reflected in the order of name/value pairs in the returned
> object (didn't know this) but if it's the same in browsers, or could be with
> small work, why not fix the underspecification?

I don't think it is the same in browsers, and from what I know (though
I can certainly be corrected), browsers do not preserve the necessary
information to preserve an ordering - as part of resolving the
cascade, property values get packed into optimized style-data objects
which contain a lot of bitfields and the like - no hope of retaining
ordering info there.  Current implementations of custom properties
handle them with whatever hashset impl the browser likes, which
returns things in whatever order the hashset likes.

Also, alpha-order has strong compat, I believe.  (Browsers still
differ on exactly *what* they return, but among the things they
return, they do it in alphabetical order.)

>> 2. I plan to define a FontSet API for exposing the loaded fonts
>> available to a given document/worker. This is a mix of UA-loaded
>> fonts, from @font-face rules in CSS, and author-provided fonts, from
>> explicit constructor calls (either referring to a font by url, or
>> constructing it straight from a TypedArray, for pdf.js use-cases).
>> It's possible to define an analog of "insertion order" at first as the
>> stylesheet-order of @font-face rules, but as you change what
>> stylesheets are loaded and load fonts manually, the ordering becomes
>> harder to define and racy.
>
> How racy? You wrote "available to a given document/worker", not shared
> mutable among workers -- right?

Definitely not shared mutable as in "the document and workers can both
mutate".  But I expect that we want to expose all the fonts from the
document's loaded CSS to workers automatically, and both the document
and workers should be able to insert manually-loaded fonts into their
local copies of the font set.

>> For example, what if you disable a
>> stylesheet, then re-enable it? Should the fonts generated by
>> @font-face rules in that sheet move to the end of the Set's ordering,
>> since they were "removed" and then re-added? This sort of ordering is
>> annoying to maintain, and of seemingly no value.
>
> Then don't do it, but taking either choice, there's no race here.

Right, my point there is just that it would be annoying and of little
value to maintain the "insertion order" semantic, at least in a strong
"what you would expose if you were polyfilling things" sense.

>> If you load a
>> stylesheet and a manually-constructed font, do you rely on execution
>> order of the load start to dictate the Set order, or race the network
>> loads against each other and insert them whenever the loads
>> individually complete?
>
> Obviously load start. Are you really planning to expose data races to JS?

I'm definitely not!  I was attempting to point out problems with
applying the "insertion order" semantic strongly.  If I go by load
start, does that mean that I must delay the second font showing up in
the list until the first load completes?

(Just to make sure - network races don't count as "data races", right?
 Network loads are observable in all kinds of ways, so it doesn't seem
feasible to try and hide their effects, beyond making it easy to *not*
race by providing good promise-based APIs for them.)

>> If we have off-main-thread parsing, or you're
>> in an isolated-process worker, can you get a manual load in the middle
>> of a stylesheet's parsing?
>
> Again, are you really planning to expose data races to JS?
>
> Bjoern's point stands: interop testing tends to forge de-facto standards, so
> adding a second underspecified order with Go-like random start is probably
> just going to fail to avoid a second de-facto-specified order. Then we'll
> have two standard orders, plus the random starting thing. Better to have one
> order.

I'd be interested in seeing what the actual experiences of Go projects
are.  I know, no language tiles the possibility space like JS does on
the open web, but still, if Go programmers have good experience with
their "random starting point", it's still evidence in the feature's
favor.

>> These two cases just recently came up in my work; I doubt they'll be the
>> last.
>
> I don't buy it. Either you are hiding a canonical order that could be
> specified, or talking about data races, which we do not want in any event.

If I was going to define a canonical order, it would be "all the fonts
coming from @font-face in stylesheet order, followed by all
manually-constructed fonts in construction order".  This definitely
doesn't conform to the "insertion order" semantic, though, as things
can appear in the middle of the list as you load more stylesheets into
the document.

And as I said, even if a canonical order can be specified, it might
not be worth specifying - invoking unicode-aware sorting just to
iterate through custom properties doesn't seem like a great use of
effort.

~TJ

Received on Monday, 2 September 2013 08:39:00 UTC