2009-12-07:
[2:42] <Wes-_> ashb / kriskowal: I personally try to avoid the use of equals in discussing javascript, preferrring instead to talk about equivalent (==) and strictly-equal (===)[2:42] <Wes-_> so I would personally never name an API deepEquals :)[2:43] <Wes-_> I would go with either deepStrictlyEquals and deepEquivalent[2:45] <Wes-_> 'deep' to me means 'recursively traversing all the ownProperties which are not intrinsic types and failing when the intrinsics don't match'[2:46] <Wes-_> By intrinsic type, I mean number, string, boolean, undefined[2:46] <inimino> FWIW, "deep" to me implies recursion, but no more[2:46] <Wes-_> this leaves behind function, object, and xml (when E4X)[2:46] <Wes-_> inimino: well, you can't recurse on intrinsics :)[2:47] <Wes-_> problem with what I have seen in the newsgroup is that the tests are against not-object[2:47] <Wes-_> And what comparison to use is determined to be == or === based on whether or not we are doing equivalent or not[2:47] <Wes-_> I would short circuit NaN so that NaN and NaN are equivalent, regardless of what == says[2:48] <Wes-_> and make functions never equivalent unless they are equal[2:48] <Wes-_> and make objects only equivalent if the prototypes are equal[2:49] <inimino> to me "equivalent" is a much stronger term[2:49] <inimino> two things in JavaScript are equivalent if they are intistinguishable, but that's just an intuition from the English usage of the word[2:50] <inimino> it doesn't have any defined meaning in common usage wrt JavaScript, as far as I know[2:50] <inimino> Python people will probably think of something else, which is fine[2:53] <inimino> I think "equals" strongly suggests either of the == or === operator, so I think naming something "Equals" that matches NaN to NaN would be confusing[2:56] <JohnnyL> uh hello?[2:56] <JohnnyL> The equals op and the identify op?[2:56] <JohnnyL> identity[3:30] <Wes-_> inimino: deepStrictlyEqual(NaN, NaN)) -- you really think that should be false?[3:30] <inimino> Wes-_: yes[3:30] <Wes-_> inimino: Interesting. I think users need to be able to test that an API returns a NaN[3:31] <inimino> Wes-_: then give them assertNaN(x)[3:31] <inimino> Wes-_: it's exactly the same issue as in the language at large, the sooner people are made aware of it the less confusion there'll be overall[3:31] <Wes-_> How about deepEquivalent(testFunc(), { x: 1, y: NaN }) ?[3:32] <inimino> well, that depends what you mean by "Equivalent" :-)[3:32] <Wes-_> inimino: problem with the assert fn is that you can't test objects which contain NaN[3:32] <inimino> the word means nothing to me, or at least nothing specific enough that I'd want to see it in an API[3:32] <Wes-_> inimino: right, let's say I meant to type deepStrictlyEqual there[3:32] <Wes-_> ~ same issue for that example[3:33] <inimino> well, then yes, I'd expect that to be false[3:33] <Wes-_> inimino: interesting -- so then you believe that this should be false too? :[3:33] <Wes-_> var a = { b: NaN }[3:33] <Wes-_> deepStrictEqual(a, a);[3:34] <inimino> yes[3:34] <inimino> well...[3:34] <inimino> hehe[3:34] <inimino> that's tricky, since I'd actually expect that to short-circuit, so... no[3:35] <Wes-_> so, you'd also want[3:35] <inimino> but I'd definitely expect var a = NaN; deepStrictEqual(a, a) to be false[3:35] <Wes-_> deepStrictEqual({a: NaN}, {b: NaN}) == false[3:36] <inimino> yes, even if the property names were the same[3:36] <Wes-_> inimino: whoops, caught my typo lol[3:36] <Wes-_> Interesting, I'm in complete disagreement there, but understand your reasoning[3:37] <inimino> now I'm not saying that's the nicest thing to have to use for testing[3:37] <inimino> I'm just saying that if you're going to have "Equal" and particularly "StrictEqual" in the name I think that's the way it has to work[3:37] <Wes-_> that's definitely true[3:37] <Wes-_> suggestion for StrictEqual replacement?[3:38] <inimino> if you go and call it assertLooseyGooseyEquiv() then I know I'm going to have to read the documentation anyway[3:39] <inimino> "Equivalent" would probably work, but I expect people may have incompatible preconceptions about what that means[3:39] <Wes-_> inimino: I think we actually need *two* functions, I'm proposing deepStrictEqual and deepEquivalent, but your points w.r.t. API names are valid concerns[3:40] <Wes-_> does anybody remember where in ES3 x to the y is defined??[3:40] <Wes-_> ah found it, Math.pow, 15.8.2.13[3:41] <inimino> Math.pow()?[3:41] <Wes-_> I'm trying to figure out when -0 and +0 have different behaviour in JS[3:41] <Wes-_> thought it was there[3:41] <inimino> ah[3:41] <Wes-_> when they say "if y < 0", I wonder if that is true when y === -0?[3:42] <inimino> -0 is not < 0[3:42] <Wes-_> but it's also == 0 - (1/Infinity)[3:42] <Wes-_> isn't it?[3:43] <inimino> well, hm...[3:43] <Wes-_> (the number approaching zero from the left hand side of the y axis)[3:43] <Wes-_> asymptotically approaching[3:44] <inimino> yes it is, but I don't think anything in the language treats it as negative[3:44] <inimino> I could be wrong though[3:45] <Wes-_> ah, yes, I was right, 15.8.2.13[3:45] <Wes-_> 0 to the power of -1[3:45] <Wes-_> js> Math.pow(0,-1)[3:45] <Wes-_> Infinity[3:45] <Wes-_> js> Math.pow(-0,-1)[3:45] <Wes-_> -Infinity[3:45] <Wes-_> bet you didn't know that![3:47] <inimino> heh[3:47] <inimino> I didn't[3:48] * Wes-_ got bit by that once[3:48] <Wes-_> in a test suite, though, not a real world example[3:48] <Wes-_> the "bite" is that SVR4-derived spidermonkeys get it wrong[3:48] <Wes-_> and have for 10 years[3:49] <inimino> yeah I was just going to say...[3:49] <Wes-_> I wrote a patch, covers a few other related things. Still need to get it pushed through moz (needs polish and better efficiency on trace)[3:49] <inimino> doesn't do that in my shell[3:49] <Wes-_> same bug exists on cygwin spidermonkey, but not most platforms[3:50] <inimino> ok[3:50] <Wes-_> interesting little factoid, eh? :)[3:50] <inimino> plain old spidermonkey shell here on Linux gives regular Infinity[3:50] <Wes-_> it's wrong on SVR4 because the error handling from the math library is different than GNU[3:50] <Wes-_> for Math.pow(-0,-1) ?[3:51] <inimino> er, no[3:51] <Wes-_> phew[3:51] <inimino> I was testing something else[3:51] <inimino> that is crazy[3:53] <inimino> js> Math.pow(-0,-2)[3:53] <inimino> Infinity[3:53] <inimino> js> Math.pow(-0,-1)[3:53] <inimino> -Infinity[3:53] <inimino> gah[3:56] <Wes-_> inimino: it's actually logical if you think of 0 and -0 as numbers approaching zero[3:56] <Wes-_> in a sort of math-professor-logical version of logic[3:56] <Wes-_> specifically, the calculus type of math professor[3:58] <inimino> true[4:06] <deanlandolt> Wes-_: isNaN IIRC should _never_ be used according to mark[4:07] <deanlandolt> i think he recommended something like x !== x as the right check (NaN is the only thing in the language that will return false)[4:16] <Wes-_> deanlandolt: AH! that's a good test[4:16] <Wes-_> can you think of a place where isNaN is wrong?[4:17] <Wes-_> (does it coerce to number?)[4:17] <deanlandolt> if i find MM's old email i can :)[4:17] <Wes-_> he's really good at that stuff[4:17] <deanlandolt> isNaN("") === true[4:18] <deanlandolt> http://groups.google.com/group/commonjs/browse_thread/thread/c2fa51581efe6ccc/163f161e05ef5055?lnk=gst&q=mark+miller+isNaN#163f161e05ef5055[4:18] <Wes-_> stupid stupid stupid[4:18] <Wes-_> that means that its coercing with the ToNumber rule[4:18] <Wes-_> or does it[4:18] <Wes-_> HmMm[4:19] <Wes-_> yeah, that must be what's going on[4:19] <Wes-_> isNaN("5") is true[4:19] <deanlandolt> spectacular[4:20] <deanlandolt> i'd say that's a pretty big wart[4:22] <deanlandolt> someone suggested documenting all of these rough edges somewhere...maybe this week i'll start sweeping them up and dumping them on the wiki[4:24] <Wes-_> ER, isNaN("5") is false, but you knew I meant, I think[4:24] <Wes-_> deanlandolt: I made the suggestion and am sort of doing that[4:24] <Wes-_> deanlandolt: would appreciate help[4:25] <Wes-_> I've expanded the scope to something along the lines of "JavaScript: a reintroduction"[4:25] <deanlandolt> Wes-_: whatcha need?[4:25] <deanlandolt> oh, i see..t.he rought edges stuff[4:25] <Wes-_> deanlandolt: Here's where I'm at right now, FWIW: http://code.google.com/p/gpsee/wiki/JavaScript_FAQ[4:25] <Wes-_> Still in the writing (not proofing) phases[4:25] <Wes-_> about to start talking about comparisons[4:26] <deanlandolt> cool...i'll start collecting examples and get them to you[4:26] <Wes-_> there's probably also some stuff in there that people would take issue with, but I'm trying to be as pragmatic as possible without lying[4:26] <Wes-_> for example, I consider undefined an intrinsic type[4:27] <Wes-_> and actually, doing so has helped a fair bit of logic to flow together, including in my newsgroup post earlier[4:27] <deanlandolt> one note -- it may make sense to write the examples in a doctest style[4:27] <Wes-_> what's doctest?[4:27] <deanlandolt> it's effectively a copy/paste of a console session[4:28] <deanlandolt> so you show the prompt and the output[4:28] <deanlandolt> (and yes, your whole reintroduction would be testable as a side-effect)[4:28] <deanlandolt> js> print("hello");[4:28] <deanlandolt> hello[4:29] <Wes-_> Oh, I see[4:29] <Wes-_> I thought of doing that, but I don't like how the js> prompt screws with the indentation, but I can work around that[4:29] <deanlandolt> yeah, that is a bit of a mess[4:29] <deanlandolt> but being able to see input/output is nice[4:29] <deanlandolt> instead of (Output is X)[4:30] <deanlandolt> i'll start reading now[4:30] <deanlandolt> as for undefined as an intrinsic type...it's not?[4:30] <Wes-_> yeah, I agree[4:30] <Wes-_> heh[4:30] <Wes-_> I knew that would be a contensious point[4:31] <Wes-_> I think of it as an intrinsic type with only one value and no coercion rules[4:31] <deanlandolt> oh no, not contentious...[4:31] <deanlandolt> at least w/ me -- i think of it the same way...wasn't aware anyone thought otherwise[4:31] <deanlandolt> but i haven't read the es specs cover to cover :/[4:32] <Wes-_> most people I have had this discussion with tell me it's not a type, it's the absence of one[4:32] <Wes-_> kinda like NaN is not a number[4:32] <deanlandolt> well, sounds like a meta-rough-edge that could get documented at the bottom ;)[4:32] <Wes-_> but then they get annoyed when I point out that typeof(NaN) === "number"[4:32] <deanlandolt> typeof(undefined)==="undefined"[4:33] <Wes-_> BTW, any feedback and/or text is appreciated. This is all stuff that every JS programmer oughta know any most don't.[4:33] <Wes-_> deanlandolt: not always, undefined is a variable[4:33] <Wes-_> js> typeof(undefined=1)[4:33] <Wes-_> number[4:33] <deanlandolt> ah yes[4:34] <deanlandolt> i'll get you some feedback and will try to dig up some examples (and remember all the times i've stabbed myself in the eye)[4:42] <deanlandolt> Wes-_: referencing an undefined property generates a strict-mode warning?[4:43] <Wes-_> deanlandolt: It does in spidermonkey, IIRC, but I haven't double checked ES5 on that[4:43] <deanlandolt> cool...at least it's just a warning and it doesn't throw[4:43] <Wes-_> oh oh[4:43] <deanlandolt> python throws and that drives me /crazy/[4:43] <Wes-_> oh, no oh oh[4:43] <Wes-_> I thought I was using gpsee's REPL, which is strict[4:43] <Wes-_> but I was using tracemonkeuy's, which is not[4:44] <Wes-_> unless you options("strict")[4:44] <Wes-_> Hmm, maybe te word "referencing" isn't what I want, though.. in C I would de-reference[4:45] <Wes-_> js> options("strict")[4:45] <deanlandolt> dereference is the /techincal/ term[4:45] <Wes-_> js> function a() {};[4:45] <Wes-_> js> var b = new a();[4:45] <Wes-_> js> var c = b.hello;[4:45] <Wes-_> js> print(b.hello)[4:45] <Wes-_> typein:28: strict warning: reference to undefined property b.hello[4:45] <Wes-_> undefined[4:45] <deanlandolt> i'll have to poke around es5 for that...this is the first i'm hearing of it[4:46] <Wes-_> well, the assignment doesn't yield the strict mode warning, which I would consider a reference[4:46] <deanlandolt> i hope that doesn't mean they're moving toward throwing in that case[4:46] <Wes-_> but *using* the property does[4:46] <Wes-_> I don't think they are, that would change the language[4:46] <Wes-_> of course, "use strict" changes it anyhow[4:46] <Wes-_> but pretty subtly IME[4:47] <deanlandolt> i was looking forward to "use strict"ing the crap out of my code once the engines all support it[4:47] <deanlandolt> now i'm not so sure[4:48] <deanlandolt> in any event...print(b.hello) warning doesn't bother me, as long as c = b.hello doesn't blow up my console with warnings[4:57] <Wes-_> deanlandolt: IIUC firefox is already throwing strict-mode warnigns (although this is spidermonkey strict mode, which is not ES5 strict mode yet)[4:57] <Wes-_> deanlandolt: do you understand why 1 || true is 1 ?[4:58] <Wes-_> oh wait, I get it[5:27] <Wes-_> function isNegZero(n) (n == 0) && (Math.pow(n, -1) == -Infinity)[5:27] <Wes-_> I guess I hsould be using --- there instead[5:55] <inimino> Wes-_: so 1/x == -Infinity would also work there, apparently[6:06] <Wes-_> inimino: good catch, probably faster too[6:10] * Wes-_ updates his page before he forgets[11:50] <ashb> Wes-_: intersting thing about -0 in perl[11:50] <ashb> $x = -0; if ($x) {[11:50] <ashb> -0 is 0 so is false. but[11:50] <ashb> $x = -0; $x = "$x" if ($x)[11:50] <ashb> is true[11:52] <ashb> deanlandolt: http://bulknews.typepad.com/blog/2009/12/plack---lpw-2009.html[11:52] <ashb> see slide 79[11:55] <zilenCe> ashb: nice one :D[11:57] <ashb> Wes-_: +0,-0 are required be IEEE 754 i think[11:59] <ashb> Wes-_: undefined section: delete also affects what the |in| operator returns[13:17] <ashb> hannesw: *whoop* *whoop* Arrowhead detected[13:19] <hannesw> ashb: arrowhead?[13:19] <ashb> http://www.codinghorror.com/blog/archives/000486.html[13:19] <hannesw> sorry, you have to use simpler language with me :)[13:20] <hannesw> ah, ok :)[13:20] <ashb> just ltos of nesting/indenting[13:20] <ashb> hannesw: actually http://bulknews.typepad.com/blog/2009/12/plack---lpw-2009.html page 79[15:27] <deanlandolt> ashb: i don't quite follow that example...what the heck is AnyEvent?[15:27] <deanlandolt> is that like the Any Key?[15:28] <ashb> AnyEvent is a wrapper around the various event loops available in perl[15:28] <ashb> but that wasn't the relevant bit[15:28] <deanlandolt> the relevant bit, i presume, is that they can do it...right?[15:28] <ashb> and the API is interesting[15:29] <ashb> want me to convert that to JS so you can see?[15:29] <deanlandolt> ha...that'd be helpful...haven't read perl in quite a while[15:30] <MisterN> hmm yeah an event-loop would be among the things that lend well to standardisation[15:30] <MisterN> cause it HAS to be written in c/c++/java[15:30] <MisterN> at least if you want reasonable performance[15:31] <ashb> http://pastie.org/731906[15:31] <ashb> deanlandolt: ^^[15:31] <deanlandolt> ashb: got it[15:32] <ashb> kriszyp: see http://pastie.org/731906 and http://bulknews.typepad.com/blog/2009/12/plack---lpw-2009.html page 79[15:34] <deanlandolt> so an async app passes back a function that takes status and headers args and allows you to write and close?[15:34] <deanlandolt> how do you get the current status and headers?[15:34] <deanlandolt> i read the whole presentation to get a better idea[15:35] <ashb> it doesn't cover that case actually[15:35] <ashb> and I would ask miyagawa, but he's somewhere over the atlantic right now[15:35] <deanlandolt> hmm...middleware not being able to switch on response headers seems pretty limited[15:35] <ashb> well you provide a proxy object to the function could work[15:36] <deanlandolt> i'll think on that one for a bit[15:36] <ashb> knocking up an example[15:41] <ashb> it really needs a bit of util code to make it nicer tho[15:44] <ashb> deanlandolt: http://pastie.org/731906[15:45] <deanlandolt> ashb: awesome, thanks[15:45] <ashb> and a lot of that logic can be simplified out[15:45] <ashb> let me refactor that to make it slightly clearer what its doing[15:45] <deanlandolt> i'll read it as it, just tell me when to refresh[15:46] <ashb> refresh[15:47] <deanlandolt> that's not so bad[15:48] <ashb> basically the switching on async/not can be wrapped up in a util function[15:48] <deanlandolt> nice[15:49] <deanlandolt> one thing...how would middleware be able to see/modify individual streamed chunks?[15:49] <deanlandolt> (i'm thinking for something like gzip middleware)[15:49] <ashb> same concept[15:49] <ashb> you create a proxy object[15:50] <deanlandolt> and intercept the write calls[15:50] <deanlandolt> hmm[15:50] <ashb> refactored again[15:50] <deanlandolt> that's pretty elegant[15:50] <ashb> i think that paste should work[15:50] <ashb> might be a few logic errors or something, but the idea should work i think[15:51] <deanlandolt> yeah, i think i'm following[15:51] <deanlandolt> the async app gets a response object /from/ the middleware to write in to[15:52] <ashb> oh yeah - i'm missing a whole level of function[15:52] <ashb> (to get the request)[15:57] <ashb> deanlandolt: refresh again[15:58] <deanlandolt> hmm...that doesn't look too onerous[15:59] <ashb> you might be able to simplify it a bit by making middleware alwasy return async even if the app was sync[15:59] <deanlandolt> yeah (that's what i'd do anyway)\[15:59] <deanlandolt> there's not really a performance hit there so why not[16:00] <deanlandolt> i was planning on doing the same thing with the promise stuff...frankly, it gives us an added benefit -- that response wrapper can have other nice helpers in it[16:02] <deanlandolt> ashb: i'll be right back but i really like this[16:02] <ashb> :D[16:03] <deanlandolt> a few util functions could really shorten this[16:03] <deanlandolt> and for error handling you can just wrap the return r(appResponderProxy); in a try, right?[16:05] <ashb> yeah[16:05] <deanlandolt> nice[16:05] <ashb> you can make a JSGI.Middleware class[16:05] <ashb> and have thingsl ike onHeader, onError, onBodyChunk, onBodyClose[16:05] <ashb> that you provide or not as desired[16:06] <deanlandolt> yeah, that's close to what i was thinking[16:06] <ashb> which is what Plack does[16:06] <ashb> the problem there of course is that it does merge SPEC and an implementation[16:06] <deanlandolt> stealing good ideas is always better than trying to come up with them on your own :)[16:06] <ashb> hmmm i wonder why SPEC was shouty there[16:06] <deanlandolt> ashb: it doesn't have to -- you can spec the low level[16:07] <deanlandolt> and the helpers are just optional deps[16:07] <deanlandolt> alright...i'll be back[16:16] <ashb> i need to think/check that it works when the middleware still works as nicely when the adjuster does some event itself[16:16] <ashb> er,[16:16] <ashb> you know what i mean[16:21] <ashb> i dont think it should make it any more complex[16:31] <deanlandolt> hannesw_: have i totally misunderstood promises?[16:31] <deanlandolt> can't you call then with additional onSuccess functions and have them execute?[16:32] <deanlandolt> i was under the impression it was like deffered.addCallback[16:32] <ashb> deanlandolt: my understanding is that a promise will only signal once[16:32] <hannesw_> deanlandolt: you may very well be right[16:33] <ashb> so adding a cb after it has signaled will do nothing[16:33] <hannesw_> I haven't done anything with promises so far[16:33] <deanlandolt> but you'd be tacking on the callback in middleware before it's been fulfilled[16:33] <deanlandolt> hannesw_: neither have i...only read about them :-/[16:34] <hannesw_> so definitely trust kriszyp more than me[18:55] <deanlandolt> Wes-_: from es5 8.1: The Undefined type has exactly one value, called undefined. Any variable that has not been assigned a value has the value undefined.[18:57] <ashb> deanlandolt: that is different to "undefined" variable[18:57] <ashb> i think anyway[18:57] <deanlandolt> ashb: ugh[18:58] <deanlandolt> i give up trying to understand undefined :)[18:59] <ashb> deanlandolt: most of the problem comes from that fact that you could do[19:00] <ashb> undefined = 1;[19:00] <ashb> ES5 strict probably makes that an error[19:00] <deanlandolt> yeah, wes pointed that out[19:00] <deanlandolt> got another meeting...back in a bit[20:51] <deanlandolt> ashb: re: my understanding is that a promise will only signal once...[20:52] <deanlandolt> i've been doing a little screwing around with the then method and it's actually pretty elegant...sure, it'll only signal once, but you can keep tacking then callbacks onto already-resolved promises and they are run immediately[20:54] <ashb> deanlandolt: ah. iu wasn't aware that was supposed to happen[21:00] <deanlandolt> yeah, kinda nice[21:00] <deanlandolt> so they can self-resolve and become syncronous[21:11] <inimino> deanlandolt: node currently doesn't actually do that but it's planned[21:56] <deanlandolt> inimino: i was actually using the narwhal promise implementation but good to know node is on it too[23:25] <isaacs> so, there's a new ES5 spec, I'm told. http://www.ecma-international.org/publications/standards/Ecma-262.htm[23:25] <isaacs> anyone in here privy to the changes and feel like summarizing so that I don't have to diff the PDFs myself? ;)[23:27] <ashb> isaacs: large changes:[23:28] <ashb> Object.keys[23:28] <ashb> Object. has a lot of other useful functions[23:28] <isaacs> kewl.[23:28] <ashb> isaacs: the property descriptor stuff is cool too[23:28] <ashb> lets you create non-enumerable props in JS[23:28] <ashb> from JS[23:28] <isaacs> right[23:29] <isaacs> i've seen that discussed quite a bit already. Object.defineProperty etc[23:29] <ashb> yeah[23:29] <ashb> there is Object.seal etc too[23:29] <isaacs> wrapping up the moz-specific __defineSetter__ and __defineGetter__ in less uglified ways[23:29] <ashb> lots of cool stuff[23:29] <isaacs> seal, walrus, narwhal, etc.[23:29] <isaacs> i get it[23:30] <isaacs> anything outside of the Object statics?[23:30] <ashb> probably[23:47] <inimino> isaacs: if you looked at the September draft, the ratified spec is the same[23:47] <isaacs> ah, ok, great[23:47] <isaacs> thanks![23:48] <inimino> :)
Logs by date :