do we need a Module object instead of require() function?

144 views
Skip to first unread message

Patrick Mueller

unread,
Feb 3, 2009, 10:43:37 AM2/3/09
to serv...@googlegroups.com
I believe some issues regarding additional capabilities around modules have already been raised, like:

- should there be a "path" associated with the lookups of modules?  Where would this be specified?
- should there be a way to return a list of loaded modules?

Along with raising the issues, the thought seemed to be "let's put this off for now", and I agree with that sentiment (though I'm happy to start talking about it as well).

However ... if we are talking about additional capabilities here, perhaps we need to think about not having a single function called require() (or whatever), but an object which contains all the functionality.  Today, it would be an object that just had a property which is the function "require".

ie, you'd be using:

io = Module.require("js.io")

instead of

io = require("js.io")

More characters to type (bummer).  Though we could also define a global variable named "require" where the following was true:

require = Module.require

to fix the wordiness.

The idea here is that the object allows us to extend the functionality later, whereas if we don't, then to add more function we'd need to add MORE globals (require_path, get_modules_loaded(), etc), or we'd need to add more functions to the require function (shiver).

Patrick Mueller - http://muellerware.org/

Davey Waterson

unread,
Feb 3, 2009, 10:52:36 AM2/3/09
to serv...@googlegroups.com
it would be quite ironic to have the global namespace polluted with
the require method ;-)

Ondrej Zara

unread,
Feb 3, 2009, 11:07:34 AM2/3/09
to serv...@googlegroups.com
> it would be quite ironic to have the global namespace polluted with
> the require method ;-)
>

I am afraid that there is no other way - moreover, we will have
_every_ namespace polluted with require. The new contexts/objects in
which module files are executed should contain - if I understand this
principle correctly - exactly two items: "global" (reference to global
object) and "require" (so the module can include additional stuff).


Ondrej

Davey Waterson

unread,
Feb 3, 2009, 11:22:36 AM2/3/09
to serv...@googlegroups.com
wouldn't global.require suffice in the modules? I ask out of ignorance
of the scoping problems you guys are thinking about.

Ondrej Zara

unread,
Feb 3, 2009, 11:27:39 AM2/3/09
to serv...@googlegroups.com
> wouldn't global.require suffice in the modules? I ask out of ignorance
> of the scoping problems you guys are thinking about.
>

Hm, that would make sense.. but for the sake of consistency, one would
want to have also "global" property in global scope (circular
reference) so it is _always_ possible to use global.require,
independently on where is this called.

Wes Garland

unread,
Feb 3, 2009, 11:47:50 AM2/3/09
to serv...@googlegroups.com
Actually, mandating global.require pollutes the namespace with the name global, which is otherwise un-named.

Making the "require" be the only pollution to the global namespace is not a bad idea.

Recall, that if the symbol is visible in the global namespace, the only possible way to make it not visible from within a module is to purposefully collide it.

Wes
--
--
Wesley W. Garland
Director, Product Development
PageMail, Inc.
+1 613 542 2787 x 102

Ondrej Zara

unread,
Feb 3, 2009, 11:54:29 AM2/3/09
to serv...@googlegroups.com
> Recall, that if the symbol is visible in the global namespace, the only
> possible way to make it not visible from within a module is to purposefully
> collide it.
>

Hm, not sure:

1) if I execute the module in separate context, _nothing_ from global
namespace would be visible within a module;

2) if I use the helma(tm) way with __proto__ and __parent__, I believe
that again, nothing in global namespace would be visible from a
module.


Perhaps some GM guru can acknowledge my second statement?

O.

Tom Robinson

unread,
Feb 3, 2009, 12:11:02 PM2/3/09
to serv...@googlegroups.com
I don't think so, at the very least if you want to work with relative
paths. The require function needs to know what module it's being
called from in order to correctly resolve relative paths.

See my latest commit to my (temporary) "require" method used in Jack
(I was inspired by this discussion): http://github.com/tlrobinson/jack/commit/795b64e15789c893c1f45764d583e917ce3caddb

As you can see, I previously I used a stack of paths, pushing and
popping paths as I imported them, but this breaks down as soon as you
call require from a function called from another file.

I hope that made sense...

Ondrej Zara

unread,
Feb 3, 2009, 12:24:15 PM2/3/09
to serv...@googlegroups.com
>
> I don't think so, at the very least if you want to work with relative
> paths. The require function needs to know what module it's being
> called from in order to correctly resolve relative paths.
>

In v8cgi, I solve this by performing a chdir() every time "include" is
called. So, I move the execution to the directory which contains file
being loaded and this ensures relative paths work as expected.


What is your opinion?


O.

Wes Garland

unread,
Feb 3, 2009, 12:44:39 PM2/3/09
to serv...@googlegroups.com
On Tue, Feb 3, 2009 at 11:54 AM, Ondrej Zara <ondre...@gmail.com> wrote:

> Recall, that if the symbol is visible in the global namespace, the only
> possible way to make it not visible from within a module is to purposefully
> collide it.
>

Hm, not sure:

1) if I execute the module in separate context, _nothing_ from global
namespace would be visible within a module;

There is no such concept in spidermonkey or the ecmascript specification.  If you make this a specification requirement, you will make v8 an implementation requirement.

There is no cross-engine way to prevent name resolution from walking up the scope chian.

Wes

Peter Michaux

unread,
Feb 3, 2009, 12:54:11 PM2/3/09
to serv...@googlegroups.com
On Tue, Feb 3, 2009 at 7:43 AM, Patrick Mueller <pmu...@yahoo.com> wrote:

> you'd be using:
> io = Module.require("js.io")
> instead of
> io = require("js.io")

> The idea here is that the object allows us to extend the functionality


> later, whereas if we don't, then to add more function we'd need to add MORE
> globals

Not necessary. All "require" related functionality can by properties
of the "require" function *object*. That is a handy feature in
JavaScript that all functions are objects and can have properties.

> (require_path, get_modules_loaded(), etc), or we'd need to add more
> functions to the require function (shiver).

Why shiver?

require.loaded
require.path

Looks great to me.

Peter

Brian LeRoux

unread,
Feb 3, 2009, 12:56:11 PM2/3/09
to serv...@googlegroups.com
Yeah I like this encapsulation.

Davey Waterson

unread,
Feb 3, 2009, 1:21:10 PM2/3/09
to serv...@googlegroups.com
do all the platforms serverside have a noSuchMethod/MethodNotFound
equivalent, spidermonkey and rhino do, and I think webkit does (though
may be wrong on that)?

coz

var File = require.File(path_to_file_module);

would be neat and javascripty ;-)

in spidermoney the nosuchmethod handler would get called with 'File'
and 'path_to_file_module' as it's args.

Tom Robinson

unread,
Feb 3, 2009, 1:28:46 PM2/3/09
to serv...@googlegroups.com
On Feb 3, 2009, at 9:24 AM, Ondrej Zara wrote:

>
>>
>> I don't think so, at the very least if you want to work with relative
>> paths. The require function needs to know what module it's being
>> called from in order to correctly resolve relative paths.
>>
>
> In v8cgi, I solve this by performing a chdir() every time "include" is
> called. So, I move the execution to the directory which contains file
> being loaded and this ensures relative paths work as expected.
>
>
> What is your opinion?
>
>
> O.

I think it suffers from the same problem as my original stack-based
approach? For example:

main.js:

include("foo/bar.js");
bar();

lib/bar.js:

function bar() {
include("qwerty.js");
}

lib/qwerty.js:

throw "ok!"

I just executing main.js in v8cgi, and it failed to find "qwerty.js".
If you move 'include("qwerty.js")' to outside the function it will work.

This is the problem I had with the previous version of Jack's
"require", and I couldn't think of a way to fix it without some sort
of macro or exception throwing/stack trace craziness. But the new
solution seems to work great.

It wraps the code in a function, but if you don't want that extra
scope you could use a "with" statement instead.


(also, chdir-ing might cause issues with File and relative paths)


Anyway, regarding the "require" pollution, isn't the whole point of
this module system that you can workaround namespace conflicts? I have
no problem with declaring "require" to be a reserved identifier in
this system, along with "File", etc.

-Tom

Peter Michaux

unread,
Feb 3, 2009, 1:30:51 PM2/3/09
to serv...@googlegroups.com
On Tue, Feb 3, 2009 at 10:28 AM, Tom Robinson <tlrob...@gmail.com> wrote:

> Anyway, regarding the "require" pollution, isn't the whole point of
> this module system that you can workaround namespace conflicts? I have
> no problem with declaring "require" to be a reserved identifier in
> this system, along with "File", etc.

File does not need to be reserved in the same sense as require.
Require would always be present. File would only be present if the
File module is required.

Peter

Tom Robinson

unread,
Feb 3, 2009, 1:35:55 PM2/3/09
to serv...@googlegroups.com

I think File is a fundamental enough object that it should be
available by default, like XMLHttpRequest. This is how it is in Ruby,
Python, etc.

But we can save this debate for later...

-Tom

Peter Michaux

unread,
Feb 3, 2009, 1:39:45 PM2/3/09
to serv...@googlegroups.com

That would be a fine extension for a particular implementation. It
does not need to be standard, however.

Peter

Patrick Mueller

unread,
Feb 3, 2009, 3:01:05 PM2/3/09
to serv...@googlegroups.com

This is just another one of these 20th century biases I'm stuck with.
I don't have any problem at thinking about objects with properties
that happen to be functions, but there's always something just a
little odd about functions that have additional properties. NOT THAT
THERE'S ANYTHING WRONG WITH IT. Just, a little unexpected.

Davey Waterson

unread,
Feb 3, 2009, 3:14:12 PM2/3/09
to serv...@googlegroups.com
It's fluent javascript. just one of the idioms when everything is orthogonal.
Reply all
Reply to author
Forward
0 new messages