00:01
<jtcranmer>
it's not hard if you use generators and promise wrappers
00:03
<TabAtkins>
Promises are just a standardized abstraction over callback-based code, so whatever you've figured out for that, you can use for Promises.
00:09
<Domenic>
Hixie_: PromiseBuiltinCapability() is a way of creating a record containing { [[Resolve]], [[Reject]], [[Promise]] } where the first two control the fate of [[Promise]]
00:10
<Domenic>
Hixie_: PromiseCatch(p, f) should be the same as p.catch(f), aka p.then(undefined, f), except it will work even if someone messes with the Promise global
00:10
<Hixie_>
TabAtkins: i've never had to trace code as complicated as the loader stuff in the ES6 spec before, so it's never come up...
00:10
<Domenic>
Hixie_: thus, returning PromiseCatch(p, f) will return the derived promise generated
00:11
<Domenic>
Hixie_: PromiseThen(PromiseOf(undefined), F) should be equivalent to EnqueueJob(<job_that_calls_F>, "PromiseTasks") I am pretty sure
00:11
<Hixie_>
Domenic: but PromiseBuiltinCapability() takes no arguments, so wtf are [[Resolve]], [[Reject]], and [[Promise]] ?
00:11
<Hixie_>
Domenic: and why would you ever need such a record
00:11
<Domenic>
Hixie_: it is a way to create new promises, along with the things that control them
00:11
<Hixie_>
there has got to be a simpler way to spec that
00:12
<Domenic>
Hixie_: it is equivalent to `function promiseBuiltinCapability() { var resolve, reject; var promise = new Promise((resolve_, reject_) => { resolve = resolve_; reject = reject_; }); return { promise, resolve, reject }; }`
00:12
<Domenic>
It is only necessary because the ES spec doesn't have closures
00:13
<Domenic>
so it is easier to create these capability records and use them in a linear fashion, than to nest your code inside `var promise = new Promise((resolve, reject) => { /* oh no closures my only weakness */ })`
00:13
<Hixie_>
Domenic: i've no idea what that code does
00:13
<Hixie_>
Domenic: it looks like perl
00:13
<Domenic>
Hixie_: well, OK, guess it wasn't helpful. But, it will give you an object { promise, resolve, reject }
00:13
<Domenic>
where promise is pending
00:13
<Domenic>
and resolve and reject change the fate of promise
00:14
<Hixie_>
but what are resolve and reject?
00:14
<Domenic>
resolve is a function that resolves promise; reject is a function that rejects promise
00:14
<Hixie_>
what do "resolves promise" and "rejects promise" mean?
00:14
<Hixie_>
and why can't that just be built-in to promises?
00:14
<Hixie_>
i don't understand why there has to be all these explicit functions internal to the spec
00:15
<Hixie_>
instead of just saying "return a new promise"
00:15
<Domenic>
ignoring the case where you call resolve(anotherPromise), "resolve promisewith x" means "the promise will be successfull, with x" and "reject promise with x" means "the promise will fail, with r"
00:15
<Domenic>
where "successful with x" means when you do p.then(onSuccess, onFail), onSuccess gets called with x
00:16
<Domenic>
these can't be built in to promises because then anyone could resolve a promise, which is bad---a promise's fate should only be determined by the person who creates it
00:16
<Hixie_>
i don't mean "built in" as in "exposed as an api"
00:17
<Hixie_>
i mean, just part of the definition of the spec concept
00:17
<Hixie_>
the spec right now is so utterly convoluted
00:17
<Domenic>
Ah. They are. You can just do ResolvePromise(p, x)
00:17
<Hixie_>
so why does the spec go through all these crazy hoops
00:17
<Domenic>
I am not sure what context you are seeing them used where the PromiseCapability is used
00:17
<Hixie_>
instead of just saying that
00:17
<Domenic>
One possible reason is because you might need to pass capability.[[Resolve]] to a real user
00:18
<Domenic>
Another might be that it hasn't had a chance to go through review; I believe the module loader section of the spec is in the process of being handed over from jorendorff to allenwb
00:18
<Hixie_>
e.g. ProceedToLocate() calls PromiseOf(undefined) which calls PromiseBuiltinCapability() which calls CreatePromiseCapabilityRecord() which is an 11-step algorithm
00:19
<Hixie_>
but i don't see why ProceedToLocate() can't just say "create a new promise" and the spec say somewhere that "a new promise is something that looks like _bla_"
00:19
<Hixie_>
without any need for these "Let constructorResult be the result of calling the [[Call]] internal method of constructor, passing promise and (executor) as the arguments" steps
00:19
<Hixie_>
whatever that means
00:20
<Domenic>
Not everyone hates formal language
00:20
<Domenic>
"create a new promise," backed by lots of implicit knowledge, is not really any better than PromiseOf(undefined), backed by explicit steps
00:21
<Hixie_>
this isn't a formal language though
00:21
<Hixie_>
it's still just english
00:21
<Domenic>
It's very close to one
00:21
<Domenic>
The steps correspond almost 1:1 with (unoptimized) implementation code
00:22
<Domenic>
compare https://github.com/domenic/Array.prototype.contains/blob/master/spec.md and https://github.com/domenic/Array.prototype.contains/blob/master/reference-implementation/index.js
00:23
<Hixie_>
that's unfortunately not a benefit
00:23
<Hixie_>
but whatever
00:23
<Hixie_>
my feedback is that the spec is unreadable :-)
00:24
<Domenic>
the barrier to entry is certainly high
00:24
<Domenic>
and i could believe that the sections you're looking at are particularly bad
00:25
<Hixie_>
right now i'm still trying to figure out what the Loader Record is created
00:25
<Hixie_>
s/what/where/
00:25
<Hixie_>
i'm trying to trace execution of the module loading stuf
00:26
<Hixie_>
i started at RequestLoad(), and i've traced it down to UpdateLinkSetOnLoad() on one side and InstantiateSucceeded() on the other
00:26
<Domenic>
I wonder if it'd be easier to trace by using a debugger against a polyfill
00:26
<Hixie_>
(no sign yet of a loader being created)
00:27
<Hixie_>
btw the kind of thing i mean when i say it's not a formal language is "Let body be the result of parsing load.[[Source]], interpreted as UTF-16 encoded Unicode text as described in 10.1.1, using Module as the goal symbol. Throw a SyntaxError exception if the parse fails or if any static semantics errors are detected."
00:27
<Hixie_>
bbl, gotta go
00:28
<Hixie_>
thanks for the help btw
00:28
<Domenic>
kk, gl hf
00:28
<Domenic>
hope jorendorff clears things up tomorrow :)
00:47
<MikeSmith>
explicit functions internal to the spec" is the style the entire ES spec's written in, isn't it? seems like anything new that's added needs to follow the same style. unless the whole spec is rewritten
01:26
<caitp>
it probably should be reimagined completely
01:26
<caitp>
it won't be, but it would be a net positive
05:21
<caitp>
did http://www.w3c-test.org break or something? seems to be broken in canary at least =(
05:21
<caitp>
looks like it's not serving MANIFEST.json
05:22
<caitp>
guess I'll just run my own :u
05:26
<Streusel>
the site works, can't find any manifest.json though.
05:34
<MikeSmith>
caitp: w3c-test.org gets wedged sometimes. I may need to just restart the server
05:34
<MikeSmith>
but it looks fine to me right now
05:35
<caitp>
I get a 404 for MANIFEST.json, and subsequent reference errors because of that
05:35
<caitp>
(using the test runner)
05:36
<MikeSmith>
that's because there's no MANIFEST.json file
05:37
<caitp>
yeah, which the runner seems to need, thus no good right now =P but it's alright
05:37
<caitp>
not going to hack on more test failures at 2am on a friday anyways, nite
05:41
<MikeSmith>
so it looks like some recent change to the tools/scripts/manifest.py script broke the manifest build
05:41
<MikeSmith>
and so the MANIFEST.json file's not getting regenerated
05:41
<MikeSmith>
I get the same error locally
05:41
<MikeSmith>
File "tools/scripts/manifest.py", line 565, in update_manifest
05:41
<MikeSmith>
manifest = load(kwargs["path"])
05:41
<MikeSmith>
KeyError: 'path'
05:42
<Streusel>
interesting array name
05:43
<MikeSmith>
that's not some built-in python array?
05:44
<Streusel>
I don't have a clue about python and their arrays, although I would assume it works like any other, I just thought the name was interesting
05:44
<MikeSmith>
https://github.com/w3c/web-platform-tests/commit/acbcad1cb71c6eebd2a63c5cf16ea7f366812f48
05:45
<MikeSmith>
committed without review
05:46
<Streusel>
9 days ago, and was only caught now? o-o
05:47
<MikeSmith>
I've been away for a week, and left Ms2ger in charge :)
05:51
<MikeSmith>
looks like the code's supposed to just use a default if no path value is explicitly specified from the command line
05:51
<MikeSmith>
https://github.com/w3c/web-platform-tests/blob/acbcad1cb71c6eebd2a63c5cf16ea7f366812f48/tools/scripts/manifest.py#L579https://github.com/w3c/web-platform-tests/blob/acbcad1cb71c6eebd2a63c5cf16ea7f366812f48/tools/scripts/manifest.py#L579
05:51
<MikeSmith>
but it seems to not be doing that
05:52
<MikeSmith>
ah wait that's just when it calls the parser
06:01
<zcorpan_>
hsivonen: ping http://krijnhoetmer.nl/irc-logs/whatwg/20140805#l-400
07:05
<Ms2ger>
MikeSmith, I'm pretty sure that https://github.com/w3c/web-platform-tests/commit/acbcad1cb71c6eebd2a63c5cf16ea7f366812f48 doesn't break anything that worked before
07:42
<Ms2ger>
MikeSmith, and reviewed at https://github.com/w3c/web-platform-tests/pull/1133
07:43
<MikeSmith>
ok
07:44
<MikeSmith>
Ms2ger: so I guess I'll need to figure out what earlier change it was that actually did break it
07:44
<Ms2ger>
There's a pointer in my commit message :)
07:45
<MikeSmith>
ah ok
08:21
<MikeSmith>
um
08:22
<MikeSmith>
Ms2ger: in fact your change is what broke it, as far as I can see
08:23
<MikeSmith>
Ms2ger: if I check out the parent of that commit, the script was still working then
08:26
<Ms2ger>
MikeSmith, how? It tried to fetch opts.foo, and opts isn't declared anywhere
08:27
<MikeSmith>
Ms2ger: dunno but apparently it did work
08:28
<Ms2ger>
Can you print opts.path there?
08:28
<MikeSmith>
sure, gimme a second
08:29
<MikeSmith>
opts.path: /opt/workspace/web-platform-tests/MANIFEST.json
08:31
<Ms2ger>
Huh
08:31
<Ms2ger>
Oh, I see
08:32
<MikeSmith>
seems like opts is assigned on line 599 or so..
08:32
<Ms2ger>
MikeSmith, at line 600, add path=opts.path
08:32
<MikeSmith>
initialized
08:32
<MikeSmith>
ok
08:34
<MikeSmith>
success
08:34
<MikeSmith>
if you commit that I'll review it
08:35
<Ms2ger>
I was just going to suggest the opposite, but sure :)
08:35
<MikeSmith>
heh
08:39
<Ms2ger>
r? https://github.com/w3c/web-platform-tests/pull/1163
08:47
<hsivonen>
zcorpan: pong
09:04
<Ms2ger>
Does anyone else than Gecko and Servo implement new Document()?
09:06
<zcorpan>
hsivonen: what is the 8 ball verdict for today?
09:38
<annevk_>
jtcranmer: from the top of my head, per the URL Standard those are not equivalent, the first normalizes to fass.de
12:21
<Ms2ger>
zcorpan_, r? https://critic.hoppipolla.co.uk/r/378
12:22
<zcorpan_>
Ms2ger: done
12:22
<Ms2ger>
Ta
12:23
<Ms2ger>
zcorpan_, https://critic.hoppipolla.co.uk/showcomment?chain=669 is done now, right?
12:30
<zcorpan_>
yes. resolved it
12:41
<Ms2ger>
Thanks!
12:50
<JakeA>
annevk: when you said new WindowClient(), were you thinking of that being ServiceWorker only or on Window too?
16:19
<smaug____>
Domenic: I don't know where you get your idea the output is the thing to read data from. https://github.com/sysapps/tcp-udp-sockets/issues/69
16:19
<smaug____>
never seen that elsewhere
16:19
<Domenic>
smaug____: things come out ... of the output ...
16:19
<smaug____>
fprintf(stdout, "foo")
16:20
<Domenic>
right, then the user reads from standard out, after someone put something there for them to read from
16:20
<smaug____>
API user doesn't read from stdout, in general
16:20
<smaug____>
one writes to output
16:20
<smaug____>
read from input
16:20
<smaug____>
that is how APIs work
16:21
<smaug____>
no reason to make web APIs work differently than rest of the world
16:21
<Domenic>
the java example in that threat is making me reconsider
16:21
<Domenic>
i agree no reason to depart from other programming models
16:21
<smaug____>
fprintf(stdout, "foo") is just the same as the java case
16:22
<Domenic>
the java example is general
16:22
<smaug____>
except that C is ancient
16:22
<Domenic>
stdout/stdin is an odd case, or so i thought
16:22
<Domenic>
i will need to do some research, as it is still mind-boggling to me that the consumer would write things *in* to the *output*... the *producer* would do that, sure, but not the consumer
16:23
<smaug____>
I've never seen any IO library which reads from output and writes to input
16:23
<smaug____>
in general
16:24
<smaug____>
of course one can do some piping (sp?) in which case you write to output and then read form the same stream elsewhere
16:41
<netzhuffle>
hi, Question: Why is the picture element only under whatwg.org/specs but not under developers.whatwg.org?
16:43
<Ms2ger>
Looks like the devs version is from 20 July
16:47
<netzhuffle>
Ms2ger: can I find that date somewhere?
16:47
<Ms2ger>
I found it in a comment at the bottom of the page
16:49
<netzhuffle>
I see, thanks :)
16:49
<netzhuffle>
is it regenerated automatically or manually?
16:50
<Ms2ger>
I don't know what the current situation is
18:06
<Hixie_>
jorendorff: i'm here
18:06
<jorendorff>
OK! I'm ready
18:07
<Hixie_>
i've been trying to trace how the loader works
18:07
<Hixie_>
right now i've got http://www.gliffy.com/go/publish/6036438
18:07
<Hixie_>
(scroll down a bit)
18:07
<Hixie_>
what i am primarily looking for right now is "what creates the Loader?"
18:09
<smaug____>
Why does postMessage work still on a closed BroadcastChannel
18:09
<smaug____>
somewhat odd
18:09
<smaug____>
I would expect some exception
18:10
<Hixie_>
that does sound wrong
18:11
<Hixie_>
yeah that's an oversight
18:11
<Hixie_>
file a bug?
18:11
<smaug____>
ok
18:12
<Hixie_>
thanks!
18:13
<jorendorff>
Hixie: There's just one Loader and it's used again and again.
18:13
<Hixie_>
where is it created?
18:13
<jorendorff>
It's not, in ES6. ES6 doesn't specify anything about it.
18:14
<Hixie_>
so, if i create it, how do i pass it to ES6?
18:14
<jorendorff>
reading a bit
18:15
<jorendorff>
Hixie_: Do you call (or plan to call) "Initialization"? http://people.mozilla.org/~jorendorff/es6-draft.html#sec-initialization
18:15
<Hixie_>
i don't do anything yet
18:16
<Hixie_>
i'm waiting for allen to update the spec like he said he would before i try to reference it
18:16
<Hixie_>
(that involves changing that part, amongst others)
18:18
<Hixie_>
jorendorff: btw, when the spec says things like "Return ProcessLoadDependencies(load, loader, depsList)", does it mean to return the result of calling that operation, or to return a reference to that operation bound to those arguments?
18:18
<jorendorff>
Return the result of.
18:18
<jorendorff>
Hixie_: OK. So, one thing "Initialization" does is create the initial Realm.
18:19
<jorendorff>
A Realm is a global and all the associated junk
18:19
<Hixie_>
allenwb assures me that that initial realm is ignorable
18:19
<Hixie_>
because it's never used
18:19
<jorendorff>
oh, is he going to delete that?
18:19
<Hixie_>
i think he wants to keep it for node.js or something
18:20
<jorendorff>
Hixie_: ...great.
18:20
<jorendorff>
Hixie_: In any case, when you create a realm...
18:20
<jorendorff>
there's no loader initially; what HTML has to do is make one, and then set the realm's [[Loader]] to it.
18:21
<Hixie_>
where does the realm get created?
18:22
<jorendorff>
Hixie_: (this is not terribly familiar stuff to me)
18:23
<Hixie_>
who is it familiar to? everyone i speak to says that. :-/
18:23
<jorendorff>
Hixie_: My guess is, dherman or allenwb wrote all this.
18:24
<Hixie_>
is anyone implementing it?
18:24
<Hixie_>
i mean, they're the people who'd be most familiar with it...
18:24
<jorendorff>
Hixie_: I want to implement Reflect.Realm because I think it's cool, there's a guy at Moz interested, but it's just not done yet
18:24
<jorendorff>
I mean the *spec* isn't shovel-ready
18:25
<Hixie_>
ah
18:25
<Hixie_>
maybe i'm just doing all this too early
18:25
<jorendorff>
I can tell you generally how it's supposed to work
18:25
<jorendorff>
HTML must have stuff that happens when a new window or iframe is created, so a new Window is needed
18:25
<Hixie_>
what i am really trying to do ultimately is extend the module system so that it's the same system that handles loading e.g. images and style sheets
18:25
<jorendorff>
yes
18:26
<jorendorff>
well, the Loader stuff at least has some concrete semantics, though it's been 100% stripped of comments
18:26
<Hixie_>
"When a browsing context is first created, it must be created with a single Document in its session history, whose address is about:blank, which is marked as being an HTML document, whose character encoding is UTF-8, and which is both ready for post-load tasks and completely loaded immediately, along with a new Window object that the Document is associated with."
18:26
<Hixie_>
looks like allen said i then had to do some of the steps of 8.5 Initialization, in particular calling 8.5.1 InitializeFirstRealm ( realm ) after calling CreateRealm().
18:26
<Hixie_>
based on this e-mail i'm looking at
18:26
<Hixie_>
but he's going to rename that to InitializeHostDefinedRealm
18:27
<jorendorff>
ok, well, i won't try to get in the middle of that
18:27
<jorendorff>
sounds like fun
18:27
<Hixie_>
so anyway, the point is you're saying i need to create the Loader here too?
18:27
<Hixie_>
ok
18:27
<Hixie_>
that sounds doable
18:27
<Hixie_>
that's good, actually, it means i can define what exactly the Loader is
18:27
<jorendorff>
yeah.
18:27
<jorendorff>
yes
18:28
<jorendorff>
that's the design intent of the module loader, we don't have "fetch", you do
18:28
<Hixie_>
and make it something more elaborate than ES's built-in Loader
18:28
<Hixie_>
i wonder how hard it would be to extend it enough to support import styles from "foo.css";
18:29
<Hixie_>
or import html from "htmlimport.html";
18:29
<jorendorff>
not so hard. let's see. switching behaviors based on the file extensions is a little weird
18:29
<Hixie_>
i was thinking switching based on magic keywords "styles" and "html"
18:29
<Hixie_>
or, based on the MIME type of the fetched file
18:30
<Hixie_>
not sure what you'd do with the keyword if you base it on the MIME type
18:30
<jorendorff>
ok
18:30
<Hixie_>
but basing it on the MIME type seems logical too
18:31
<Hixie_>
maybe import foo from "mystylesheet"; causes a "foo" variable whose value is the created <link> element to be exposed
18:31
<Hixie_>
that would be quite useful
18:31
<Hixie_>
i wonder if the "import" machinery can handle the thing being exposed not being a Module
18:31
<jorendorff>
that's doable, I'm like 98% sure
18:31
<jorendorff>
damn
18:31
<jorendorff>
you're right, it can't
18:31
<Hixie_>
or maybe i still export a Module but i just add some new fields on it
18:31
<jorendorff>
right
18:31
<jorendorff>
that is doable
18:31
<Hixie_>
to expose the underlying <link> or whatnot
18:32
<jorendorff>
just by specifying a suitable "translate" and "instantiate" hook
18:32
<jorendorff>
instantiate containing the important part
18:32
<Hixie_>
i'm gonna try to finish this flowchart, i think. it's helping me a lot in getting a handle on this thing.
18:32
<Hixie_>
and i can't really make progress til allen's done these changes anyway.
18:32
<jorendorff>
flow chart?
18:33
<Hixie_>
<Hixie_> right now i've got http://www.gliffy.com/go/publish/6036438
18:34
<Hixie_>
bbiab, lunch
18:34
<Hixie_>
thanks for the help so far
18:37
<Hixie_>
(filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=26546 on the import styles idea)
19:46
<smaug____>
if a script in page A creates some object using 'new someotherwindow.Foobar();', what is the incumbent settings object when ctor is called?
19:46
smaug____
never remembers this stuff, and 'incumbent settings object' is so bizarre term that it really doesn't help with this
19:49
<smaug____>
Hixie_: ^
19:50
<smaug____>
I assume incumbent settings object is the one from page A
20:01
<jtcranmer>
annevk: I'm aware they're not equivalent
20:02
<jtcranmer>
the question is, since they are both A-labels of faß.de (just under different definitions of transitonal/nontransitional processing)
20:02
<jtcranmer>
would it be better to, e.g., consider user⊙fd and user⊙xd to be "equal"
20:03
<smaug____>
Hixie_: any chance to get some examples of various settings object to the spec ?
20:03
<annevk>
no, registrars messed that up
20:04
<smaug____>
incumbent settings object vs. entry settings object
20:04
<annevk>
jtcranmer: well not just registrars, but also the IETF
20:04
<annevk>
and whoever else is to blame for IDNA2008
20:08
<jtcranmer>
annevk: theoretically, they're supposed to be owned by the same people
20:08
<jtcranmer>
which is why I bring it up
20:08
<annevk>
jtcranmer: in practice, they are owned by distinct entities
20:09
<annevk>
jtcranmer: which is also what the .de registry wants, but most (if not all) browsers consider bad for security
20:10
<jtcranmer>
the registrars even bungled that up?
20:10
<jtcranmer>
okay, so I'll treat all the assurances that IDNA says registrars are supposed to do as packs of lies
20:11
jtcranmer
heads out
20:11
<annevk>
so they a) don't want to handle bundling, b) in Germany they want ß and ss to be distinct
20:15
<Hixie_>
smaug____: yeah, it's A, i think, because that's all within the JS spec and the JS spec doesn't manipulate the stack of settings objects
20:16
<Hixie_>
smaug____: what part of "incumbent settings object" is bizarre? i'd happily use a better term if you have one
20:16
<smaug____>
Hixie_: just some example would be good
20:16
<smaug____>
incumbent settings object vs. entry settings object
20:19
<Hixie_>
ah, that's a good idea
20:19
<Hixie_>
will file a bug on that
20:19
<smaug____>
I just filed
20:20
<Hixie_>
even better :-)
20:20
<Hixie_>
thanks!
20:23
<Hixie_>
jorendorff: does "The System object is the Loader Object instance associated with the Realm of the current global object" mean "The property "System" of the global object is the current Realm's [[loader]]"?
20:30
<Domenic>
Hixie_: I am 90% sure that is true
20:30
<Hixie_>
interesting
20:31
<Hixie_>
(isn't window.System going to clash with existing code?)
20:32
<Domenic>
I wonder what happens when you override window.System
20:32
<Domenic>
will the browser try to use it anyway?
20:32
<Domenic>
or does it only work if you override properties of the built-in window.System
20:33
<Domenic>
System is a dumb name anyway, maybe it'll conflict and they'll change it
20:33
<TabAtkins>
The browser will certainly use the original one.
20:33
<Domenic>
TabAtkins: but the whole point of overridable loader hooks is to allow arbitrary user code to execute at those points
20:33
<TabAtkins>
Ah, then I dunno.
20:34
<Domenic>
yeah, unclear
20:34
<Domenic>
Hixie can probably tell us, now that he is an expert at this stuff ;)
20:34
<Hixie_>
i haven't traced this back far enough to reach [[loader]]
20:34
<Hixie_>
so i'll let you know!
20:38
Hixie_
wonders what "Return PromiseThen(p, F)" means
20:38
<Hixie_>
(http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promisethen is blank)
20:38
<Hixie_>
Domenic: any idea? ^
20:38
<jorendorff>
it needs to be changed. I'll file a bug. it means p.then(F)
20:39
<jorendorff>
possibly with some automatic coercions going on
20:39
<Hixie_>
what does that mean? return a new promise that resolves when F has been invoked?
20:39
<jorendorff>
Yes.
20:40
<Hixie_>
k
20:45
<Domenic>
Hixie_: ah those sections rae still blank, wonderfully. They're supposed to just be un-tamper-withable versions of p.then(F), ya
20:45
<Hixie_>
jorendorff: why does the UpdateLinkSetOnLoad(linkSet, load) Abstract Operation sometimes (though not always) return a value? the return value seems to be ignored by the caller (which is always LoadSucceeded Functions)
20:46
<Domenic>
Hixie_: just guessing, but often "return values" in ES are just "did this function throw an exception or not" exception ~= abrupt completion.
20:46
<Hixie_>
that's ignored too
20:46
<Hixie_>
the caller just says "Call UpdateLinkSetOnLoad(linkSet, load)."
20:47
<Hixie_>
it ignores the result, abrupt or not
20:47
<Domenic>
ah OK. My guess is spec bug then. Allen caught many such bugs in my promises draft.
20:48
<jorendorff>
Hixie_: yeah, it should be changed for clarity to just say "7.a. Call LinkSetFailed... b. Return."
20:48
<Hixie_>
k
20:50
<jorendorff>
Domenic: i added a comment to https://bugs.ecmascript.org/show_bug.cgi?id=2683 explaining what those abstract operations are for
20:51
<jorendorff>
Domenic: as for System conflicting -- it *is* a dumb name
20:52
<Domenic>
jorendorff: ya looks good. I imagine all of the user-exposed versions will be implemented in terms of the abstract operations in one way or another.
20:53
<jorendorff>
of course any name could have a conflict -- anyway, assuming one does occur with System, I think the intent was to use Realm.[[Loader]] consistently everywhere
20:53
<Hixie_>
Realm.[[loader]], lowercase L
20:54
<Hixie_>
([[Loader]] is used on other records)
20:55
<Hixie_>
given PromiseThem(PromiseNew(A), B) in what order do A and B execute?
20:55
<Hixie_>
Then, not Them
20:55
<Hixie_>
or are none of them executed immediately?
20:55
<jorendorff>
where?
20:56
<Hixie_>
where what?
20:56
<jorendorff>
where does this occur?
20:56
<Hixie_>
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-requestload
20:57
<caitp>
if native promises are anything like the conventions that have been agreed on by the community over the past few years, PromiseThen(not-a-function) should be irrelevant
20:57
<jorendorff>
(but Domenic can check me -- the answer is, A would be called immediately, and B definitely not during this event turn)
20:57
<Hixie_>
step 6 does "PromiseNew(F)", where F is a "CallNormalize(resolve, reject) Functions"
20:57
<TabAtkins>
I assume that PromiseNew(A) is the internal equivalent of new Promise(A).
20:57
<jorendorff>
yes
20:57
<jorendorff>
that one actually has spec text
20:57
<Hixie_>
so what are the "resolve" and "reject" arguments set to?
20:57
<TabAtkins>
So then yeah, A is executed immediately, as part of constructrion of the promise. B is executed when/if the first promise fulfills.
20:58
<TabAtkins>
The resolver and rejecter for the promise beign constructed.
20:58
<Domenic>
yepyep, Tab's got it
20:58
<Hixie_>
i tried to follow it down, but "resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]" doesn't mean anything to me
20:58
<TabAtkins>
Methods that, when called, resolve or reject that promise. They're the only way to manipulate the promise's state.
20:58
jorendorff
is slightly relieved that the Promises spec is not a great deal more comprehensible than the Loader spec
20:58
<jorendorff>
though, i hasten to add
20:59
<jorendorff>
much more complete and correct
20:59
<Hixie_>
oh they're the spec-provided callbacks to actually resolve the promise, ok
20:59
<TabAtkins>
Yeah.
20:59
<Hixie_>
"Return the result of calling the [[Call]] internal method of resolve passing undefined and (name) as arguments" seems like a really convoluted way of just saying "resolve the promise"
21:00
<Hixie_>
but ok
21:00
<jorendorff>
yep
21:00
<TabAtkins>
Urf, agreed.
21:00
<jorendorff>
this is one of those places where i would totally just file a pull request, if TC39 had a process
21:00
<TabAtkins>
This is why I switched the spec for the color classes to just use actual JS, because writing JS in prose is *terrible*.
21:01
<TabAtkins>
(And I needed enough detail that it was kinda bad to use prose.)
21:01
<Hixie_>
TabAtkins: i would have just said "resolve the promise with 'name' as the value"
21:01
<TabAtkins>
Normal prose, that is.
21:01
<Hixie_>
which seems like sufficient detail...
21:01
<Hixie_>
(along with corresponding changes around it, obviously)
21:01
<Hixie_>
anyway
21:01
<TabAtkins>
"Resolve promise F with "value"." is the defined language, I think.
21:02
<Hixie_>
yeah, something like that would be fine
21:04
<Hixie_>
man, the ES spec uses this "Return Foo()" (where Foo() returns 'undefined' or nothing at all) style a _lot_
21:04
<Hixie_>
it's really confusing
21:05
<Hixie_>
so wait, wait, wait
21:05
<Hixie_>
the function passed to PromiseNew() has to have 'resolve' and 'reject' arguments, right?
21:06
<TabAtkins>
Well, it'll get passed those args. It doesn't necessarily have to have them, obviously, since you're always allowed to ignore input args.
21:06
<Hixie_>
but why does the function passed as the second argument to PromiseThen() not have to also?
21:06
<TabAtkins>
PromiseThen() is nothing like PromiseNew().
21:06
<Hixie_>
i thought it was the same thing but chaining on from a previous promise
21:07
<TabAtkins>
It doesn't get resolve/reject functions. You either return a value or throw a value; that resolves/rejects the chained promise automatically.
21:07
<TabAtkins>
(The constructor doesn't have the same behavior because you sometimes want to wait and resolve things *later*, by passing the resolve/reject functions to something outside.)
21:07
<Hixie_>
so there's kind of two types of promises? those whose handlers are async and those whose handlers are sync?
21:07
<TabAtkins>
No.
21:08
<Hixie_>
i'm so confused
21:08
<TabAtkins>
Most of the time, you deal with a promise by having your callback either (a) return a value (fulfilling the promise), (b) throw (rejecting the promise), or (c) return another promise (resolving the promise and slaving it to your returned promise, so it'll fulfill/reject later).
21:09
<TabAtkins>
But you need to bootstrap the promise in the constructor, so you're instead given the handles directly.
21:09
<Hixie_>
but CallNormalize() just does things synchronously
21:09
<Hixie_>
so why bother with a promise at all?
21:09
<TabAtkins>
I have no idea what that is, so shrug.
21:09
<TabAtkins>
I can just tell you about promises, not about whatever other crazy stuff the ES spec has in it.
21:10
<Hixie_>
jorendorff: ^
21:10
<Hixie_>
jorendorff: why does RequestLoad() use a promise to call CallNormalize()?
21:10
<jorendorff>
ok, this part of the pipeline is actually going to be a pleasant surprise for you, i hope
21:10
<jorendorff>
because it all sort of makes sense actually
21:11
<Hixie_>
try me :-)
21:11
<jorendorff>
second, multiple conversations...
21:11
<jorendorff>
ok. to answer your question first
21:12
<jorendorff>
it's just so that the normalize hook is called async
21:12
<jorendorff>
for consistency with all the other hooks
21:12
<jorendorff>
they're all called async in a fresh event loop turn
21:12
<Hixie_>
wait, it is?
21:12
<Hixie_>
i thought we established PromiseNew() would synchronously call the executor
21:12
<jorendorff>
yes
21:12
<jorendorff>
definitely
21:13
jorendorff
looks at the spec text
21:13
<Hixie_>
PromiseNew() calls InitializePromise() which calls "the [[Call]] internal method of executor with undefined as thisArgument and (resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]) as argumentsList"
21:13
<jorendorff>
PromiseNew should call its argument synchronously
21:13
<jorendorff>
just like new Promise(f)
21:13
<Hixie_>
so then how is that calling it async
21:14
<jorendorff>
huh, it is totally calling it sync
21:14
jorendorff
is confused
21:14
<Hixie_>
glad it's not just me :-P
21:14
<jorendorff>
maybe it got "fixed"
21:14
<jorendorff>
because the old way looked weird
21:14
<jorendorff>
it was like, why are you creating this pointless promise?
21:14
<jorendorff>
sorry
21:14
<jorendorff>
so let's address the spec as it is then
21:15
<jorendorff>
Hixie_: In that case the main difference between using PromiseNew to call a function
21:15
<jorendorff>
and just directly calling it
21:15
<jorendorff>
Hixie_: is that any exceptions thrown by the function are then caught for you and PromiseNew returns a rejected promise
21:16
<jorendorff>
(step 8 of InitializePromise, called from PromiseNew)
21:16
<Hixie_>
i was wondering why CallNormalise caught an abrupt termination but then just returned it instead of calling the rejection handler
21:17
<Hixie_>
i guess it's the same either way
21:17
<Hixie_>
but ironically in the spec prose it ends up not being automatic since you have to catch all the abrupt terminations
21:17
<jorendorff>
right. think of it this way
21:17
<jorendorff>
if you were implementing all this in JS
21:17
<jorendorff>
you would *definitely* do it this way, because it's quite a bit nicer to have `new Promise()` catch the exception than write a try/catch block
21:18
<jorendorff>
try/catch being what it is
21:19
<Hixie_>
ok so. next question then. AddDependencyLoad() takes an argument depLoad. Where does that come from?
21:20
<Hixie_>
it's called as the callback from a promise that fires once GetOrCreateLoad() has returned, if i'm following this right
21:20
<Hixie_>
but GetOrCreateLoad() is just a promise callback, it doesn't resolve a new promise, so what's the value of the promise that gets passed to AddDependencyLoad() ??
21:21
<Hixie_>
is it the same "name" value as was passed to GetOrCreateLoad() from CallNormalize() ?
21:27
jorendorff
looks
21:32
<jorendorff>
Hixie_: ok. PromiseThen does chain, so looking at RequestLoad, we have
21:33
<jorendorff>
5. it calls new Promise(CallNormalize) directly
21:33
<jorendorff>
8. and calls .then(GetOrCreateLoad) on that
21:33
<jorendorff>
now back to ProcessLoadDependencies
21:34
<jorendorff>
4.e. and we call .then(AddDependencyLoad) on that
21:35
<jorendorff>
CallNormalize figures out the normalized name to use
21:35
<jorendorff>
GetOrCreateLoad either finds an already-loaded Module, a Load already in progress, or it kicks off a new Load
21:37
<jorendorff>
AddDependencyLoad adds that as a dependency of this load.
21:37
<Hixie_>
jorendorff: with you so far
21:37
<Hixie_>
jorendorff: but what's the argument to AddDependencyLoad()? where does it come from?
21:37
<jorendorff>
GetOrCreateLoad always returns a Load record, even for an already-loaded Module it just synthesizes one
21:37
<jorendorff>
that is the value passed to AddDependencyLoad
21:37
<jorendorff>
it's a record
21:37
<Hixie_>
oh!
21:37
<Hixie_>
the return value of the callback is what sets the argument of the next callback
21:38
<Hixie_>
ok
21:38
<jorendorff>
yes
21:38
<Hixie_>
(if GetOrCreateLoad() wanted to be async, what would it return? a promise? does that then automatically get handled somehow?)
21:38
<jorendorff>
yes
21:39
<jorendorff>
yes, so suppose you d
21:39
<jorendorff>
*you do
21:39
<jorendorff>
p1.then(function (v1) {
21:39
<jorendorff>
return <<some new Promise called p2>>;
21:40
<jorendorff>
}).then(function (v2) {
21:40
<jorendorff>
...and so on...
21:40
<jorendorff>
});
21:40
<Hixie_>
is it http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-resolve-functions that handles this?
21:40
<jorendorff>
v2's eventual value is whatever p2 finally settles to
21:40
<Hixie_>
i'm not seeing anything there that checks if the return value is a promise
21:40
<Hixie_>
(what if you actually want to return a promise? not just a promise to a value?)
21:41
<jorendorff>
Hixie_: what the spec does instead of "if v is a Promise" is "if v has a callable .then method"
21:41
<jorendorff>
(if you actually want to return a promise... I don't know, I think you're screwed? Domenic?)
21:42
<jorendorff>
(some folks thought that was inelegant, but the design already had so much traction in real code, it was kind of a fiat accompli or whatever)
21:57
<TabAtkins>
The current API can't fulfill a promise to a promise, because it always uses the "resolve" algorithm, which automatically slaves to promises. We don't directly expose the "fulfill" algorithm yet, which would allow fulfilling a promise with a promise directly.
22:16
<Hixie_>
jorendorff: oh wow, really? I don't have to return a Promise, i can return a { then: function () } ?
22:16
<Hixie_>
fascinating
22:16
<jorendorff>
yes, you can.
22:16
<boogyman>
So it's duck-typing?
22:16
<jorendorff>
yeah
22:17
<jorendorff>
as an implementer, i'm not crazy about stuff like that (in the absence of use cases). it creates corner cases
22:21
<Hixie_>
why does Promise.resolve() not also allow that then?
22:21
<Hixie_>
wait, this is going to cause all kinds of problems
22:21
<Hixie_>
it means that not only can you not return a promise, you also can't return any object that happens to have a callable 'then'
22:22
<caitp>
sounds almost exactly like aplus
22:32
<jorendorff>
i agree that that's what it means
22:34
<jorendorff>
can't say if it'll cause all kinds of problems in practice
22:34
<caitp>
on the other hand, it means you can consume non-"native" implementations
22:34
<caitp>
these same rules have been in place for a few years
22:34
<caitp>
people have gotten pretty used to them, I think
22:40
<Hixie_>
well it means e.g. if i want to return an object that's a dictionary of english words with functions attached to them, the code will suddenly break utterly if one of those words is "then".
22:41
<Hixie_>
if i'm the F in a construct like PromiseCatch(PromiseThen(p, F), G)
22:41
<caitp>
sure, but in practice people do things like `return { data: theDictionary };` or similar
22:41
<Hixie_>
and I return a promise
22:41
<Hixie_>
and that promise is a construct like PromiseThen(PromiseNew(A), B)
22:42
<Hixie_>
and B throws
22:42
<Hixie_>
does G get called?
22:42
<Hixie_>
Domenic: ^
22:43
<jorendorff>
Hixie_: yes
22:43
<Hixie_>
k
22:43
<Hixie_>
thanks
22:43
<jorendorff>
in the lingo, the promise PromiseThen(p, F) is not "settled" when F returns
22:43
<jorendorff>
if it returns a thenable
22:44
<jorendorff>
instead, we let it ride
22:44
<jorendorff>
double the stakes
22:44
<jorendorff>
"now you have two promises"
22:44
<jorendorff>
and other pithy sayings
22:51
<Hixie_>
is %Loader% the same as the Realm's [[loader]] (which is the same as window.System)?
22:51
<Hixie_>
(the definition of %Loader% is blank)
22:53
<TabAtkins>
Hixie_: Re "you also can't return any object that happens to have a callable 'then'", yup, I fought against that crap. So did Alex Russell, for a while - he was arguing for "ghetto branding" (the presence of an improbably-named property) as we don't have Symbols quite yet. But we lost.
22:54
<Hixie_>
TabAtkins: i don't understand the argument for this. I mean, other parts of the spec use IsPromise() without controversy as far as I can tell.
22:54
<TabAtkins>
It's so that existing Promise libraries (conforming to the A+ spec) can be used directly as promises without any updates.
22:54
<TabAtkins>
I still don't think it's worth it, but shrug.
22:54
<Hixie_>
but they can't with other parts of the api
22:54
<caitp>
domenic you aren't writing a CL for that are you? that one looks simple!
22:54
<TabAtkins>
Right, I think a lot of this is a mess. :/
22:55
<Hixie_>
e.g. you can't call Promise.resolve() with an a+ promise
22:55
<TabAtkins>
That's actualy surprising, and likely a mistake.
22:55
<TabAtkins>
Promise.resolve() is supposed to ahve the same semantics as returning a value from a promise callback.
22:56
<TabAtkins>
Promise.resolve(foo) === new Promise(function(resolve){ resolve(foo); }) === somePromise.then(function(){ return foo}, function(){ return foo; })
22:56
<TabAtkins>
That's what the semantics are *supposed* to be.
22:57
<Hixie_>
well right now Promise.resolve({then:foo}); is not the same as Promise.resolve(new Promise(foo)) (i'm assuming i got those right)
22:58
<TabAtkins>
Well, it's unlikely that the same "foo" can be used in both those places, but sure.
22:58
<Hixie_>
yeah i don't really understand this promise stuff
22:59
<Hixie_>
and the more i learn about it the less clear it gets :-(
22:59
<TabAtkins>
I don't know why; they feel really simple to me.
22:59
<TabAtkins>
But oh well.
23:00
<TabAtkins>
A consistent pattern in your confusion seems to be that you continually get confused over the difference between the contruction callback and the then() callbacks.
23:00
<TabAtkins>
Fix that, and maybe it will help?
23:01
<Hixie_>
well what would the equivalent of Promise.resolve({then:foo}) be using a promise and 'foo'?
23:01
<boogyman>
My understanding would be a TypeError, right?
23:01
<TabAtkins>
{then:foo} is an object that happens to have a "then" property with the value foo. Maybe that's a method, but we have no idea what it does.
23:02
<Hixie_>
assume 'foo' is a function
23:02
<TabAtkins>
With a promise, that's, um, "somePromise.then = foo;", which is almost certainly not what you're thinking about.
23:04
<Domenic>
caitp: which one?
23:05
<TabAtkins>
(Here, you're confusing setting "then" to some value and calling "then" with an argument.)
23:05
<Hixie_>
TabAtkins: take new Promise(function(a, b) { a() }).then(function () { return { then: foo } });
23:05
<Hixie_>
TabAtkins: what's the equivalent of that but using a real promise instead of "{ then: foo }" ?
23:06
<Hixie_>
TabAtkins: make that new Promise(function(a, b) { a() }).then(function () { doSomething(); return { then: foo } });
23:06
<TabAtkins>
There isn't, because a real promise won't have "foo" as the value of its "then" property. It'll have, most likely, the default value of Promise.prototype.then.
23:06
<Hixie_>
?
23:06
<TabAtkins>
I'm not sure what you're itnending with the thenable there, so it's hard to answer.
23:06
<Hixie_>
that seems like a non-sequitur
23:06
<TabAtkins>
{then:foo} is an object with a then() method that does something. A Promise is also an object with a then() method that does something.
23:07
<Hixie_>
right now if you return a {then:foo} from a then() callback, it calls foo() in a microtask later.
23:07
<TabAtkins>
Yes.
23:07
<Hixie_>
ok so you can do this also with real promises right?
23:07
<TabAtkins>
And the same thing happens to a promise - its then() method gets called later.
23:07
<Hixie_>
instead of this fake object with a 'then' property?
23:07
<TabAtkins>
Depends on what you're intending - I'm very confused here.
23:07
<Hixie_>
so how do you return a promise whose then() method calls foo?
23:08
<TabAtkins>
Is your *intention* that foo() get called at some point? That is, that the foo() method itself is important, not just a metasyntactic variable?
23:08
<Hixie_>
yes
23:08
<TabAtkins>
Ah, k.
23:08
<Hixie_>
first doSoemthing() is called, then foo() is called
23:08
<Hixie_>
in separate microtasks
23:09
<TabAtkins>
And you still want a promise returned from the chain like normal? (In the thenable example you've provided, unless foo() acts correctly, you'll probably get a rejected promise out at the end.)
23:09
<Hixie_>
what is "acts correctly"?
23:10
<Hixie_>
isn't it just "not throw"?
23:10
<boogyman>
implements the same interface as a Promise()
23:10
<TabAtkins>
`new Promise(function(a, b){ a(); })` is equivalent to `Promise.resolve()`, so I'll pretend you used that, since it's clearer.
23:10
<TabAtkins>
I'm not sure what the expected beahvior of a then() method is, precisely. I haven't looked into it in detail, and don't plan to write my own promise impl.
23:11
<TabAtkins>
So, your requirement can just be Promise.resolve().then(doSomething).then(foo)
23:11
<Hixie_>
hold on, you've moved 'foo' outside of the original callback
23:11
<TabAtkins>
???
23:12
<TabAtkins>
I did what you asked for. You want something different, give me better requirements. ^_^
23:12
<boogyman>
Then's are chainable.
23:12
<Hixie_>
ok a better example: suppose you have new Promise(function(a, b) { a() }).then(F);
23:12
<Hixie_>
and F is function F() { doSomething(); return { then: foo } }
23:12
<TabAtkins>
Okay, `fulfilledPromise.then(F)` for clarity.
23:13
<Hixie_>
so the question is, how do you rewrite F so it uses a real promise instead of { then: foo }
23:13
<TabAtkins>
That code is *not* the normal way to have a method get called later. Don't use thenables on purpose unless you're actually intending them to be promise-likes.
23:13
<Hixie_>
i've no idea what that means
23:13
<TabAtkins>
And I don't know what your code means.
23:13
<Hixie_>
what's a "thenable"
23:13
<TabAtkins>
An object with a callable "then" property.
23:14
<TabAtkins>
Or, in other words, a Promise or Promise-like.
23:14
<Hixie_>
"don't use a promise unless you want a promise"?
23:14
<Hixie_>
i don't know what i want
23:14
<Hixie_>
i'm trynig to work out what it means to return a {then:foo}
23:14
<TabAtkins>
It *appears* that you want doSomething() to be called in one microtask, and then foo() in another.
23:14
<TabAtkins>
You're for some reason trying to achieve this by constructing a promise-like object, which is weird and almost certainly not what you want.
23:15
<Hixie_>
all i'm trying to do is understand what the spec means
23:15
<Hixie_>
the spec allows you to return any object with a "then" property that's callable
23:15
<caitp>
Domenic, v8:3499 --- that one seems really trivial, so I wanna write that one while I make dinner :3
23:15
<caitp>
but if you've already done it then no big deal
23:15
<Domenic>
caitp: haha ya be my guest, I haven't gotten my dev environment set up
23:15
<TabAtkins>
Returning {then:foo} means the same thing as returning a promise. Except that if foo() doesn't do what the spec expects (I dont' know the details of this), weird things will happen.
23:16
<TabAtkins>
Where "weird" is probably "the chained promise gets rejected".
23:17
<Hixie_>
and if you return a promise, what happens? it just gets its "then" method called immediately?
23:17
<TabAtkins>
I *think* all that happens is that the spec calls foo() at some appropriate time, and creates its own (native) promise that either fulfills or rejects, based on whether foo() returns or throws. But I'm not certain if that's exactly right.
23:17
<TabAtkins>
"immediately": well, whenever the spec says to.
23:17
<TabAtkins>
I don't recall the details.
23:18
<Hixie_>
i'm reading the spec as we speak and i can't figure out the details either
23:18
<Hixie_>
whence my confusion
23:18
<TabAtkins>
Oh wait, I remember a bit better.
23:18
<TabAtkins>
So, this is complicated.
23:18
<TabAtkins>
And now there's a fire drill, so bbiab
23:56
<Hixie_>
i think i'm suffering from some sort of stockholm syndrome with the loader
23:57
<Hixie_>
i've reached the ProceedToTranslate callers
23:58
<Hixie_>
basically i've flow-charted everything from ProceedToTranslate() to UpdateLinkSetOnLoad()