04:12
zcorpan
back from vacation
04:30
<MikeSmith>
zcorpan: time for you to get back to writing some w3cmemes
04:30
<zcorpan>
yeah man
04:35
<zewt>
well, that's awesome: system crashed and firefox completely lost my session
04:38
<zewt>
wow, it just uses a text file with json, not sqlite
04:40
<SamB>
what, you wanted an sqlite DB with JSON?
04:40
<zewt>
better than a raw file for important user data
04:53
<roc>
performance of JSON is much better
04:53
<roc>
and I suspect robustness is too
04:53
<roc>
overall
04:54
<SamB>
well, robustness would be more better either way if FF told you when the disk was full ;-P
05:06
<zewt>
json has zero robustness since it's a text format, not a data storage system
05:06
<zewt>
sqlite's journalling would probably have prevented me ending up with a nulled out session and having to dig out an old backup
05:17
<SamB>
zewt: yes, but it'd probably be missing random tabs or pages or something
05:17
<SamB>
depending on the cause of the problem
05:20
<zewt>
... no, it wouldn't ...
05:21
<SamB>
well if you ran out of storage it likely would
05:21
<SamB>
at least that's what happens to my history
05:21
<zewt>
if you ran out of storage sqlite would throw an error and nothing would be changed
05:21
<zewt>
but they're just doing ad hoc writing to a file so who knows what happens
07:28
<JakeA>
Domenic: If I wanted to pipe a response into a cache and the browser (for rendering), how can I do that without the whole response ending up in memory?
07:29
<Domenic>
JakeA: in that case if you tee and then pipe both ends of the tee into places immediately, the data will just flow through
07:29
<JakeA>
Domenic: cool, that's what I thought
07:29
<Domenic>
JakeA: the problematic case is teeing and then piping only one end
07:29
<Domenic>
sorry I still haven't had time to process your reply
07:29
<Domenic>
Working on a talk I'll be giving in ... 7 hours? :P
07:30
<JakeA>
NOT ACCEPTABLE
07:30
<JakeA>
Domenic: no worries! I'm only just replying to that thread myself
07:30
<JakeA>
Good luck with the talk
07:30
<Domenic>
:) thanks
07:40
<Domenic>
JakeA: what do you mean by a transaction story that works for both IDB and fetchstore
07:40
<Domenic>
JakeA: my point was that .batch() is a better primitive to build anything more complicated on top of. For *both* APIs
07:41
<Domenic>
JakeA: the only thing I could think of that works for both would be some kind of strange global variable that is "in a transaction", that IDB and fetchstore both consult
07:41
<JakeA>
Domenic: slightlyoff was talking about a way to have the same story for both, rather than something cache specific. Maybe even something that can be a single transaction across both
07:41
<Domenic>
Bleh, I will try taking things up with him then
07:41
<JakeA>
Yeah, I like .batch, but happy to keep it as an algorithm for the sake of getting cache out of the door
07:42
<Domenic>
That is totally fair
07:42
<Domenic>
But I want to convince him that it is the correct primitive :)
07:42
<JakeA>
Domenic: Go for it :D
07:42
<Domenic>
Or hear what his thoughts are for something else, if there are concrete ideas
07:43
<JakeA>
Domenic: Just to confirm, if the active consumer of a stream errors/dies, something consuming the tee of the original stream is unaffected right?
07:43
<Domenic>
JakeA: right
07:43
<JakeA>
cool
07:49
<JakeA>
Domenic: Thinking of adding response.clone() and request.clone() rather than doing any implicit teeing. How does that sound?
07:50
<Domenic>
JakeA: I think I like it, but kind of want to read through the thread first
07:50
<JakeA>
No worries, don't worry about it until after your talk
07:50
<Domenic>
Seems related to "structured cloning of streams" discussion I kinda-started a while ago
08:13
<annevk>
Why are we changing the design of responses and requests?
08:17
<JakeA>
annevk: looking for ways to allow a response to have multiple consumers without adding magic
08:17
<JakeA>
(or indeed, a request)
08:18
<JakeA>
Domenic: if I tee a stream, can I read it without the original stream being read? If a teed (or original) stream isn't read, and data builds up in memory, what's expected to happen when memory runs out? All active streams fail?
08:20
<JakeA>
annevk: The use cases are, read a response as two types, send a response to cache & browser, read a request's body before deciding whether to fetch it or not
08:20
<annevk>
note that there is some tee'ing going on already per algorithms in Fetch
08:21
<annevk>
e.g. because of redirects a request can be tee'd several times
08:25
<JakeA>
good point
08:25
<annevk>
and at least once
08:25
<JakeA>
annevk: So .clone() would give that to the user. We'll be able to explain it in terms of new Response & a teed stream, but I think we need it sooner than streams
08:25
<annevk>
JakeA: why .clone() and not structured clone?
08:25
<annevk>
we want structured clones
08:25
<annevk>
and maybe structured clones need an API
08:25
<JakeA>
annevk: What's the API… aha
08:26
<JakeA>
annevk: so there isn't a way to structured-clone with script (aside from going back & forth between a dedicated worker I suppose)
08:26
<JakeA>
annevk: In fact, is there a sync way to create a structured clone?
08:26
<annevk>
you can always do window.postMessage
08:27
<annevk>
I don't think there's a synchronous API at this point
08:27
<annevk>
although there's a couple of spec algorithms that do it
08:29
<JakeA>
annevk: so, can we have .clone() that returns a structured clone, or are you thinking more window.createStructuredClone(obj);
08:29
<annevk>
the latter, something TC39-designed
08:30
<annevk>
e.g. you can clone `{ data: obj }` too
08:30
JakeA
plays Oh Fortuna
08:31
<annevk>
there's several open issues on this
08:31
<annevk>
including a big red note in Fetch
08:32
<JakeA>
annevk: You mean https://github.com/slightlyoff/ServiceWorker/issues/313?
08:33
<Domenic>
It would be good if structure clone were async
08:33
<Domenic>
I can't remember why off the top of my head but IIRC it enabled some scenarios
08:35
<Domenic>
JakeA: the way to think of teeing is you have created two new streams which are hooked up to the original stream. So when you read from one of the new streams, it pulls from the original stream into both new streams. The one you are reading from then gets the data handed to the user, but the other one just gets the data sitting there in the queue.
08:35
<Domenic>
If memory runs out ... usual platform OOM behavior, I suppose? Which is pretty undefined IIRC?
08:35
<annevk>
JakeA: yup
08:36
<annevk>
OOM is undefined
08:36
<annevk>
There was a thread recently about defining stack limits
08:36
<Domenic>
You could also imagine the platform swapping out all the data to disk and letting you read it later... the details are hidden enough that this is possible. I wouldn't want to write such a tee-with-disk-intermediating myself, but it could be done.
08:37
<Domenic>
You'd want to avoid that if possible though. Ideally you want .read() to translate straight into a syscall, and the more layers of teeing and caching you add in between, the less likely that is.
08:38
<JakeA>
Domenic: in your example there, were you thinking of two calls to tee? Otherwise I'm not sure where the *two* new streams come from
08:38
<Domenic>
JakeA: a tee is meant to create two new streams from the original, thus the "T" shape
08:38
<Domenic>
or "Y" shape
08:39
<Domenic>
one stream goes in, gets consumed, two unconsumed streams come out
08:39
<Domenic>
well, "consumed" isn't quite right, we don't wait for you to read to the end
08:39
<JakeA>
Got it
08:40
<JakeA>
I guess that makes request.clone() either weird or all the more useful. It'd have to replace its own stream with one part of the tee
08:41
<JakeA>
starting to understand the issues around structured cloning and streams
08:41
<Domenic>
hmm
08:42
<annevk>
Domenic: is there an explanation somewhere of why an IO stream needs to have both readable and writeable parts?
08:42
<annevk>
Domenic: e.g. why it can't be more like the simplest asynchronous iterable object you can imagine (that has both push and async read)
08:42
<Domenic>
annevk: not sure exactly what you mean... a stream is either readable (someone else controls data production) or writable (someone else controls consumption of data you put in it)
08:43
<annevk>
Domenic: why can't it be more like a promise, where that can be the case, but you can also control both ends
08:44
<Domenic>
annevk: a readable stream is much like a promise. (And a writable stream, in reverse.) But the creator controls one end, and does not give the ability to others via the public API
08:44
<Domenic>
a readable stream is only readable, although its creator says how to get the data that consumers read from it
08:45
<Domenic>
you could imagine a stream API that leaves both ends open for people to shove data through, but that has some ergonomic issues:
08:45
<Domenic>
instead of writing e.g. "when someone writes data to me, put it in the file descriptor," you have to continually be reading from the output end, and then putting the results of what you read into the file descriptor
08:47
<annevk>
I guess it's needed for perf, but it seems weird that we're focused that much on current low-level implementation details, rather than what is the best abstraction for what we want.
08:47
<Domenic>
It's not really perf, it's ergonomics
08:49
<annevk>
If read returns a promise, you don't have to continuously read for instance
08:49
<Domenic>
You have to recurse at the very least
08:49
<Domenic>
But hmm
08:49
<annevk>
It would just fulfill with the next chunk or error
08:50
<Domenic>
I am starting to do perf benchmarks and it is possible promise-returning read() might make a comeback if those show non-failure
08:50
<annevk>
Yes, and with recursion you get nice ergonomics. Especially with synchronous notation
08:50
<annevk>
Sounds good
08:54
<JakeA>
Domenic: if I tee a stream but don't read either of the tees, is the original stream consumed or does it wait for the first read on one of the tees?
08:54
<Domenic>
JakeA: it waits. Although trying to read from it would race with the tee mechanism, which is also trying to read from it
08:55
<JakeA>
yeah, was just trying to work out when it starts filling memory. Got it.
08:55
<Domenic>
I am looking forward to thinking harder about how to implement clone() ... clearly it is not quite the same as teeing
09:07
<JakeA>
Domenic: can it be explained with a tee and taking one part of the tee for itself?
09:16
<Domenic>
JakeA: seems weird. maybe possible, but i think i'd use something slightly different than a tee...
09:29
<JakeA>
annevk: In https://github.com/slightlyoff/ServiceWorker/issues/398, what's the difference between "use a local file if available" and "conditional request", does the former not care about freshness?
09:57
<annevk>
JakeA: maybe, not sure; I'm not that familiar with cache implementations and what options they have
09:57
<annevk>
JakeA: I can imagine if you're offline you might decide to not care about freshness
10:00
<Ms2ger>
annevk, r? https://github.com/w3c/web-platform-tests/pull/1131
10:00
<JakeA>
annevk: fair enough, we do that in Chrome (behind a flag, I think)
10:03
<annevk>
Ms2ger: should I merge it after I reviewed it?
10:03
<Ms2ger>
Either way
10:04
<annevk>
Ms2ger: bit surprised the critic bot didn't post anything back
10:56
<JakeA>
annevk: thought… do we need to make fetch('//other-origin/whatever', {mode: 'no-cors'}) revalidate against the server? Else, if I get a response back, and navigator.offLine == true, we're exposing the user's history
10:56
<JakeA>
annevk: more so if the developer can go to the cache despite the cached entry being stale
11:05
<annevk>
JakeA: can't you probe that already with <img>?
11:05
<annevk>
JakeA: agreed that with the cache settings stuff, if we add that for v1, we'll need to carefully consider privacy
11:06
<JakeA>
annevk: for images, yeah. Scripts too I guess.
11:06
<JakeA>
annevk: hmm, maybe anything with iframes
11:09
<tobie>
Boy, SW issue 372 is now officially all over the place.
11:09
<JakeA>
yeah, ok, iframes too. Not a new problem then.
11:10
<JakeA>
tobie: is it? Felt like it was zoning in.
11:12
<tobie>
JakeA: well, you need to be familiar with Stream API status, teeing, stream cloning, advantages of async structured cloning over sync one, future tc39 plans for structured cloning, transactional requests in indexedDB, etc.
11:13
<tobie>
Did I mention request had a stream too? How that interact at the SW level just blew my mind.
11:14
<JakeA>
when you submit a form (with a mixture of files and form fields) that's a body stream that's sent to the server
11:15
<tobie>
Of course. Makes complete sense. It's just. Woah.
11:15
<JakeA>
yeah, it goes all the way down
11:21
<tobie>
JakeA: why does cache.addAll deplete a request's body stream? Do we cache non GET requests or does fetch send body of GET requests?
11:21
<tobie>
(asking for a friend)
11:22
<tobie>
;)
11:22
<JakeA>
tobie: bloody good point. No, it rejects with non-GET requests, so it's a non-issue
11:23
<JakeA>
updated
11:23
<tobie>
JakeA: how are GET requests with a body handled though?
11:24
<tobie>
Wasn't it you writing recently about how these were a thing?
11:26
<JakeA>
not that I know of. annevk, should we throw if a GET request is constructed with a body?
11:26
<annevk>
Domenic: so btw, the read-write distinction for streams is problematic for Request and potentially Response objects btw
11:26
<annevk>
Domenic: nobody had a good answer there so far and we plan on shipping this end of Q3...
11:27
<annevk>
JakeA: hmm, might not be handled specifically at the moment
11:27
<annevk>
JakeA: XMLHttpRequest ignores the body for GET/HEAD
12:20
<JakeA>
annevk: if we're not throwing for headers, we shouldn't throw for body I guess
12:22
<annevk>
I guess I should try to handle this in Fetch itself so we don't have to reinvent it for each API
12:22
<JakeA>
agreed
12:22
<annevk>
JakeA: there's also https://github.com/slightlyoff/ServiceWorker/issues/120 I just noticed
12:23
<annevk>
JakeA: maybe willchan & co should look at that
12:23
<JakeA>
annevk: Yeah, I don't have strong feelings there
12:45
<annevk>
Declares us-ascii, expects windows-1252; nice find zcorpan! http://futbolenlatele.com/
12:45
<zcorpan>
np
12:46
<zcorpan>
found it while eating my lunch :-)
12:49
<zcorpan>
"there are no pages doing X" is basically always false on the web
12:50
jgraham
wonders if that will fit in the topic :)
12:51
<annevk>
fits in a tweet
12:52
<zcorpan>
Hixie: &ndash; works with the new pipeline i take it?
14:09
<zcorpan>
https://www.w3.org/Bugs/Public/show_bug.cgi?id=9785#c10 - no pages doing X for X = moznofilter :-)
14:30
<zcorpan>
Hixie: ok if i close srcset bugs that are fixed by <picture>?
14:31
<annevk>
zcorpan: at least some time ago it was fine to close bugs given solid rationale
14:44
<zcorpan>
MikeSmith: do you have opinions on https://www.w3.org/Bugs/Public/show_bug.cgi?id=25552 ?
15:17
<hemanth>
meow, Object.keys returns an arrayLike object or an array ?
15:18
<hemanth>
specs says array
15:18
<hemanth>
but...
15:18
<hemanth>
>> obj = {x:1,y:2}; for (k in Object.keys(obj)) {console.log(k)}
15:18
<hemanth>
gives '0', '1'
15:19
<hemanth>
indices
15:21
<caitp>
Object.getPrototypeOf(Object.keys(...)) === []
15:22
<Ms2ger`>
What else?
15:23
<caitp>
Array.isArray(Object.keys(...)) === true ?
15:23
<caitp>
etc :c
15:23
<caitp>
Object.prototype.toString(Object.keys(...)) === [object Array]?
15:24
<caitp>
+ missing `.call`
15:25
<hemanth>
heh heh my bad, Enumeration VS Iteration
15:30
<caitp>
yes, it won't behave the same as for-of
15:31
<hemanth>
hrrm
15:34
<hemanth>
there must be a deprecated 'for each...in' as well ;)
15:34
<Ms2ger>
There is
15:35
<Ms2ger>
Thanks to E4X
15:36
<caitp>
and for-of will confuse people in other ways too, we don't know how to spec consistent languages
15:36
<hemanth>
heh heh
15:41
<hemanth>
I would stick for forEach for array and for-of for generator objects and for-in for the rest...
16:39
<JakeA>
annevk: ahh, so is https://github.com/slightlyoff/ServiceWorker/issues/398#issuecomment-51081392 correct, "conditional" mean must-revaidate?
16:39
<JakeA>
means&
16:39
<JakeA>
means**
16:39
<JakeA>
means*
16:39
<JakeA>
there, fixed.
16:44
<annevk>
JakeA: oh, yes, conditional goes via a server
16:52
<JakeA>
Riiiiiiight. I'd gotten confused. I thought "available" meant something other than "fresh"
18:08
<Hixie>
zcorpan: if they're assigned to me, comment on them first so i can check them out
18:24
<Hixie>
"There is no way to represent a promise value in IDL"
18:24
<Hixie>
what's a "promise value"?
19:45
<Domenic>
annevk: whatever form it takes it will almost certainly be { input, output }
19:45
<annevk>
Domenic: a class that has both input and output?
19:46
<annevk>
Domenic: because a plain object is unlikely to fly by Adam Barth
19:47
<Domenic>
annevk: not sure which yet. mostly a convention.
19:48
<Domenic>
annevk: but yes, something like var { input, output } = new PassThroughStream() seems reasonable.
19:48
<Domenic>
this comes back to my confusion as to how to "bootstrap" a two-ended stream
19:49
<Domenic>
if a PassThroughStream is composed of a { WritableStream input, ReadableStream output }, then WritableStream and ReadableStream should have constructors
19:50
<Domenic>
But kind of the whole point of PassThroughStream is that you should be able to use it to create either end, without creating them separately....
19:50
<Domenic>
meh, it's solvable
19:51
<Domenic>
just need to get these damn benchmarks finished
19:51
<Domenic>
then the potential simplifications can begin
20:30
<smaug____>
does chrome warn about use of some deprecated features ?
20:33
<caitp>
yes
20:38
<smaug____>
caitp: which features for example?
20:39
<smaug____>
Hmm, looks like MutationEvent usage has dropped
20:39
<caitp>
someone filed a bug on angular about browsers (including chrome) complaining about touching Event.returnValue some time ago
20:39
<caitp>
so that would be one
20:40
<smaug____>
caitp: I guess it just doesn't warn about mutation events
20:40
<smaug____>
nor sync XHR
20:40
<caitp>
i'm not sure if synchronous XHR is properly deprecated in chromium yet
20:40
<caitp>
tyoshino would probably know
20:41
<caitp>
if there was an intent to deprecate thread for that, I missed that one
20:41
<SamB>
hmm, is it that complicated that it needs deprecating in a technical sense?
20:42
<SamB>
rather than just a "hey dumbass, don't block your script on that; it's bad for UX"
20:42
<smaug____>
caitp: it is deprecated in the spec
20:42
<smaug____>
all the browser vendors agreed about that
20:42
<caitp>
yes, but not necessarily in browsers
20:43
<caitp>
IE a browser doesn't necessarily warn you, there aren't necessarily plans to remove the feature yet
20:43
<SamB>
oh, that reminds me about trigraphs
20:44
<smaug____>
well, in Gecko the plan is to "remove-when-the-usage-low-enough-and-warn-until-then"
20:45
<caitp>
that's a reasonable approach :>
21:06
<zcorpan>
Hixie: comment and close at the same time ok? or just comment?
21:11
<jarek>
Hi
21:12
<jarek>
which spec covers the data binding functionality from Polymer?
21:12
<jarek>
the template spec is said to be moved to HTML5 spec, but I can't find any mention of data binding there
21:13
<Hixie>
zcorpan: comment, if you comment and close i won't see it for months (i only read my bugmail ~annually)
21:13
<Hixie>
jarek: there is no spec that covers data binding
21:13
<Hixie>
to my knowledge
21:14
<zcorpan>
k
21:15
<jarek>
so the stuff described here is completely non-standard? http://www.polymer-project.org/docs/polymer/databinding.html
21:15
<jarek>
is there any chance that Mozilla will implement it?
21:20
<Hixie>
jarek: yes, that is currently non-standard.
21:20
<Hixie>
jarek: no idea what mozilla's plans are, but if two browsers implement this, then it's a de facto standard
21:31
<Domenic>
chrome does not implement it either
21:31
<Domenic>
it is just a library
21:31
<Domenic>
produced by the same company that produces chrome
21:31
<Domenic>
jarek ^
21:31
<smaug____>
and there isn't any spec for that data binding
21:35
<jarek>
every Web Components talk by Google I have seen was actually discussing Polymer
21:36
<jarek>
I thought it was just a shim like e.g. Traceur
21:37
<caitp>
it's sort of a mix
21:38
<caitp>
polyfills for custom elements/html imports/etc, as well as a library of components and some syntax for simplifying the creation of components + databinding
22:07
<caitp>
i dunno hixie, I think the arguments against the behaviour of constraint validation have been pretty well reasoned --- and not limited to my own criticisms of it. it's just not how people expect it to behave
22:08
<Hixie>
i don't understand the problem
22:08
<Hixie>
i mean, i really don't
22:08
<Hixie>
valueMissing tells you if the value is missing
22:08
<Hixie>
badInput tells you if the user has entered bad input
22:08
<Hixie>
that seems to me to cover all the bases
22:08
<Hixie>
what am i missing
22:09
<caitp>
that's basically it, but it's just more complicated than it really needs to be, there are things which are sort of misnomers (like [novalidate]), there's a lot of stuff there that really confuses users
22:10
<Hixie>
sounds like you're talking about more than just that bug
22:11
<Hixie>
if there's other things that need fixing, then please do file bugs (but bear in mind that if people depend on it, it's too late to change, you should have complained earlier when we asked for feedback!)
22:11
<caitp>
well, [novalidate] isn't related to the valueMissing issue, but it's in the same family of things which are not very intuitive to users
22:14
<Hixie>
that's fine, but then file a new bug :-)
22:14
<Hixie>
i thought you were talking about the bug i commented on
22:32
<Hixie>
TabAtkins: in css-font-loading - "unloaded" sounds very much like something that used to be loaded but is no longer loaded
22:32
<Hixie>
TabAtkins: consider e.g. onunload, onbeforeunload, etc.
22:32
<TabAtkins>
Hm, true.
22:33
<Hixie>
TabAtkins: i don't have a much better term, but fwiw the media stuff uses "none"
22:34
<Hixie>
other terms i've used include "empty", "idle", "nothing"
22:35
<Hixie>
TabAtkins: also it's more common to use readyState than status, fwiw.
22:36
<Hixie>
since i'm giving feedback, some more notes:
22:36
<Hixie>
i recommend against using ES-style [[Foo]] syntax, it is hard to read
22:36
<TabAtkins>
Hm. Unsure if I can change a property name, but I might try. I'll put up a message for it, at least.
22:36
<TabAtkins>
Yeah, not super happy about that either. I want something to indicate "internal" properties, though.
22:37
<TabAtkins>
(It's super-inconvenient to type, since it collides with Bikeshed's shorthands.)
22:37
<Hixie>
just say "FontFace objects have an internal font status promise, which..."
22:37
<Hixie>
where "font status promise" is <dfn>ed
22:38
<Hixie>
what's a Promise<boolean>? Aren't you really just promising a void? I mean, you'll never resolve to false, will you?
22:38
<Hixie>
i'd probably do a Promise<FontFace>, like load()
22:38
<Hixie>
(for loaded)
22:39
<Hixie>
not sure what "... of which one is not null and the rest are null." means. There's two things. One is null and the other not? What's the one that isn't null set to?
22:39
<TabAtkins>
Actually, that's an IDL error (Promise<boolean>). The promise it refers to resolves to the FontFace.
22:40
<TabAtkins>
"rest are null". Yeah, just two things. (Maybe there were more before, and this language is a remnant? I forget.) The one that isn't null gets set by the constructor.
22:43
<Hixie>
other than that, looks ok. I'm not sure about the whole Set thing, that looks a bit overcomplicated, but I assume that's just waiting for WebIDL to catch up.
22:43
<Domenic>
Can workers (service workers in particular) access WebRTC?
22:45
<Hixie>
Domenic: i don't think they've made that work yet, but long term i'm not aware of a reason that shouldn't work
22:45
<Domenic>
Ya that's kind of what I expected. Curious if there was a reason not; heartened that you don't think there is such a reason.
22:47
<TabAtkins>
Hixie: Yeah, the Set mimicry is me waiting for IDL to have something that'll do it for me. I had a [SetClass] attribute previously, but heycam ended up not wanting to spec that yet.
22:47
<TabAtkins>
I think we're waiting for JS to actually define a subclassable Set/Map/etc.
22:48
<TabAtkins>
(Right now, you simple can't subclass them properly. Either you have to manually copy methods (and thus don't get new methods added by future specs or by authors), or you aren't able to enforce any constraints (because authors can modify it via the core Map/Set methods instead, bypassing whatever restrictions you've added).
22:48
<TabAtkins>
)
22:52
<Hixie>
sounds like the mess we had (have?) with Array
22:55
<TabAtkins>
Yup.
22:55
<TabAtkins>
Except it's even less explicable, because you don't even need a Proxy to get it right.
22:57
<gsnedders>
why didn't it get it right for Set/Map/etc. first time?
22:57
<caitp>
if MySpecialSet has its own special 'add' method to enforce constraints, who is to stop me from invoking Set.prototype.add.call(mySpecialSet, value) and bypass any constraints anyways?
23:20
<Domenic>
Saying that it's "right" for a subclass to impose more restrictions than its superclass is a matter of opinion
23:20
<Domenic>
http://en.wikipedia.org/wiki/Liskov_substitution_principle etc
23:22
<SamB>
caitp: on that note, I think I'm permanently confused about which is the prototype in prototype-based programming
23:22
<jyasskin_w>
I definitely understand the desire to define a class whose specification "automatically" grows any methods added to Map, say, but which adds certain restrictions onto its values. I wouldn't call that a "subclass", but it'd be worth finding a word for it that doesn't run into LSP complaints.
23:23
<caitp>
instead of this, we implement new NoInterfaceObjects in C++ which inherit from a common base in C++ and extend the behaviour appropriately, without exposing a way to do it in scriptland
23:23
<caitp>
and this makes everybody happy
23:26
<caitp>
except that I guess we aren't even really doing that yet for all of the custom containers
23:26
<Domenic>
One way of doing this would be to divide up the container classes into "core" and "mixin" methods
23:27
<Domenic>
so e.g. .add, .delete, [Symbol.iterator] would be core; .forEach would be mixinable
23:27
<Domenic>
and if we later added e.g. .map it would be mixinable, delegating to [Symbol.iterator]
23:27
<caitp>
but you don't want to use core .add, you want to impose restrictions on what can be added to your magic collection
23:27
<Domenic>
that way you can do Object.define(MyMap, MapMixins) as long as MyMap implements the core interface
23:27
<Domenic>
yes
23:28
<Domenic>
you implement your own .add etc.; you don't subclass Map
23:28
<Domenic>
then you mixin MapMixins to get all the non-core methods
23:28
<Domenic>
I wonder if this has anything to do with traits
23:28
<caitp>
traits would have been neat, I was sad that didn't make it =(
23:29
<caitp>
[[into harmony]]
23:29
<Domenic>
this looks to be exactly related to traits
23:29
<Domenic>
based on http://soft.vub.ac.be/~tvcutsem/traitsjs/tutorial.html