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

2009-12-21:

[12:25am] <isaacs_ is now known as isaacs.
[03:25am] <tlrobinson> ondras / isaacs how do you implement require without a different require function per module?
[03:26am] <isaacs> tlrobinson> well, you could just have a single function require (mod) that does it for you
[03:26am] <tlrobinson> isaacs> but how does it handle relative ids
[03:26am] <isaacs> i mean, node actually has a single loadModule function that gets used
[03:26am] <isaacs> well, you'd have to resolve that by figuring out which module you're in at the moment of it being called.
[03:27am] <isaacs> bt yeah, seems easier to do with a fresh closure for each module.
[03:27am] <tlrobinson> that will only work in some cases
[03:27am] <tlrobinson> exports.foo = function() { require("./blah") }
[03:27am] <isaacs> that's an interesting test. i wonder if node has a test for that.
[03:28am] <isaacs> but yeah, i think that'd work just fine, because each "require" is actually trapped with a specific module ref inside a closure.
[03:29am] <tlrobinson> if each require is a separate function closing on the module id, yeah
[03:29am] <ashb> isaacs> http://github.com/kriskowal/commonjs/tree/master/tests/
[03:29am] <ashb> should be a test in there for ./require
[03:29am] <ashb> oh doesn't seem to test ./
[03:30am] <ashb> oh yes there is
[03:30am] <kriskowal> gpsee and v8cgi are stack-based.
[03:30am] <tlrobinson> if v8cgi only uses a single "require" function for all modules then i'm pretty sure that case will fail
[03:31am] <ashb> http://github.com/kriskowal/commonjs/tree/master/tests/modules/1.0/relative/
[03:31am] <kriskowal> that's likely, tlrobinson
[03:31am] <ashb> damn coda sucks as an editor
[03:32am] <kriskowal> tlrobinson, we'll have to add a test for that.
[05:19am] <erikg_ is now known as erikg.
[05:35am] <cpojer1 is now known as cpojer.
[07:42am] <ondras> tlrobinson> yes, relative requires at non-execution time fail
[07:42am] <ondras> and I am kinda happy with this approach
[07:42am] <ondras> because it is identical to what php does
[07:43am] <tlrobinson_> ondras> as long as you know it's incompatible with the spec / other implementations...
[07:43am] <ondras> => relative paths are resolved with respect to the code they are *executed* in, not *defined* in
[07:43am] <ondras> also, at the time of implementation, I am pretty sure this was not a requirement / explicitely mentioned
[07:44am] <tlrobinson_> also, aspiring to be like PHP seems like it would be unwise in many cases
[07:45am] <ondras> tlrobinson_> people comming to commonjs from php would probably disagree here .)
[07:45am] <ondras> *coming
[07:46am] <kriskowal> is there a case where it would ever be a useful behavior?
[07:46am] <kriskowal> or do you keep it this way to prevent it from being used
[07:47am] <ondras> Relative identifiers are resolved relative to the identifier of the module in which "require" is written and called.
[07:47am] <ondras> hmmh
[07:48am] <ondras> what if "written" != "called" ?
[07:48am] <kriskowal> that strikes me as a contradiction
[07:49am] <ondras> kriskowal> actually, I never used/written a module which would benefit from a "delayd require"
[07:49am] <ondras> *delayed
[07:49am] <tlrobinson_> it will be resolved relative to the last module evaluated
[07:49am] <tlrobinson_> won't it?
[07:49am] <ondras> e.g. exports.foo = function() { require("./xxx"); }
[07:50am] <ondras> tlrobinson_> relative to the module in which it is called
[07:50am] <tlrobinson_> either way it seems like it would be unpredictable
[07:50am] <tlrobinson_> what does "called" mean
[07:50am] <kriskowal> no, that's not it exactly.
[07:50am] <ondras> well, it is php's behavior, if that makes it easier to comprehend...
[07:51am] <kriskowal> with your implementation, the module identifier will be resolved relative to the topmost module currently being evaluated, which is not deterministic
[07:51am] <kriskowal> so, it's not the module in which "require" is being called, but the module in which "foo" is being called.
[07:51am] <ondras> exactly.
[07:51am] <kriskowal> unless "foo" has already been loaded, in which case it falls back to whomever required "foo". not deterministic.
[07:51am] <ondras> it is nondeterministic as long as the require is not executed in module's top level
[07:52am] <ondras> which I use and recommend
[07:52am] <tlrobinson_> if i have a> 'exports.a = function() { require("b").b(); }' and b> 'exports.b = function() { require("./c") }' then ./c will be resolved relative to wherever require("a").a() is called
[07:52am] <ondras> OTOH, in my opinion, generic "relative" term always implies some level of nondeterminism, as everything which is relative must have some base
[07:53am] <tlrobinson_> i'm not sure why you would ever want that behavior
[07:53am] <ondras> I would probably not
[07:53am] <kriskowal> i've used a require call from within a function on several occasions.
[07:53am] <ondras> but as I said before
[07:53am] <ondras> I have - so far - three good reasons to keep it that way
[07:54am] <ondras> 1) no direct conflict with spec; 2) php-compatible; 3) ony one require() necessary
[07:54am] <ondras> also, I do not like conditional includes
[07:54am] <ondras> so having require in a non-top level is not something I prefer
[07:54am] <tlrobinson_> ondras> i'm pretty sure it conflicts with the spec. if it doesn't then the spec is wrong
[07:54am] <kriskowal> 1 is false. 2 isn't a good reason. i don't know what 3 means.
[07:54am] <ondras> 07:47 < ondras> Relative identifiers are resolved relative to the identifier of the module in which "require" is written and called.
[07:56am] <ondras> var a = require().a; a("./othermodule");
[07:56am] <ondras> if a is defined as "exports.a = function(id) { return require(id); }"
[07:57am] <ondras> then ./othermodule is being - in my implementation - resolved relative to the module in which it is called
[07:57am] <ondras> but not being written
[07:57am] <tlrobinson_> it's resolved relative to the last evaluated module
[07:58am] <kriskowal> to accomplish that in other systems involves explicitly resolving the identifier in the calling module.
[07:58am] <ondras> evaluated == called, okay?
[07:58am] <ondras> imho the phrase from spec I posted is not okay
[07:58am] <ondras> because I comply with one verb and not the other
[07:58am] <ondras> "written and called"
[07:58am] <ondras> that is the problematic place for me
[07:58am] <kriskowal> called is perhaps ambiguous, but not in the context of written
[07:59am] <ondras> generally speaking, we are right now describing the case where written != called
[07:59am] <ondras> exports.foo = function() { require("./b"); }
[07:59am] <ondras> do we agree on this one?
[07:59am] <kriskowal> no
[07:59am] <ondras>
[08:00am] <ondras> well then
[08:00am] <kriskowal> that is the case we're talking about, but require is written in the module, and called in the same module. you have to walk up the stack to find a function that's written in a different module.
[08:01am] <ondras> I do not agree here - the require is not called (yet)!
[08:01am] <kriskowal> more to the point, the "closure" of require is rooted in that module's scope. that's what it means to be called in a module.
[08:01am] <kriskowal> i will concede that "called" is ambiguous depending on whether we're talking about "dynamic" or "static" scoping.
[08:02am] <kriskowal> but in modern computing contexts, you're almost never talking about dynamic scoping. it's not even supported by lisp anymore.
[08:02am] <kriskowal> certainly not common anyway.
[08:02am] <kriskowal> http://en.wikipedia.org/wiki/Scope_(programming)#Static_versus_dynamic_scoping
[08:03am] <ondras> kriskowal> well, if I understand it, your terminology is okay as long as there are multiple require()s
[08:03am] <ondras> so each module has its own
[08:03am] <kriskowal> that's not necessarily the case.
[08:04am] <ondras> 08:01 < kriskowal> more to the point, the "closure" of require is rooted in that module's scope.
[08:04am] <kriskowal> you could just have one "require", but you would have to search the closure instead of the stack.
[08:04am] <kriskowal> which is the difference between dynamic and static scoping, in a nutshell
[08:05am] <ondras> so, we moved to "what it means to be called in a module"
[08:05am] <ondras> let me show an example
[08:06am] <ondras> /* a.js */ exports.displayIt = function(x) { alert(x); }
[08:06am] <ondras> /* main.js */ require("a").displayIt("hi");
[08:06am] <ondras> in which module is the alert() called?
[08:06am] <kriskowal> a.js
[08:07am] <ondras> hmmh
[08:07am] * ondras would say main.js
[08:07am] <ondras>
[08:07am] <kriskowal> you cannot reliably say main.js even if you subscribe to the notion of dynamic scoping.
[08:07am] <kriskowal> what if main.js has already been loaded and you're calling a.displayIt("hi") in response to another module
[08:08am] <ondras> than the alert is called in the other module
[08:08am] <ondras> the one currently being evaluated
[08:08am] <kriskowal> in the dynamic scope of the other module, yes
[08:08am] <ondras> I don't know why, but it just makes perfect sense to me
[08:08am] <ondras> although it looks like a complete deviation to most of other people
[08:09am] <ondras> btw
[08:09am] <kriskowal> the point is that the writer of the code is giving up the right to know which module they're getting.
[08:09am] <kriskowal> with your impl. which is a programming hazard.
[08:09am] <kriskowal> someone else gains the ability to subvert your intent.
[08:09am] <ondras> kriskowal> imho he already gave up the right by deciding to use relative paths
[08:10am] <ondras> however, I see your point
[08:10am] <ondras> let me show another code snippet:
[08:10am] <ondras> exports.require = require;
[08:10am] <ondras> this is not a good idea, okay?
[08:11am] <ondras> because in other impls, exported require will act differently from the default one, ok?
[08:11am] <ondras> var req = require("somemodule").require; req("./xxx");
[08:13am] <kriskowal> real-world example> pixastic is a client side canvas filtering library by jacob seidelin
[08:14am] <kriskowal> i ported it to chiron. it has dozens of filters.
[08:14am] <kriskowal> you don't want to load them unless they're being used, unless you want your engine to start acting too much like photoshop.
[08:14am] <kriskowal> so, i set it up to load those modules on demand.
[08:15am] <kriskowal> where those modules are does not depend on who required me. it depends on where i am.
[08:16am] <kriskowal> http://code.google.com/p/chironjs/source/browse/trunk/src/pixastic.js#154
[08:18am] <ondras> makes sense
[08:20am] <ondras> so now, how do you implement these requires without js?
[08:22am] <kriskowal> you have a module scope object, right?
[08:22am] <ondras> no
[08:23am] <kriskowal> a context for each module?
[08:23am] <ondras> no
[08:23am] <ondras> I evaluate them in "exports" context
[08:23am] <kriskowal> so, exports ends up on the scope chain?
[08:23am] <ondras> (if we share the "context" terminology!")
[08:23am] <ondras> no, exports == this
[08:23am] <kriskowal> i'm using "context" in the ECMA specification sense, which should match what it means in the v8 engine internals.
[08:23am] <ondras> it might be easier to explain how I do it now
[08:24am] <kriskowal> oh. in ECMA parlance, "this" is the "activation object"
[08:24am] <ondras> ah, sorry
[08:24am] <ondras> so, what I do:
[08:24am] <ondras> 1) prepend "(function(exports, module){" before module code
[08:24am] <ondras> 2) append "})" after module code
[08:24am] <ondras> 3) evaluate code, fetch resulting function
[08:25am] <ondras> 4) call that function with 2 arguments in exports activation object
[08:25am] <ondras> done.
[08:25am] <kriskowal> "context" object has a bunch of roles. it's "this" in a program's top-level scope. it's "this" in any function that's not called as a constructor. it's also the top of the scope chain.
[08:26am] <kriskowal> okay. so relative identifiers don't work at all.
[08:26am] <kriskowal> not just in the inside a function case. interesting.
[08:26am] <ondras> why not?
[08:26am] <ondras> they certainly do, so perhaps I made some mistake here
[08:27am] <ondras> ah, "0) push module's path to stack of module paths"
[08:27am] <kriskowal> the require function doesn't have any information about where require is called, neither based on the stack nor based on the scope chain.
[08:27am] <ondras> "5) pop module's path from stack"
[08:27am] <kriskowal> oh, i see.
[08:27am] <kriskowal> you maintain a parallel stack
[08:27am] <ondras> yes
[08:27am] <kriskowal> yeah, equivalent to dynamic scoping.
[08:28am] <kriskowal> here's a thought experiment to illustrate why dynamic scoping is not in vogue?
[08:28am] <kriskowal> if javascript employed dynamic scoping, this would work:
[08:29am] <kriskowal> (function (foo) { var a = 10; foo() })(function () {print(a)})
[08:30am] <kriskowal> this would be the case even if the two functions were declared in two different files.
[08:30am] <kriskowal> which is to say, it is impossible, in any scope, to know what free variables there are.
[08:31am] <kriskowal> which means that because the programmer has opted to use variables (analogous to relative identifiers), they have given up on knowing what they are and where they came from, so it is impossible to maintain any invariants about them.
[08:32am] <ondras> http://bespin.cz/~ondras/html/classv8_1_1Context.html
[08:32am] <ondras> hmmh
[08:32am] <ondras> creating one of these for every module ...
[08:32am] <ondras> that is too heavy-weight imho
[08:32am] <ondras> but I do not see anything lighter in v8 api
[08:33am] <kriskowal> yeah, that wouldn't do.
[08:33am] <ondras> also, if every v8 context has its own globals, I am f*cked
[08:33am] <ondras> because of instanceof Object tests, etc
[08:33am] <kriskowal> helma gets around that
[08:33am] <kriskowal> by making every context.__proto__ == a single global
[08:34am] <kriskowal> gpsee does that too, i think.
[08:34am] <kriskowal> but, i agree that creating a new context for each module is heavy.
[08:34am] <ondras> there might be another way for this
[08:34am] <ondras> (althought I am not aware of any right now)
[08:34am] <kriskowal> in any case, the trick is that you would need to walk the closure's scope chain until you find whatever scope is a module scope and resolve the relative identifier based on that.
[08:35am] <kriskowal> alternately, you could do it in pure javascript, which is both easy and light-weight
[08:35am] <ondras> by prepending the module code with some more js, containing definition of a module-specific require?
[08:36am] <kriskowal> no, simpler.
[08:36am] <kriskowal> you inject a require with the thing you're already using to wrap
[08:36am] <kriskowal> (function (require, exports, module) {?})
[08:36am] <kriskowal> then, when you call that, you pass it a version of require that closes on the module id
[08:36am] <ondras> well
[08:37am] <ondras> can I build that version in c/c++ ?
[08:37am] <ondras> imho no
[08:37am] <kriskowal> http://github.com/kriskowal/narwhal/blob/master/lib/sandbox.js#L243-248
[08:37am] <kriskowal> why not?
[08:38am] <ondras> hm, maybe yes, but I don't know why
[08:38am] <kriskowal> you could make a FunctionTemplate and set a property on it
[08:38am] <cpojer1 is now known as cpojer.
[08:39am] <kriskowal> alternately, you could do another eval.
[08:39am] <ondras> hmmh
[08:40am] <ondras> so I would need a c require bound to a functiontemplate
[08:40am] <ondras> which is able to get its js property
[08:40am] <ondras> and that property is a (dontenum) module identifier
[08:40am] <kriskowal> somethign like Handle subRequire = v8::Compile("(function (require, resolve, baseId) {return function (id) {return require(resolve(id, baseId));})")->Call(v8::Undefined(), require, resolve, baseId)
[08:42am] <ondras> I will try some experiments with this stuff
[08:42am] <kriskowal> an arg count and an arg array have to be constructed for that; sorry for the imprecise syntax
[08:42am] <ondras> np
[08:44am] <kriskowal> cool, thanks for hearing me out.
[09:34am] <ondras> hmmh
[09:34am] <ondras> require.paths is now a little bit more tricky
[09:35am] <ondras> in my config file, I do require.paths = [....]
[09:35am] <ondras> but this only modifies the require specific to this config module
[09:35am] <ondras> oh my.
[09:35am] <ondras> kriskowal> is there some best practice for solving this?
[09:35am] <kriskowal> i use splice
[09:36am] <ondras> hmhm
[09:36am] <kriskowal> oh, and i copy paths to every require object
[09:36am] <ondras> so the point is
[09:36am] <ondras> that the "paths" exists independently on require
[09:36am] <ondras> and is copied to every require
[09:37am] <kriskowal> yeh. es5 properties will make this problem go away.
[09:37am] <kriskowal> which is no comfort in the interim, i know
[09:37am] <ondras> maybe it can be *cloned* to every require
[09:38am] <ondras> hm, cloning no-no
[09:38am] <ondras> okay
[09:50am] <oberhamsi> whats currently the "best" module loader for inbrowser? chiron?
[09:59am] <kriskowal> as the one who wrote chiron, i must say, "no".
[10:00am] <kriskowal> oberhamsi and there is only pareto optimal for browsers.
[10:01am] <kriskowal> different techniques with tradeoffs. i think the sproutcore and bespin folks might be the furthest along for browser loading.
[10:01am] <kriskowal> i'm working on it. narwhal has a jack module that'll host modules for client-side.
[10:01am] <kriskowal> but that's just one way to do it.
[10:03am] <oberhamsi> ok thx i want something standalone, so i'll check if spurtcore/bespin works for me
[10:07am] <ondras> hmm
[10:07am] <ondras> require.paths = forbidden
[10:07am] <ondras> individual requires are more restrictive
[10:16am] <ondras> kriskowal> so, implementation took cca 30 minutes; testing is now in progress...
[10:24am] <oberhamsi> hm sproutcore seems to resolve clientside requires at buildtime and bespin's loader.js is nharwal-specific... *still searching*
[10:30am] <ondras> kriskowal> btw, please let me know when you are avail, I want to discuss one more thing
[12:12pm] <oberhamsi> didn't find an easy to use, dropin clientside moduleloader so i'm back to chiron's/modules.js
[12:16pm] <Dantman> Tch, I can't remember what I was always calling the module system anymore...
[12:16pm] <Dantman> I can't remember some word, something like mutated fusion, unholy combination, or something... I called PHP's array() the same thing but I still can't remember.
[12:24pm] <Dantman> Oh right, bastard child
[12:24pm] <Dantman> Heh
[1:40pm] <hassox_ is now known as hassox.
[2:52pm] <hassox_ is now known as hassox.
[6:35pm] <You left the chat by being disconnected from the server.
[6:36pm] <You rejoined the room.
[7:07pm] <RayMorgan_ is now known as RayMorgan.
[7:50pm] <isaacs> kriskowal> here's one for you> require("constructor")
[7:51pm] <kriskowal> what kind of thing is this?
[7:51pm] <isaacs> also> require("./__proto__")
[7:51pm] <isaacs> in line with your use of "hasOwnProperty" as a module id
[7:51pm] <kriskowal> sure. we should add tests for those.
[7:51pm] <kriskowal> i have to wonder whether they would actually cause problems though.
[7:51pm] <ashb> heh. interesting edge cases
[7:52pm] <isaacs> thing is, if you do this> var cache = {}; cache.constructor = {...};
[7:52pm] <isaacs> then cache.constructor still === Object
[7:52pm] <ashb> constructor could
[7:52pm] <isaacs> easy to fix, of course. just have the memo/cache add ___ to every module id
[7:52pm] <kriskowal> have i ever mentioned that javascript is my *favorite* language
[7:53pm] <isaacs> hahah
[7:53pm] <ashb> isaacs> or __proto__ = null;
[7:53pm] <ashb> (on the cache object)
[7:53pm] <kriskowal> isaacs, would you mind writing up test cases for these?
[7:53pm] <isaacs> sure, i'll try to get to that today
[7:53pm] <kriskowal> in the commonjs/tests/modules/1.0?
[7:53pm] <isaacs> yeah
[7:53pm] <kriskowal> thanks.
[7:54pm] <isaacs> i'm also kinda itching to make node able to run those, or do you have a way to do that already?
[7:54pm] <kriskowal> i know exactly how to harden narwhal if those cases break, but i'd like to see whether it breaks first.
[7:54pm] <isaacs> suresure
[7:54pm] <kriskowal> i don't yet.
[7:54pm] <isaacs> ashb> but what if i then wanted to have a module named "__proto__"?
[7:55pm] <ashb> dont?
[7:55pm] <isaacs> hehe
[7:55pm] <kriskowal> i'm working on making node a narwhal engine. ultimately that means that it will run with narwhal's module loader.
[7:55pm] <isaacs> oh, actually, seems like require("constructor") won't break it, at least, not in v8
[7:55pm] <isaacs> i thot that was ReadOnly
[7:55pm] <ashb> very little is
[7:56pm] <ashb> constructor is an interesting case
[7:56pm] <ashb> should add it anywahy
[7:56pm] <kriskowal> so i'm not working toward the goal of making node's loader work, although i will likely adapt narwhal's sandbox module to take advantage of node's async facilities for require.async.
[7:56pm] <isaacs> kriskowal> it should be a minimal amount of glue code to make node work with your commonjs test suite
[7:56pm] <isaacs> seems pretty consistent
[7:57pm] <isaacs> it might involve dynamically adding to require.paths, but meh
[7:57pm] <kriskowal> yeah. i bet narwhal's lib/packages.js will work on node
[7:58pm] <ashb> isaacs> i just run it with some shell
[7:58pm] <kriskowal> well, it needs sync file api stuff
[7:58pm] <ashb> (on flusspferd)
[7:58pm] <isaacs> ah, i see
[7:58pm] <isaacs> so some of the tests just won't ever work on node.
[7:58pm] <ashb> look at just the compliance dir
[7:59pm] <ashb> oh wait no thats the old structue
[8:00pm] <ondras> kriskowal> I was also thinking about introducing a __FILE__ magic free variable
[8:00pm] <kriskowal> ondras, i think we hinted at "module.path" for that purpose, ondras
[8:01pm] <ondras> ah, ok
[8:01pm] <kriskowal> we've got "module.id" in the spec. ashb is using "module.uri"
[8:01pm] <kriskowal> narwhal's got "module.path"
[8:01pm] <ashb> there's module.uri (currently speced) which should be a file:// and module.resource hinted at for opening files relative to the module
[8:01pm] <ashb> uri is kinda of a pain to do anything with mid
[8:01pm] <ondras> this way or another, one can use this to implement your graphics processor's requires without the need for closured
[8:01pm] <ashb> mind
[8:02pm] <ondras> *closures
[8:02pm] <ondras> .)
[8:02pm] <ashb> kriskowal> module.uri is in Modules/1.1 btw
[8:02pm] <kriskowal> i don't see it
[8:02pm] <ashb> 3.2
[8:02pm] <ashb> http://wiki.commonjs.org/wiki/Modules/1.1
[8:02pm] <ondras> otoh, v8cgi is now equipped with reworked require() with correctly supports relative requires
[8:03pm] <kriskowal> ah, there it is
[8:03pm] <kriskowal> cool
[8:03pm] <kriskowal> you can also use the module.id and module.path to do your dynamic scope resolution
[8:03pm] <ondras> yes, as I said\
[8:03pm] <ondras> but that is of little interest now
[8:04pm] <ondras> this was a good day for my coding
[8:05pm] <kriskowal> just woke up myself. this weekend was good for code.
[8:05pm] <ondras> also, the magic system in my rpg was strongly improved today
[8:05pm] <ashb> does it have a story?
[8:06pm] <ondras> not much
[8:06pm] <ondras> so far, there is one quest and a bunch of maps
[8:06pm] <ondras> it is still more an engine than a game
[8:06pm] <ashb> cool
[8:07pm] <ondras> feel free to commit some more .)
[8:08pm] <ashb> seems unlikly
[8:08pm] <ashb> i'm busy writing a decent JS markdown parser
[8:09pm] <ashb> which 1) doesn't do MD direct to js, but stores a JsonML md tree first
[8:09pm] <ashb> and 2) should be easily pluggable for different dialects
[8:09pm] <ashb> since ther are like 700 of them
[8:13pm] <ashb> i so wish JS regexps had the /x flag
[8:18pm] <kriskowal> ashb you might consider forking my markdown package
[8:18pm] <kriskowal> http://github.com/kriskowal/markdown
[8:19pm] <ashb> ugh showdown
[8:19pm] <kriskowal> mine's a minimal straight port. if you improve it, i'll gladly revise the narwhal catalog to point to yours
[8:19pm] <ashb> oh i've not been pushing to github
[8:19pm] <ashb> lemme throw it in a quick paste
[8:20pm] <ashb> http://pastie.org/private/cmy4aehnlxotend0j8nfkg
[8:20pm] <kriskowal> nevertheless, seems useful.
[8:20pm] <ashb> tests are inline at the end
[8:20pm] <kriskowal> what's up with snake_case?
[8:20pm] <ashb> private
[8:20pm] <ashb> or protected
[8:21pm] <ashb> basically it splits it roughly into blocks
[8:22pm] <kriskowal> it never made sense to me to mangle those things on properties; they're every bit as public as anything else and likely to be used as the public api since nothing prevents it
[8:22pm] <ashb> then asks an ordered set of functions 'handle this if you can'
[8:22pm] <nrstott> snake_case is superior ;0
[8:22pm] <nrstott> wish JS devs would adopt i!
[8:22pm] <nrstott> it*
[8:22pm] <ashb> nrstott> ditto
[8:22pm] <nrstott> consider http_client....
[8:22pm] <nrstott> in camel youve got to do HTTPClient or HttpClient
[8:22pm] <nrstott> both of which look weird
[8:22pm] <ashb> kriskowal> i just use it as an indication that 'here be dragons, bring a sword'
[8:22pm] <kriskowal> or a hobbit to run faster than
[8:22pm] <ashb> yeah
[8:23pm] <ashb> once we've got the basic outline working we've got a huge test suite of different dialects from perl's Text::Markdown to make pass
[8:23pm] <nrstott> i really dislike the dash-case used in commonjs packages ;0 you can't make those into JS vars.
[8:23pm] <ashb> (we being myself and evilstreak)
[8:24pm] <kriskowal> excellent.
[8:24pm] <ashb> toTree outputs a JsonML parse tree, which is then fairly quick to turn into html
[8:25pm] <ashb> plus you can do other things with it
[8:25pm] <kriskowal> i went through a snake_case phase. at the end of the day, we can't change the javascript native types to use it, so they're just going to look inconsistent side-by-side.
[8:25pm] <ashb> direct md text -> html text seems silly now
[8:25pm] <ashb> sure you can. index_of = { return this.indexOf.appl(this, arguments); }
[8:25pm] <ashb>
[8:26pm] <kriskowal> if not silly, having a standard intermediate object graph would make pluggable parsers/formatters possible for inter-markup conversion.
[8:26pm] <ashb> so its just JsonML
[8:26pm] <ashb> with suitable node names
[8:26pm] <nrstott> kriskowal> that's true about the native types, unfortunately :(.
[8:26pm] <ashb> which could be quite easily changedc
[8:26pm] <kriskowal> sounds good to me.
[8:27pm] <kriskowal> alright, getting up and out to the office now. ttyl
[8:27pm] <ashb> kriskowal> re inter-markup. i plan on doing something like that actually
[8:27pm] <ashb> k. have fun
[8:27pm] <ashb> i plan to write a jsdoc parser for http://packag.es
[8:27pm] <ashb> (unless someone has written a commonjs version yet?)
[8:43pm] <nrstott> there's a jsdoc package that you can tusk install with narwhal
[8:43pm] <nrstott> don't know if it works outside of narwhal
[8:44pm] <ashb> i imagine it just packages up the js files but still dependso n rhino
[9:20pm] <inimino> ashb> so you're back to raw JavaScript and regexes?
[9:55pm] <ashb> inimino> yeah. it seemed better suitedto being pluggable/extendable
[9:55pm] <inimino> ok
[9:55pm] <ashb> might use a PEG for some bits still
[9:56pm] <inimino> alright
[9:56pm] <inimino> well, thanks for the bug reports
[9:56pm] <ashb> i have other projects where i know a PEG or some other parser generator is needed
[9:56pm] <ashb> so they'll be more coming
[9:57pm] <ashb> there'll
[9:57pm] <inimino> cool

 

 

Logs by date :