Mochabot log - CommonJS IRC channel: #commonjs on irc.freenode.net

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 :