a module system (difficult to agree)

398 views
Skip to first unread message

Peter Michaux

unread,
Jan 29, 2009, 7:12:10 PM1/29/09
to serv...@googlegroups.com
From http://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/

> JavaScript needs a standard way to include other modules and for
> those modules to live in discreet namespaces. There are easy ways
> to do namespaces, but there's no standard programmatic way to load
> a module (once!). This is really important, because server side apps
> can include a lot of code and will likely mix and match parts that
> meet those standard interfaces.

An include/load/require system is the essential ingredient in
developing an extensible core interpreter. If a standard existed for
how modules load, then more code could be shared.

Unfortunately, people disagree about how this should be done. Some
like the shared global scope with a module in each child scope and/or
namespace is the way to go. I think this is unnecessarily complex and
that a single global scope like the browser has is the way to go and
anything more should come from the language first.

A large discussion about these issues was had on the Helma NG group
with three main participants. The lack of agreement on the module
system issue was a complete spoiler. I believe this is *the* major
issue to overcome.

Peter

Brian LeRoux

unread,
Jan 29, 2009, 7:20:37 PM1/29/09
to serv...@googlegroups.com
Agreed, and from there package management is going to be a lot easier.

I'm of the belief that continuing on the JavaScript tradition of being
a first class language of the web that loading into a global space
should be the default (as it is today) with the onus of good
namespacing being the domain of the library authors.

Lots of good places for inspiration out there...

http://code.google.com/apis/ajaxlibs/documentation/index.html
http://developer.yahoo.com/yui/examples/get/get-script-simple.html
http://developer.yahoo.com/yui/yuiloader/

Robin Berjon

unread,
Jan 29, 2009, 7:24:57 PM1/29/09
to serv...@googlegroups.com
On Jan 30, 2009, at 01:12 , Peter Michaux wrote:
> A large discussion about these issues was had on the Helma NG group
> with three main participants. The lack of agreement on the module
> system issue was a complete spoiler. I believe this is *the* major
> issue to overcome.

Do you have a pointer to it? That way we could read up beforehand and
avoid going through the same issues :)

--
Robin Berjon
Robineko (http://robineko.com/)

Peter Michaux

unread,
Jan 29, 2009, 7:34:07 PM1/29/09
to serverjs
On Jan 29, 4:20 pm, Brian LeRoux <brian.ler...@gmail.com> wrote:
>
> Agreed, and from there package management is going to be a lot easier.

I almost wrote the same thing. A package system (CPAN and apt
inspired) is the second thing I worked on for my server-side system. I
don't think a package distribution system has any issues that are as
"hot button" as the module loading issue has.

> I'm of the belief that continuing on the JavaScript tradition of being
> a first class language of the web that loading into a global space
> should be the default (as it is today) with the onus of good
> namespacing being the domain of the library authors.

I agree. It is the way the language is and we have already discovered
ways for how to deal with the problems of a global namespace.

Peter

Peter Michaux

unread,
Jan 29, 2009, 7:42:12 PM1/29/09
to serverjs
On Jan 29, 4:24 pm, Robin Berjon <robin.ber...@gmail.com> wrote:
> On Jan 30, 2009, at 01:12 , Peter Michaux wrote:
>
> > A large discussion about these issues was had on the Helma NG group
> > with three main participants. The lack of agreement on the module
> > system issue was a complete spoiler. I believe this is *the* major
> > issue to overcome.
>
> Do you have a pointer to it? That way we could read up beforehand and  
> avoid going through the same issues :)

It was a doozy spread across several threads.

http://groups.google.com/group/helma-ng/browse_frm/thread/79afcdef68a2aa55

http://groups.google.com/group/helma-ng/browse_frm/thread/6d002cb42a47ae42

Peter

Peter Svensson

unread,
Jan 30, 2009, 12:47:06 AM1/30/09
to serv...@googlegroups.com
Ow. I really don't agree :/ Having said that, I'll take a double helping of global namespace pollution gladly any day over not getting anywhere :)
In my experience (again, only either hopping on random code on disaster area projects or using Dojo) is that a short namespaced object hierarchy for different functions has the benefit of being very clear. Putting everything in global is a bit like having indexOf in the global namespace instead of on the String object.

Also, using namespaced object does the obvious; no collission of variable of function names, or the more probably mistaken one function for another with a similar sounding name.

I'd rather see;

ssjs.file.open()
ssjs.foo.openup()

than

open()
openup()

Cheers,
PS

http://unclescript.blogspot.com

Peter Michaux

unread,
Jan 30, 2009, 2:12:35 AM1/30/09
to serv...@googlegroups.com
On Thu, Jan 29, 2009 at 9:47 PM, Peter Svensson <psve...@gmail.com> wrote:
> Ow. I really don't agree :/ Having said that, I'll take a double helping of
> global namespace pollution gladly any day over not getting anywhere :)
> In my experience (again, only either hopping on random code on disaster area
> projects or using Dojo) is that a short namespaced object hierarchy for
> different functions has the benefit of being very clear. Putting everything
> in global is a bit like having indexOf in the global namespace instead of on
> the String object.
>
> Also, using namespaced object does the obvious; no collission of variable of
> function names, or the more probably mistaken one function for another with
> a similar sounding name.
>
> I'd rather see;
>
> ssjs.file.open()
> ssjs.foo.openup()
>
> than
>
> open()
> openup()

This is not the difference folks usually mean when they talk about
namespaces and module loading systems. What you are showing is
simulating namespaces by using an object hierarchy in a global
namespace system. It works in the browser and would work fine in a
server-side system with a global namespace. I'm in favor of this type
of system (though see ssjs_file_open as better than ssjs.file.open in
several ways). These types of namespacing strategies are based on
convention.

When folks talk about "real" namespaces they are usually meaning
systems where code from one namespace has a limited, controlled
channel of interaction with objects from another namespace. There is
language or host support to assist or support the idea of namespaces.
From what I've seen on the ECMAScript mailing list, this sort of
system has been proposed and rejected (at least for now) from
ECMAScript.

Peter

Peter Svensson

unread,
Jan 30, 2009, 3:01:20 AM1/30/09
to serv...@googlegroups.com
Then I stand happily corrected :)
Though, concatenating the names in a simulated object hierarchy give nothing of the benefits of having an actual hierarchy and you're still using one, so ..

Cheers,
PS

Tom Robinson

unread,
Jan 30, 2009, 6:17:01 AM1/30/09
to serverjs
You mention "open()" and "ssjs.file.open()" as possibilities, but you
left out my preference: "file.open()". I think it's perfectly
reasonable to have a few standard objects in the global scope, like
"File", "Socket", "require", etc.

Here's why:

1) While I do think *libraries* of code should be "namespaced", I
don't think that's necessary for what we're trying to do here. In the
browser XMLHttpRequest is a top level object. I'd say this project is
more like adding XMLHttpRequest to JavaScript than writing a library.

2) It's essentially what Ruby, Python, and many other languages do.
You usually don't see things like "Ruby.File.open()".

If we want this to be a standard (de facto or otherwise) we have to
act like it's a standard. Using "ssjs.File" sends the message that
it's not *really* the standard, it's just part of this "ssjs" thing
(also, I think ssjs is a misleading name, since you'll be able to use
it for things other than servers)

3) Some command line JS interpreters already come with a File object,
but they all vary slightly in how they work. Hopefully this project
will standardize them, not augment them. Having "File" and "ssjs.File"
is just confusing.

4) If you force all 3rd party libraries loaded through the package
system to also be part of this "ssjs" namespace, you're not fixing the
collision problem, you're just moving it down one layer.

5) Accessing "ssjs.File" is slightly slower than "File". Probably not
a big deal though.

That's my 2¢

-Tom

On Jan 29, 9:47 pm, Peter Svensson <psvens...@gmail.com> wrote:
> Ow. I really don't agree :/ Having said that, I'll take a double helping of
> global namespace pollution gladly any day over not getting anywhere :)
> In my experience (again, only either hopping on random code on disaster area
> projects or using Dojo) is that a short namespaced object hierarchy for
> different functions has the benefit of being very clear. Putting everything
> in global is a bit like having indexOf in the global namespace instead of on
> the String object.
>
> Also, using namespaced object does the obvious; no collission of variable of
> function names, or the more probably mistaken one function for another with
> a similar sounding name.
>
> I'd rather see;
>
> ssjs.file.open()
> ssjs.foo.openup()
>
> than
>
> open()
> openup()
>
> Cheers,
> PS
>
> http://unclescript.blogspot.com
>

Peter Svensson

unread,
Jan 30, 2009, 6:22:04 AM1/30/09
to serv...@googlegroups.com
Thanks for giving me another angle to see this from, Tom.

I agree with you that if this is going to be _the_ standard Server-Side JavaScript definition, then having an extra level of namespace is of no real use. I think I was mainly trying to emphasize the use of namespacing objects in general, instead of concatenated function names as namespace.

Cheers,
PS

Stuart Langridge

unread,
Jan 30, 2009, 6:48:46 AM1/30/09
to serv...@googlegroups.com
> 2) It's essentially what Ruby, Python, and many other languages do.
> You usually don't see things like "Ruby.File.open()".

> 3) Some command line JS interpreters already come with a File object,


> but they all vary slightly in how they work. Hopefully this project
> will standardize them, not augment them. Having "File" and "ssjs.File"
> is just confusing.

I don't agree there. Python does that because there's only one Python
interpreter. (Well, there are others, but they're explicitly
compatible with CPython.) We have multiple incompatible interpreters.
If there's going to be a global File object then we either wait for
all the interpreters to implement it, or we implement it ourselves as
a wrapper on top of whichever interpreter you're on. As you say, some
interpreters already come with a File object, but the whole point of
standardising an API, to my mind, is to make sure you can write SSJS
to one API and not many. If you're using ssjs.File then you *know*
that it's the standard file object. If you're using File, then you
don't know whether it's the SSJS file object or the interpreter's file
object. Worse, if we override an existing global File with our global
File then anyone who *wants* to make their project
interpreter-dependent is out of luck, because we've overridden the
interpreter's API.

> 4) If you force all 3rd party libraries loaded through the package
> system to also be part of this "ssjs" namespace, you're not fixing the
> collision problem, you're just moving it down one layer.

I don't think that's a good idea (it's certainly not what I'm
proposing). SSJS would be the anointed, simple, API that does the
basics. Other libraries can depend on it if they want to, but I don't
think that they're part of it.

sil

Miguel Coquet

unread,
Jan 30, 2009, 7:33:54 AM1/30/09
to serv...@googlegroups.com
I must say, I'm personally for the top level objects in global. An
ssjs.* object would "smell" too much like a library or framework.

This being a spec, means that whoever wants a compatible interpreter
will have to implement it to be so, or just stay incompatible, making
the overriding problem a non-issue. Patches can be submitted for the
different opensource projectes and the closedsource world will just
have to make do.

The need for a standard is exactly so people can follow it and not the
other way around.


Cheers

Miguel

Thomas Robinson

unread,
Jan 30, 2009, 8:11:50 AM1/30/09
to serv...@googlegroups.com
I think the concept of wrapping a bunch of existing incompatible APIs
in a library is a necessary evil of the browser world, which we should
try to avoid on the server, because we can.

Many of the things we're planning on doing will require modifying the
command line shells themselves. In the process I don't have any qualms
about replacing an old File object API with the new standard one.

But now that I think about it, none of the standard shells actually
come with a File object. So neither of our arguments on that one are
valid ;)

- Rhino has java.io.File, of course. No namespace conflict there though.
- SpiderMonkey/TraceMonkey has one that's not included in normal
distributions, and they don't sound very enthusiastic about it: https://developer.mozilla.org/En/SpiderMonkey/File_object
- V8 doesn't have one (lv8call and v8cgi implement incompatible ones)
- JavaScriptCore doesn't have one.

Those are the "big four" in my mind. What others are there that we
want to support?

-tom

Robin Berjon

unread,
Jan 30, 2009, 8:11:33 AM1/30/09
to serv...@googlegroups.com
On Jan 30, 2009, at 12:48 , Stuart Langridge wrote:
>> 3) Some command line JS interpreters already come with a File object,
>> but they all vary slightly in how they work. Hopefully this project
>> will standardize them, not augment them. Having "File" and
>> "ssjs.File"
>> is just confusing.
>
> I don't agree there. Python does that because there's only one Python
> interpreter. (Well, there are others, but they're explicitly
> compatible with CPython.) We have multiple incompatible interpreters.
> If there's going to be a global File object then we either wait for
> all the interpreters to implement it, or we implement it ourselves as
> a wrapper on top of whichever interpreter you're on. As you say, some
> interpreters already come with a File object, but the whole point of
> standardising an API, to my mind, is to make sure you can write SSJS
> to one API and not many. If you're using ssjs.File then you *know*
> that it's the standard file object. If you're using File, then you
> don't know whether it's the SSJS file object or the interpreter's file
> object. Worse, if we override an existing global File with our global
> File then anyone who *wants* to make their project
> interpreter-dependent is out of luck, because we've overridden the
> interpreter's API.

Your argument relies entirely on clashes with identically named
objects in existing interpreters. I agree that that can be a problem —
if, say, you redefine File.open() then anything that already relies on
it in that implementation might break — but disagree that stuffing
everything into a subnamespace is necessarily the solution: we can
simply pick names that don't clash with the implementations that we're
targeting.

Ondrej Zara

unread,
Jan 30, 2009, 8:18:34 AM1/30/09
to serv...@googlegroups.com
My two cents: JavaScript already comes with the concept of
global-level "class" names (Object, Array, Date, ..) and people (we!)
are well used to this. The whole "encapsulate-or-die" stuff is the
result of mixing client libraries, something we want (and can) evade.

So, I strongly opt for [global].File() instead of ssjs.File().

Ondrej

Hannes Wallnoefer

unread,
Jan 30, 2009, 8:48:48 AM1/30/09
to serverjs
I think you're aiming too high by trying to get people agree on
namespaces at this time. IMO, what we should do now is talk about what
basic API should be provided - what classes and objects are available,
and what they do. I think namespaces are the last thing we need to
worry about, and in JavaScript it's just one line to turn a foo.File
into a File.

With Helma NG, you have full control how you want to access your
modules. import('helma.file') will put the module into a helma.file
namespace, while include('helma.file') will set up the File
constructor (generally all exported symbols) directly in your local
scope, and you can do var file = require('helma.file') to take control
of the namespace yourself. I personally wouldn't want to live without
this, just like no Python person in one's right mind would trade
python's module system for something less flexible.

Talking about File APIs, the helma.file module is built on top of
java.io.File:
http://github.com/hns/helma-ng/blob/89a30cf8b6f83e8f180a6d87d45d30f57fdeefde/modules/helma/file.js
It has a few nice extras, like recursive copying of directories and
iterating through the lines of a file. For example, the following line
prints all lines of file README.txt prefixed with '>':

helma> include('helma.file');
helma> for (var line in new File('README.txt')) print(line);

I think it's things like this that are worth being considered as
standards or pseudo-standards.

Hannes

pmuellr

unread,
Jan 30, 2009, 8:53:21 AM1/30/09
to serverjs
Shoving everything into the global namespace doesn't scale well,
especially when it comes to users wanting to build their own libraries/
frameworks. This was the story in Smalltalk, back in the day. We use
to have to prefix all our classes with product specific strings to
keep some amount of order (AbtXxxYyy, anyone?). PHP, today, does the
same thing, see the Zend framework for their naming scheme:

http://framework.zend.com/manual/en/

If you have to end up with prefixes anyway, they might as well be
first-class objects (in the "ssjs" sense) as opposed to prepended
strings in your function/class names. Objects == good.

As I hope some of the good stuff coming out of this effort might rub-
off on our JavaScript environments in browsers, I'm not terribly keen
on "ssjs" as the prefix though. "js"? "std"?

Peter Svensson

unread,
Jan 30, 2009, 8:53:46 AM1/30/09
to serv...@googlegroups.com
OK. Let's shelve the namespaces for now and focus on features :)

Cheers,
PS

nlloyds

unread,
Jan 30, 2009, 9:29:53 AM1/30/09
to serverjs

Tom,

On Jan 30, 7:11 am, Thomas Robinson <tlrobin...@gmail.com> wrote:
> - Rhino has java.io.File, of course. No namespace conflict there though.
> - SpiderMonkey/TraceMonkey has one that's not included in normal  
> distributions, and they don't sound very enthusiastic about it:https://developer.mozilla.org/En/SpiderMonkey/File_object
> - V8 doesn't have one (lv8call and v8cgi implement incompatible ones)
> - JavaScriptCore doesn't have one.
>
> Those are the "big four" in my mind. What others are there that we  
> want to support?

On ASP and other Windows-based JS implementations, COM/ActiveX objects
are used, so on Windows servers there is Scripting.FileSystemObject
(http://www.w3schools.com/asp/asp_ref_filesystem.asp)

For environments that don't include a *real* file API, it's easy to
build a layer on top of the ActiveXObject access. That's what I've
been doing internally for a while, and it will be nice to have an
*official* file API to follow rather than taking random inspiration
from different sources.

Thanks,

Nathan

Robin Berjon

unread,
Jan 30, 2009, 9:52:57 AM1/30/09
to serv...@googlegroups.com
On Jan 30, 2009, at 14:53 , pmuellr wrote:
> Shoving everything into the global namespace doesn't scale well,
> especially when it comes to users wanting to build their own
> libraries/
> frameworks.

Those are two separate issues. The standard stuff defines a (limited)
number of objects in the global namespace (e.g. File) and then
extensions do whatever they want, except that good practice is
documented telling people not to pollute the global namespace. That's
how CPAN works, and overall it works really well.

Peter Michaux

unread,
Jan 30, 2009, 10:03:18 AM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 5:11 AM, Thomas Robinson <tlrob...@gmail.com> wrote:
>
> I think the concept of wrapping a bunch of existing incompatible APIs
> in a library is a necessary evil of the browser world, which we should
> try to avoid on the server, because we can.

Since this group is essentially a specification group, that is just a
matter of specifying only one API.

> Many of the things we're planning on doing will require modifying the
> command line shells themselves. In the process I don't have any qualms
> about replacing an old File object API with the new standard one.
>
> But now that I think about it, none of the standard shells actually
> come with a File object. So neither of our arguments on that one are
> valid ;)

Command shells are applications (just like browsers are) where the
application has a JavaScript interpreter embedded inside the
application.

> - Rhino has java.io.File, of course. No namespace conflict there though.
> - SpiderMonkey/TraceMonkey has one that's not included in normal
> distributions, and they don't sound very enthusiastic about it: https://developer.mozilla.org/En/SpiderMonkey/File_object
> - V8 doesn't have one (lv8call and v8cgi implement incompatible ones)
> - JavaScriptCore doesn't have one.

It is the host application's job to expose access to things
appropriate to the particular scripting environment. A server-side
interpreter can expose a File object. A browser interpreter should
not. So it is good that SpiderMonkey and V8 don't expose File as a
standard host object.

> Those are the "big four" in my mind. What others are there that we
> want to support?

This discussion group won't support JavaScript implementations. Host
applications will choose to support the results of this discussion
group by adding host objects and only if a particular host application
finds doing so worthwhile and beneficial.

Peter

Peter Michaux

unread,
Jan 30, 2009, 10:09:17 AM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 6:52 AM, Robin Berjon <robin....@gmail.com> wrote:
>
> On Jan 30, 2009, at 14:53 , pmuellr wrote:
>> Shoving everything into the global namespace doesn't scale well,
>> especially when it comes to users wanting to build their own
>> libraries/
>> frameworks.
>
> Those are two separate issues. The standard stuff defines a (limited)
> number of objects in the global namespace (e.g. File) and then
> extensions

Although a standard File API would be great, the actual File
implementation can be as an extension itself. The only thing that
needs to be added to the JavaScript interpreter is something like
"load" to execute other files of code. One of those files of code
could contain a File object.

> do whatever they want, except that good practice is
> documented telling people not to pollute the global namespace. That's
> how CPAN works, and overall it works really well.

I agree. A library author should not be forced into a straight jacket.
He should be shown how to put on the straight jacket himself. I think
most JavaScript programmers realize a library global function called
"trim" has a good chance of namespace collision and would like to
avoid that.

Peter

Robert Schultz

unread,
Jan 30, 2009, 10:18:07 AM1/30/09
to serverjs
It could behave something like this:

import("File")
Import the standard File object directly into the global namespace. So
now you can do
var f = new File("some.txt");
var lines = f.readLines();
or
var lines = File.readLines("some.txt");

Maybe import could have an optional second argument, which object to
insert into:
var myObj = {};
import("File", myObj)
var f = new myObj.File("some.txt");
var lines = f.readLines();
or
var lines = myObj.File.readLines("some.txt");

This way those that are ok with polluting the global namespace for
efficiency sake can just import away.
Those that want things all in a single object like SSJS or something
can do that.

The question then becomes where does import live?
Does it sit in the global object, do we have a tiny few number of
these?
Maybe a command line switch to optionally have import and other
similar functions be put into a new SSJS object in global rather than
directly in global. Again, giving pollution control to those that want
it.

It's trivial to implement both (well it is for v8 and for
spidermonkey, dunno on the other interpreters) and seems ok to me to
implement both.

Peter Michaux

unread,
Jan 30, 2009, 10:20:37 AM1/30/09
to serv...@googlegroups.com

I mostly agree and would like to agree completely.

I think that CPAN offers a good example to follow. Because CPAN is the
canonical repository, code in CPAN can define a global like "File".
The CPAN maintainers approve new namespaces to avoid collision. If
everyone else in the Perl world uses a prefix containing who they are
then that will never collide with CPAN naming because CPAN naming
doesn't contain any information about who is writing the code. So a
company called XYZ would write an XYZ::File module and that would
likely never collide with any CPAN module because "XYZ" is a company
name and likely not appropriate for a CPAN module. There is still some
risk.

Java takes this to what might be considered an extreme by using
reverse domain names. That same company's class would be com.xyz.File
and this naming convention almost ensures no collisions as domains are
registered with a central service.

For a standardized JavaScript file object, if the desired semantics
are a global file object then it is a matter of choosing a string for
that object's identifier. Choosing "File" would work. Choosing
"std_File" would work. Even "asdf" would work. Some of these are
better than others but they all have the same semantics.

Peter

Thomas Robinson

unread,
Jan 30, 2009, 10:23:50 AM1/30/09
to serv...@googlegroups.com

On Jan 30, 2009, at 7:03 AM, Peter Michaux wrote:

>
> On Fri, Jan 30, 2009 at 5:11 AM, Thomas Robinson
> <tlrob...@gmail.com> wrote:
>>
>> I think the concept of wrapping a bunch of existing incompatible APIs
>> in a library is a necessary evil of the browser world, which we
>> should
>> try to avoid on the server, because we can.
>
> Since this group is essentially a specification group, that is just a
> matter of specifying only one API.
>
>> Many of the things we're planning on doing will require modifying the
>> command line shells themselves. In the process I don't have any
>> qualms
>> about replacing an old File object API with the new standard one.
>>
>> But now that I think about it, none of the standard shells actually
>> come with a File object. So neither of our arguments on that one are
>> valid ;)
>
> Command shells are applications (just like browsers are) where the
> application has a JavaScript interpreter embedded inside the
> application.

Yes, but the interpreter doesn't implement the File object, otherwise
we would all have File objects in the browser. The shell, or some
library included by the shell, implements it.

>
>> - Rhino has java.io.File, of course. No namespace conflict there
>> though.
>> - SpiderMonkey/TraceMonkey has one that's not included in normal
>> distributions, and they don't sound very enthusiastic about it: https://developer.mozilla.org/En/SpiderMonkey/File_object
>> - V8 doesn't have one (lv8call and v8cgi implement incompatible ones)
>> - JavaScriptCore doesn't have one.
>
> It is the host application's job to expose access to things
> appropriate to the particular scripting environment. A server-side
> interpreter can expose a File object. A browser interpreter should
> not. So it is good that SpiderMonkey and V8 don't expose File as a
> standard host object.
>
>> Those are the "big four" in my mind. What others are there that we
>> want to support?
>
> This discussion group won't support JavaScript implementations. Host
> applications will choose to support the results of this discussion
> group by adding host objects and only if a particular host application
> finds doing so worthwhile and beneficial.

That's ideally how it would work, but I suspect if we just release a
spec and hope for the JS engine developers to implement it themselves
it will take years. I think we'll need to actively develop at least
one "reference implementation" of the spec.

But if there are JS engine contributors here who plan to support this
project, it would be nice to hear that :)

I saw Norris Boyd (creator of Rhino) is on the list, but I don't know
if he or anyone from the Rhino project plans to actively implement
this stuff.

Peter Michaux

unread,
Jan 30, 2009, 10:33:15 AM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 5:48 AM, Hannes Wallnoefer <han...@gmail.com> wrote:

> With Helma NG, you have full control how you want to access your
> modules. import('helma.file') will put the module into a helma.file
> namespace,

Does that mean global.helma.file will access the file object from any
code (previously loaded or loaded later)?

What is the general structure of the helma.file code? Something like this

var helma = helma || {};
helma.file = function() {
// ...
}
//... helma.file and helma.file.prototype properties


> while include('helma.file') will set up the File
> constructor (generally all exported symbols) directly in your local
> scope, and you can do var file = require('helma.file') to take control
> of the namespace yourself.

> I personally wouldn't want to live without
> this, just like no Python person in one's right mind would trade
> python's module system for something less flexible.

I'm not sure anything conclusion can be drawn from this statement.
Presumably a Python person choose Python because he likes how Python
works. That implies he wouldn't want to change how Python works.

Peter

Robin Berjon

unread,
Jan 30, 2009, 11:02:31 AM1/30/09
to serv...@googlegroups.com
On Jan 30, 2009, at 16:20 , Peter Michaux wrote:
> I think that CPAN offers a good example to follow. Because CPAN is the
> canonical repository, code in CPAN can define a global like "File".
> The CPAN maintainers approve new namespaces to avoid collision.

To be precise, that's not actually the case. PAUSE users (PAUSE is the
name of the system to upload to the CPAN) can upload modules that
contain namespaces *so long as those namespaces are not already in
existence*. Basically, it's a first-come-first-serve system. If the
name already exists, then you need maintainer or co-maintainer status
on that namespace to upload (the status can be granted to you by
whoever owns it). There is an approved list of modules (the registered
modules) that CPAN admins maintain but that's largely fallen into
disuse because the first-come-first-serve approach (perhaps
surprisingly) works very well on its own.

Patrick Mueller

unread,
Jan 30, 2009, 11:08:04 AM1/30/09
to serv...@googlegroups.com
On Jan 30, 2009, at 10:18 AM, Robert Schultz wrote:

>
> It could behave something like this:
>
> import("File")
> Import the standard File object directly into the global namespace. So
> now you can do
> var f = new File("some.txt");
> var lines = f.readLines();
> or
> var lines = File.readLines("some.txt");
>
> Maybe import could have an optional second argument, which object to
> insert into:
> var myObj = {};
> import("File", myObj)
> var f = new myObj.File("some.txt");
> var lines = f.readLines();
> or
> var lines = myObj.File.readLines("some.txt");

In my playing with "modules" in JS, what I've done is had the import()
function return a "module" object which had properties that the module
exported. So the code might look something like this:

var IO = import("io.jsm")
var f = new IO.File("some.txt")
...

In this case, there's an "io" module, which exports a class named
"File". What's interesting about this is the "global naming" problem
goes away, kind of. The only global names are the module names
(presumably uri's of some kind). Within each module, the namespace is
managed by the module.

Patrick Mueller
http://muellerware.org/

Robin Berjon

unread,
Jan 30, 2009, 11:09:21 AM1/30/09
to serv...@googlegroups.com
On Jan 30, 2009, at 16:18 , Robert Schultz wrote:
> The question then becomes where does import live?
> Does it sit in the global object, do we have a tiny few number of
> these?
> Maybe a command line switch to optionally have import and other
> similar functions be put into a new SSJS object in global rather than
> directly in global. Again, giving pollution control to those that want
> it.

You really don't want that. Libraries want to work everywhere
irrespective of the environment, so the second you introduce that
option, every library that needs to import something will do if
(import) import(Foo) else SSJS.import(Foo). Or if SSJS is always
present, then people will just use that, making the option useless. It
becomes a mess :)

Introducing a small, controlled number of globals is fine. You might
not want to make actual functions global but rather objects so that
new functionality can go on said objects rather than in the global
namespace. Random example: if in v2 we want to have unimport()
(matching Perl's "no" keyword) we're better off with Module.import()/
Module.unimport() than with adding unimport() globally.

Robert Koberg

unread,
Jan 30, 2009, 11:09:27 AM1/30/09
to serv...@googlegroups.com
>>
>>> Many of the things we're planning on doing will require modifying
>>> the
>>> command line shells themselves. In the process I don't have any
>>> qualms
>>> about replacing an old File object API with the new standard one.
>>>
>>> But now that I think about it, none of the standard shells actually
>>> come with a File object. So neither of our arguments on that one are
>>> valid ;)
>>
>> Command shells are applications (just like browsers are) where the
>> application has a JavaScript interpreter embedded inside the
>> application.
>
> Yes, but the interpreter doesn't implement the File object, otherwise
> we would all have File objects in the browser. The shell, or some
> library included by the shell, implements it.

It would really be nice to get away from a 'File' object (which, to
me, means a filesystem directory or file) and go to Collection and
Resource (or Document or Doc). Then it would be up to the implementor
to abstract away and/or mix a filesystem, a json DB (at least like
mongodb as couchdb doesn't have collections... don't know much about
perservere), an XML db or a relation db.

I also think a RESTful perspective would be very useful in dealing
with Collections and Resources.

best,
-Rob

Hannes Wallnoefer

unread,
Jan 30, 2009, 11:21:34 AM1/30/09
to serverjs
On Jan 30, 4:33 pm, Peter Michaux <petermich...@gmail.com> wrote:
> On Fri, Jan 30, 2009 at 5:48 AM, Hannes Wallnoefer <hann...@gmail.com> wrote:
> > With Helma NG, you have full control how you want to access your
> > modules. import('helma.file') will put the module into a helma.file
> > namespace,
>
> Does that mean global.helma.file will access the file object from any
> code (previously loaded or loaded later)?

Nope, because a loaded module is only available to the module (scope)
that loaded it. There's no reference in the shared global scope,
unless you explicitly set it. But loaded modules are shared on a per
request basis, so two different modules loading the same other module
within one request will get the same object back, regardless of what
name they use for it locally.

If this sounds confusing just think of Python. Helma NG is really
JavaScript with pythonic modules and scopes.

> What is the general structure of the helma.file code? Something like this
>
> var helma = helma || {};
> helma.file = function() {
>  // ...}
>
> //... helma.file and helma.file.prototype properties
>
> > while include('helma.file') will set up the File
> > constructor (generally all exported symbols) directly in your local
> > scope, and you can do var file = require('helma.file') to take control
> > of the namespace yourself.
> > I personally wouldn't want to live without
> > this, just like no Python person in one's right mind would trade
> > python's module system for something less flexible.
>
> I'm not sure anything conclusion can be drawn from this statement.
> Presumably a Python person choose Python because he likes how Python
> works. That implies he wouldn't want to change how Python works.

I was just trying to express my dislike for module-less, raw
JavaScript. But I've stopped evangelizing our approach, I'm not good
at it and it seems people have become to used to the way things
are :-)

Hannes

> Peter

Kevin Dangoor

unread,
Jan 30, 2009, 11:44:00 AM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 11:21 AM, Hannes Wallnoefer <han...@gmail.com> wrote:
> I was just trying to express my dislike for module-less, raw
> JavaScript. But I've stopped evangelizing our approach, I'm not good
> at it and it seems people have become to used to the way things
> are :-)

I like Python's system of modules very much as well...

But, I'd like to make a suggestion that may help this thread from
continuing endlessly. I think that's especially important because
*everything* will be built on how modules work.

My suggestion is that people who are interested or already have useful
APIs for this or whatever, create a new page under ServerJS/Modules/
quickly describing the approach (basically a few examples of file
layout and inclusion of modules). If you've already got some docs, you
can copy and paste that in or something. And then add a link under
"Proposed API" here:

https://developer.mozilla.org/ServerJS/Modules

It's hard to have productive conversations about APIs without code to
look at. Once there's a somewhat complete picture, it's much easier to
spot and discuss strengths and weaknesses.

Kevin

--
Kevin Dangoor

email: k...@blazingthings.com
blog: http://www.BlueSkyOnMars.com

mvalente

unread,
Jan 30, 2009, 11:48:54 AM1/30/09
to serverjs

On Jan 30, 11:17 am, Tom Robinson <tlrobin...@gmail.com> wrote:
> You mention "open()" and "ssjs.file.open()" as possibilities, but you
> left out my preference: "file.open()". I think it's perfectly
> reasonable to have a few standard objects in the global scope, like
> "File", "Socket", "require", etc.
>

> 2) It's essentially what Ruby, Python, and many other languages do.
> You usually don't see things like "Ruby.File.open()".
>

> 3) Some command line JS interpreters already come with a File object,
> but they all vary slightly in how they work. Hopefully this project
> will standardize them, not augment them. Having "File" and "ssjs.File"
> is just confusing.
>

YES! YES!... :-)

-- MV

Ross Boucher

unread,
Jan 30, 2009, 1:20:13 PM1/30/09
to serv...@googlegroups.com
Completely agree Robin. Generally, adding a billion options is the
absolute wrong approach and a nightmare to support down the line.

The simplest approach here is probably the best, and I prefer having a
File object with methods like open, close, etc..

I'd also mention that it sounds like some of the proposals would
require you to write files which would be imported in a certain way.
Maybe I'm just misunderstanding, but I think that's definitely
something that needs to be avoided.

I should be able to import any file containing valid javascript and
have it be available to me just as if I had included it with a
<script> tag in the browser.

Peter Michaux

unread,
Jan 30, 2009, 2:12:31 PM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 10:20 AM, Ross Boucher <rbou...@gmail.com> wrote:

> I'd also mention that it sounds like some of the proposals would
> require you to write files which would be imported in a certain way.

This is why the module system is such an important issue.

> Maybe I'm just misunderstanding, but I think that's definitely
> something that needs to be avoided.

In some sense, it cannot really be avoided. Any choice on script
loading mechanism will impact the way scripts are written.

> I should be able to import any file containing valid javascript and
> have it be available to me just as if I had included it with a
> <script> tag in the browser.

I agree for the simple reasons that it is how things work in the
browser and people already know how that works in JavaScript. By
writing files essentially the same way they are written for the
browser, it means server-side code can easily be shared with the
browser.

Peter

Ross Boucher

unread,
Jan 30, 2009, 2:28:13 PM1/30/09
to serv...@googlegroups.com

On Jan 30, 2009, at 11:12 AM, Peter Michaux wrote:

> In some sense, it cannot really be avoided. Any choice on script
> loading mechanism will impact the way scripts are written.
>
>> I should be able to import any file containing valid javascript and
>> have it be available to me just as if I had included it with a
>> <script> tag in the browser.
>
> I agree for the simple reasons that it is how things work in the
> browser and people already know how that works in JavaScript. By
> writing files essentially the same way they are written for the
> browser, it means server-side code can easily be shared with the
> browser.

Maybe we just disagree on terminology here. But I agree, you should be
writing javascript files exactly the same way you already do for the
browser. This is what I meant by not requiring a specific syntax for
allowing import of a file.

The fact that JavaScript left out this feature is unfortunate, but
there are already plenty existing implementations out there in the
wild. Dojo has one, Objective-J has one, Jack has one, and they all
work differently.

It would probably be a good idea to survey what people are doing, and
either just pick an existing implementation or create a new compromise
solution that makes everyone reasonably happy.

Peter Svensson

unread,
Jan 30, 2009, 2:49:05 PM1/30/09
to serv...@googlegroups.com
This will would obviously be the first task for the modularization group.

Cheers,
PS

Patrick Mueller

unread,
Jan 30, 2009, 3:32:26 PM1/30/09
to serv...@googlegroups.com
On Jan 30, 2009, at 2:28 PM, Ross Boucher wrote:

> Maybe we just disagree on terminology here. But I agree, you should be
> writing javascript files exactly the same way you already do for the
> browser. This is what I meant by not requiring a specific syntax for
> allowing import of a file.

The problem is, "the way you do for the browser" means you have to
write assuming your code gets run in the "global context". Some of
the module stories have a different way of working, like loading your
code into a new context. It sounded like one already mentioned here
(Helma?) supports BOTH. You can include() a resource, which is just
like <script src=""> (or #include in C) but they also had an import()
which was more like a Python import. Actually, supporting both would
be nice, include() for pre-existing stuff, or those times when you
really do want stuff imported into the global namespace, and import()
for libraries where you'd like to take advantage of the new context.
The problem is, you probably need to know which one to use for a
particular module, and using the wrong one is going to give you
surprises.

> The fact that JavaScript left out this feature is unfortunate, but
> there are already plenty existing implementations out there in the
> wild. Dojo has one, Objective-J has one, Jack has one, and they all
> work differently.

I'd say it's a blessing, to some extent. It doesn't need to be added
to the language (if that's the suggestion), since it can be added as
new function. Letting folks experiment with different ways of doing
this. Same is true for people who want to add "classical OO" type
capabilities - you can do it via functions, without having to have new
language constructs, though the resulting function invocation may look
a bit messier. This, BTW, is the same approach Smalltalk took - there
are no "language level" features to define classes, defining classes
is done via message sends.

Patrick Mueller
http://muellerware.org/

Peter Michaux

unread,
Jan 30, 2009, 3:34:29 PM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 8:44 AM, Kevin Dangoor <dan...@gmail.com> wrote:

> My suggestion is that people who are interested or already have useful
> APIs for this or whatever, create a new page under ServerJS/Modules/
> quickly describing the approach (basically a few examples of file
> layout and inclusion of modules). If you've already got some docs, you
> can copy and paste that in or something. And then add a link under
> "Proposed API" here:
>
> https://developer.mozilla.org/ServerJS/Modules

Two ideas posted.

Peter

Peter Michaux

unread,
Jan 30, 2009, 3:41:52 PM1/30/09
to serv...@googlegroups.com

Writing a send function

send(obj, "message", arg0, arg1);

or making objects functions of their messages

obj("message", arg0, arg1);

or using multi-methods

message(obj, arg0, arg1)

all work. They are instant ways to free the programmer from the
limited, built-in OOP system. They are all slower than the built-in
style as dispatch cannot be optimized as much. It also makes for some
funny looking code to have the built-in dot notation for DOM methods,
mixed in with one or more of the above styles. No perfect solution.
Code gets messy. Life goes on.

Peter

Ross Boucher

unread,
Jan 30, 2009, 3:47:11 PM1/30/09
to serv...@googlegroups.com
This is exactly why we wrote Objective-J.

Messages are written like this:

[object message];

In reality, they are simple:

objj_msgSend(object, "message");

Just like in Objective-C. Doing this without the syntax support would
be a nightmare. As for speed, it's not really an issue. objj_msgSend
is < 1% of the profile time of any part of 280 Slides. Once you're
doing anything remotely complicated, that quickly eclipses the
overhead of the message send.

Peter Michaux

unread,
Jan 30, 2009, 3:51:40 PM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 12:47 PM, Ross Boucher <rbou...@gmail.com> wrote:
>
> This is exactly why we wrote Objective-J.

"This"? I'm not sure which part of what I wrote is the "this" part.

> Messages are written like this:
>
> [object message];
>
> In reality, they are simple:
>
> objj_msgSend(object, "message");

Slower than object.message().

> Just like in Objective-C. Doing this without the syntax support would
> be a nightmare. As for speed, it's not really an issue. objj_msgSend
> is < 1% of the profile time of any part of 280 Slides. Once you're
> doing anything remotely complicated, that quickly eclipses the
> overhead of the message send.

These numbers are exciting and encouraging. I'd need to do a big study
on a variety of code bases or see a good article explaining how the
tests were made before I could depend on any number like <1%. It is
potentially a big performance risk.

Peter

Hannes Wallnoefer

unread,
Jan 30, 2009, 4:02:09 PM1/30/09
to serverjs
On Jan 30, 9:34 pm, Peter Michaux <petermich...@gmail.com> wrote:
> On Fri, Jan 30, 2009 at 8:44 AM, Kevin Dangoor <dang...@gmail.com> wrote:
> > My suggestion is that people who are interested or already have useful
> > APIs for this or whatever, create a new page under ServerJS/Modules/
> > quickly describing the approach (basically a few examples of file
> > layout and inclusion of modules). If you've already got some docs, you
> > can copy and paste that in or something. And then add a link under
> > "Proposed API" here:
>
> >https://developer.mozilla.org/ServerJS/Modules
>
> Two ideas posted.

I added my proposal, too. I'm calling it 'Pythonic Modules', which is
catchy and gives a good idea what it is about.

https://developer.mozilla.org/ServerJS/Modules/Pythonic_Modules

Hannes

> Peter

Breton

unread,
Jan 30, 2009, 4:22:29 PM1/30/09
to serverjs
Adobe Extendscript also has a File object with seek abilities. I think
it's similar, or the same as the one in Spidermonkey.

Breton

unread,
Jan 30, 2009, 4:33:52 PM1/30/09
to serverjs


On Jan 31, 3:09 am, Robert Koberg <r...@koberg.com> wrote:

> It would really be nice to get away from a 'File' object (which, to  
> me, means a filesystem directory or file) and go to Collection and  
> Resource (or Document or Doc). Then it would be up to the implementor  
> to abstract away and/or mix a filesystem, a json DB (at least like  
> mongodb as couchdb doesn't have collections... don't know much about  
> perservere), an XML db or a relation db.
>
> I also think a RESTful perspective would be very useful in dealing  
> with Collections and Resources.
>
> best,
> -Rob

I really don't know why this post isn't getting more attention. I
think this is a marvelous idea, and really increases the opportunities
for polymorphic code. If a server environment doesn't have an SQL db,
you can use files. If it doesn't have files, you can use XML. if it
doesn't have XML, you can use JSON. etc. etc. without rewriting
everything.

In fact, I think I'll start using this idea right away, myself.

Peter Svensson

unread,
Jan 30, 2009, 5:56:21 PM1/30/09
to serv...@googlegroups.com
It's a bit like the Jackrabbit idea (JSR-170) popularized by Sling; To b able to map anything onto a REST idea adn have multiple (and custom) renderers, which Persevere have lifted up in the JS space.

Cheers,
PS

Robert Koberg

unread,
Jan 30, 2009, 6:03:07 PM1/30/09
to serv...@googlegroups.com

On Jan 30, 2009, at 5:56 PM, Peter Svensson wrote:

> It's a bit like the Jackrabbit idea (JSR-170) popularized by Sling;
> To b able to map anything onto a REST idea adn have multiple (and
> custom) renderers, which Persevere have lifted up in the JS space.

I would say it is more of an XPath thing (and probably many others). I
think XPath has a good base that could be brought over to the
discussion here. If anything, reading the links below (they are short,
I promise :) ) will perhaps pop some ideas.

From an earlier post in this thread:

http://www.w3.org/TR/xpath-functions/#func-doc
http://www.w3.org/TR/xpath-functions/#func-doc-available
http://www.w3.org/TR/xpath-functions/#func-collection

collection() isn't completely defined but saxon has a really nice
implementation:

http://saxonica.com/documentation/sourcedocs/collections.html

best,
-Rob

Steven Brown

unread,
Jan 30, 2009, 7:04:11 PM1/30/09
to serv...@googlegroups.com
A lot of the discussion so far is about JS in typical web server
environments.

I'd like to be able to share code between my web server (e.g. Apache+Jaxer)
and streaming server environments, for example Red5.

I know that Red5 has some basic JS support but it really is only basic and a
bit of a pain to work with, for example you have to restart the server with
any code changes.

At the moment most of my work is PHP+JS/Flash+AS/Red5, it would be great to
have Jaxer JS/Flash JS/Red5 JS and allow all of them to share a similar code
base and highly streamlined interactions.

For example a page is created with SSJS and served to the client. The user
can click a link using CSJS which tells flash to play a video. The FJS then
makes a request from Red5, which can process stuff pretty much the same as
SSJS (permissions etc.) and stream the video to the client. At this point
SSJS/CSJS/FJS/Red5JS are all able to communicate with each other easily and
they all "know" the same stuff.

Maybe it's just a dream...but then Paul had a dream once :)


Kevin Dangoor

unread,
Jan 30, 2009, 7:48:23 PM1/30/09
to serv...@googlegroups.com

Thank you!

If I get a chance, I'll see if I can make some of the other pages look
a bit more like the Modules one does now. Thanks to you and Hannes,
there is now something concrete to talk about.

Robert Koberg

unread,
Jan 30, 2009, 8:11:34 PM1/30/09
to serv...@googlegroups.com

On Jan 30, 2009, at 7:48 PM, Kevin Dangoor wrote:

>
> On Fri, Jan 30, 2009 at 3:34 PM, Peter Michaux
> <peterm...@gmail.com> wrote:
>>
>> On Fri, Jan 30, 2009 at 8:44 AM, Kevin Dangoor <dan...@gmail.com>
>> wrote:
>>
>>> My suggestion is that people who are interested or already have
>>> useful
>>> APIs for this or whatever, create a new page under ServerJS/Modules/
>>> quickly describing the approach (basically a few examples of file
>>> layout and inclusion of modules). If you've already got some docs,
>>> you
>>> can copy and paste that in or something. And then add a link under
>>> "Proposed API" here:
>>>
>>> https://developer.mozilla.org/ServerJS/Modules

Just looked at this page. First:

"Spidermonkey and Rhino offer a load function, but does not have any
specific pattern for namespacing."

At least for Rhino, this is just for the shell. There is no 'load'
function available to JS. (if there is it is new?).

Second, apart from the name 'File' which seems unnecessary limiting in
what it could describe... why would you need this on the server? It
seems to me that all you needs is a shared directory and a runtime
directory.

In the shared directory you dump all your scripts that should live in
a shared/global scope available to all runtime scripts. At startup
they are loaded and cached.

In the runtime directory you 'sort of' mimic your request URIs and
target a single script for the HTTP request. You provide the shared/
global scope to the runtime instance. I say 'sort of' because you may
need to reduce the path by removing request instance specific details
so it can match a generic runtime script. Even further break out the
scripts to target request methods:

a request to /projects has:
- GET.js -- display a list of a user's projects
- PUT.js -- allow authorized users to modify/add a project
- DELETE.js -- allow authorized users to delete a project
(I avoid POST, that and other methods could be MOVE and COPY)

So, on a (servlet container) filesystem it would look like:

- docroot
|- WEB-INF
- scripts
|- shared
|- runtime
|- projects
- GET.js
- PUT.js
- DELETE.js


best,
-Rob


Thomas Robinson

unread,
Jan 30, 2009, 8:58:31 PM1/30/09
to serv...@googlegroups.com

On Jan 30, 2009, at 5:11 PM, Robert Koberg wrote:

>
>
> On Jan 30, 2009, at 7:48 PM, Kevin Dangoor wrote:
>
>>
>> On Fri, Jan 30, 2009 at 3:34 PM, Peter Michaux
>> <peterm...@gmail.com> wrote:
>>>
>>> On Fri, Jan 30, 2009 at 8:44 AM, Kevin Dangoor <dan...@gmail.com>
>>> wrote:
>>>
>>>> My suggestion is that people who are interested or already have
>>>> useful
>>>> APIs for this or whatever, create a new page under ServerJS/
>>>> Modules/
>>>> quickly describing the approach (basically a few examples of file
>>>> layout and inclusion of modules). If you've already got some docs,
>>>> you
>>>> can copy and paste that in or something. And then add a link under
>>>> "Proposed API" here:
>>>>
>>>> https://developer.mozilla.org/ServerJS/Modules
>
> Just looked at this page. First:
>
> "Spidermonkey and Rhino offer a load function, but does not have any
> specific pattern for namespacing."
>
> At least for Rhino, this is just for the shell. There is no 'load'
> function available to JS. (if there is it is new?).

Yes, the load function is implemented as part of the "shell", but it's
available to any JavaScript that's executed using the shell, including
files you pass in as command line arguments, not just commands you
type into the shell.

That said, it's not particularly very useful, since all paths must be
absolute or relative to the directory you start Rhino from. That is,
they can't be relative to the importing file's path, or in "search
paths" like you have in Ruby, etc.

(I've implemented a really simple "import"/"require" mechanism that
has search paths and relative paths: http://github.com/tlrobinson/jack/blob/54a28398425287bddd9466955d5e8ea616eb8d47/core.js#L10
but the "real" one would also probably have to handle importing
native code extensions, not just simple "eval()"-ing of the file
contents)

This seems like a very application-specific way of doing things. It
would certainly be acceptable as part of a web framework stack, but I
think we should provide general purpose tools for writing any sort of
non-client side JavaScript as well.

Kris Zyp

unread,
Jan 30, 2009, 9:33:24 PM1/30/09
to serv...@googlegroups.com
This looks good, but could you explain the necessity of the three
different module loading mechanisms (import, require, and include)?
Would it be possible to boil it down to one or two? I would certainly
prefer to keep things as simple as possible.
Thanks,
Kris

Ycros

unread,
Jan 30, 2009, 9:46:41 PM1/30/09
to serverjs
On Jan 31, 1:33 pm, Kris Zyp <kris...@gmail.com> wrote:
> This looks good, but could you explain the necessity of the three
> different module loading mechanisms (import, require, and include)?
> Would it be possible to boil it down to one or two? I would certainly
> prefer to keep things as simple as possible.
>
> Hannes Wallnoefer wrote:
> > On Jan 30, 9:34 pm, Peter Michaux <petermich...@gmail.com> wrote:
>
> >> On Fri, Jan 30, 2009 at 8:44 AM, Kevin Dangoor <dang...@gmail.com> wrote:
>
> >>> My suggestion is that people who are interested or already have useful
> >>> APIs for this or whatever, create a new page under ServerJS/Modules/
> >>> quickly describing the approach (basically a few examples of file
> >>> layout and inclusion of modules). If you've already got some docs, you
> >>> can copy and paste that in or something. And then add a link under
> >>> "Proposed API" here:
>
> >>>https://developer.mozilla.org/ServerJS/Modules
>
> >> Two ideas posted.
>
> > I added my proposal, too. I'm calling it 'Pythonic Modules', which is
> > catchy and gives a good idea what it is about.
>
> >https://developer.mozilla.org/ServerJS/Modules/Pythonic_Modules

I really like the 'P3 - Pythonic Modules' proposal. Having done both
extensive Ruby (similar to 'P1 - global file loading') and Python
work, I feel that Python's approach to the problem of modules and
importing code is vastly superior. I've had to wrangle with
interesting conflicts between Ruby libraries in the past, and it's
really annoying in large projects.

I like the idea of explicit exports, but I also agree that it's only
needed for the include() use-case. Perhaps if there is no explicit
exports() definition, it should just import everything.

I also don't like how there are three somewhat arbitrarily named
functions. I have a proposal on how to fix that though:

1. var module = import('foo.module'); -- Like require(), just
returns the module.

2. import('foo.module').global() -- Like import() (not sure if
global is the best name, since it'd only be "global" for the script
that's importing it)

3. import('foo.module').include() -- Like include(), merging that
module's members into the current module's scope.

Peter Michaux

unread,
Jan 30, 2009, 10:17:37 PM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 1:02 PM, Hannes Wallnoefer <han...@gmail.com> wrote:

>> >https://developer.mozilla.org/ServerJS/Modules
>>
>> Two ideas posted.
>
> I added my proposal, too. I'm calling it 'Pythonic Modules', which is
> catchy and gives a good idea what it is about.
>
> https://developer.mozilla.org/ServerJS/Modules/Pythonic_Modules

I like the Python module loading style you have outlined. It seems
great for a server-only ecosystem of code modules.

My concern is sharing code with the client. If I make a file like the
following for use on the server

// foo.js
var a = function() {};
var b = function() {};
var c = function() {};

then I can use it in another file on the server without polluting the
global namespace.

// bar.js
var foof = require('foo');
foof.a();

If I find that the contents of foo.js are useful in the browser, then
foo.js, as written, will pollute the global namespace in the browser
when loaded.

Another problem is if several files written as foo.js is above are to
be concatenated for use in the browser, how is that to be done in a
straight foward, reliable way?

Peter

Peter Michaux

unread,
Jan 30, 2009, 10:26:31 PM1/30/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 6:33 PM, Kris Zyp <kri...@gmail.com> wrote:
>
> This looks good, but could you explain the necessity of the three
> different module loading mechanisms (import, require, and include)?
> Would it be possible to boil it down to one or two? I would certainly
> prefer to keep things as simple as possible.

I think it could be trimmed down to just the "require" function.

----

Perl allows for the include/export business and although I haven't
written much Perl, it certainly seems better to have the file doing
the including to explicitely specify what is to be included. I have
written the following in Perl

use Mod::Ule ();

to avoid automatically exported symbols.

----

Destructuring assignment for the require-type of script loading was
discussed on the ECMAScript list and seemed quite well liked.

var foo = require('foo');
var a = foo.a;
var b = foo.b;

can be shortened to

var {a: a, b: b} = require('foo');

which can further be shortened to

var {a, b} = require('foo');

which is pretty darn short, very JavaScript-like, and explicitly shows
all variables that appear in a file.

Peter

Kris Zyp

unread,
Jan 30, 2009, 10:26:14 PM1/30/09
to serv...@googlegroups.com
I guess I need some clarification on what the terms mean here. When you
say "returns the module" do you mean that it returns the execution of
the script as eval does, which in multi-line script returns the value of
the last expression? Or does it return a scope object? And is imported
script supposed to execute in a different scope than the global scope
(of the caller)? Is the callee's scope a child scope of the global scope
(where [[Parent]] refers to the global scope) or a completely different
global scope? And does export() export from the module's scope (whatever
that is) to a newly created object that gets returned includes?
Thanks,
Kris




> >
>

Ycros

unread,
Jan 30, 2009, 10:57:37 PM1/30/09
to serverjs

Ycros

unread,
Jan 30, 2009, 11:14:50 PM1/30/09
to serverjs
On Jan 31, 2:17 pm, Peter Michaux <petermich...@gmail.com> wrote:
Interesting problem. I can see how it would be useful to share some
bits of code (validation for your models AND client-side forms?). The
Pythonic model seems to not support that too well, because the module
system takes care of name spacing concerns for you.

Maybe there could be an exporter which you could run over a bunch of
files, and it would do some light-weight namespace wrapping?

Thomas Robinson

unread,
Jan 30, 2009, 11:38:53 PM1/30/09
to serv...@googlegroups.com


Destructuring assignment is a JavaScript 1.7 feature. I don't know if
we've determined what version of the language to support, but I would
prefer 1.6 or maybe even 1.5. (SM and Rhino implement at least 1.7,
but JSC and V8 only implement 1.6, I think)

Also, I don't think that last syntax ("var {a, b} = require('foo');")
is valid. The other syntax seems a bit verbose.


Personally, I think the simplest solution is the best: just eval the
code in the global shared scope.

Perhaps wrap the code in a function to give "var" variables "file
scope", while still allowing globals (that's what we do in Objective-J)

Library authors should be responsible and not pollute the global scope
excessively. If they do, users will complain, or someone else will
write a better library.

This has worked pretty well in the browser (at least recently), as
well as in various languages like Ruby.


-Tom

Davey Waterson

unread,
Jan 31, 2009, 12:25:09 AM1/31/09
to serv...@googlegroups.com
the helma thread shows how this is tricky and political, implementing a
'standard' for this would be tough for existing libraries, for example in Jaxer
we can run most any clientside library on the server so doing something like

require('jQuery.js');

would at least require an optional custom test to see if it was already loaded

require('jQuery.js', isjQueryLoaded);

for the cases where the library being loaded doesn't know about he module
system, clearly not a hugely tricky piece of code to write per library, but
something that would need to be allowed for.

I understand this is less important if you are only viewing serverside js as a
kind of cgi equivalent, but there's so much more.

I tend to err towards module should be a language feature, at the very least
some guidance from Brendan, would be good, as this was an ES4 proposal that was
killed in the whole ES3.1 debacle.

Peter Michaux wrote:
> On Jan 29, 4:24 pm, Robin Berjon <robin.ber...@gmail.com> wrote:
>> On Jan 30, 2009, at 01:12 , Peter Michaux wrote:
>>
>>> A large discussion about these issues was had on the Helma NG group
>>> with three main participants. The lack of agreement on the module
>>> system issue was a complete spoiler. I believe this is *the* major
>>> issue to overcome.
>> Do you have a pointer to it? That way we could read up beforehand and
>> avoid going through the same issues :)
>
> It was a doozy spread across several threads.
>
> http://groups.google.com/group/helma-ng/browse_frm/thread/79afcdef68a2aa55
>
> http://groups.google.com/group/helma-ng/browse_frm/thread/6d002cb42a47ae42
>
> Peter
>
> >
>

Peter Michaux

unread,
Jan 31, 2009, 3:18:43 AM1/31/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 8:38 PM, Thomas Robinson <tlrob...@gmail.com> wrote:

> Also, I don't think that last syntax ("var {a, b} = require('foo');")
> is valid.

Firefox 3

function bar() { return {p:42, q:"hi"} }
var {p, q} = bar()
p // 42
q // "hi"


> Personally, I think the simplest solution is the best: just eval the
> code in the global shared scope.

> Perhaps wrap the code in a function to give "var" variables "file
> scope", while still allowing globals (that's what we do in Objective-J)

If the file is loaded with script tags (which is the way most code
will continue to be loaded) then this wrapping needs to be done when
the file is served or at compile time (which means introducing a
compile time). I'm not in favor of any of these options.


> Library authors should be responsible and not pollute the global scope
> excessively. If they do, users will complain, or someone else will
> write a better library.
>
> This has worked pretty well in the browser (at least recently), as
> well as in various languages like Ruby.

Yes it has.

Peter

Peter Michaux

unread,
Jan 31, 2009, 3:24:39 AM1/31/09
to serv...@googlegroups.com
On Fri, Jan 30, 2009 at 9:25 PM, Davey Waterson <geek...@gmail.com> wrote:

> I tend to err towards module should be a language feature,

I agree. On the ES discuss list, some committee members feel that
script loading is up to the host to expose in an appropriate manner
for the containing app. Some members seem to think there should be a
standard loading system. Since script loading involves the containing
app, I side with those leaving up to the app programmer because
otherwise ECMAScript will loose some flexibility as an embedded
language.

> at the very least
> some guidance from Brendan, would be good, as this was an ES4 proposal that was
> killed in the whole ES3.1 debacle.

Packages, namespaces and units seemed like a big, confusing,
overlapping mess in the ES4 proposal. If I remember correctly,
one-by-one each of these was shot down as "inappropriate for the web".

Peter

Peter Svensson

unread,
Jan 31, 2009, 4:24:05 AM1/31/09
to serv...@googlegroups.com
I think that the low-level APIs for the upcoming specification will be just as useful for the red5 environment as it will be for an web/appserver environment. Sockets, File and other stuff are not inherently tied to any specific scenario.

Cheers,
PS

Hannes Wallnoefer

unread,
Jan 31, 2009, 6:12:20 AM1/31/09
to serverjs
On Jan 31, 6:25 am, Davey Waterson <geekfr...@gmail.com> wrote:
> the helma thread shows how this is tricky and political, implementing a
> 'standard' for this would be tough for existing libraries, for example in Jaxer
> we can run most any clientside library on the server so doing something like

Yes, it was a difficult process, even for one little framework. But I
think we got something nice, so it was worth it.

> I tend to err towards module should be a language feature, at the very least
> some guidance from Brendan, would be good, as this was an ES4 proposal that was
> killed in the whole ES3.1 debacle.

Ideally it would be a language feature. But don't hold your breath for
it. It's quite clear the EcmaScript folks (rightfully) see their
language as an embedded one, and prefer to leave the question of
script loading to the application domain. In the case of the browser,
that is the W3C with the (X)HTML specs. In the case of server side JS,
I guess it would be ...us!

But I have enough realism in me to know that it's quite unlikely we
will reach agreement here. The goals and designs of the various
projects are just too diverse. Still, I think it's worth another try,
which is why I wrote the Pythonic Modules proposal.

Hannes

Hannes Wallnoefer

unread,
Jan 31, 2009, 6:42:34 AM1/31/09
to serverjs
On Jan 31, 3:33 am, Kris Zyp <kris...@gmail.com> wrote:
> This looks good, but could you explain the necessity of the three
> different module loading mechanisms (import, require, and include)?
> Would it be possible to boil it down to one or two? I would certainly
> prefer to keep things as simple as possible.

I agree, three loading mechanisms seem like overkill. You can do with
one or two, and this is what we aimed for initially. But we actually
have use cases for each of it. In particular, import() and require()
are similar, as the first can be implemented in terms of the second.
The following two lines are aequivalent:

import('foomodule');
var foomodule = require('foomodule');

In the end, it was convenience that outweighted the overlapping
functionality. For example, a row of aligned import() calls at the
beginning of a script are much easier to parse than a list of var foo
= require('foo') assignments, each one aligned differently. Also,
importing modules into nested namespaces is cumbersome with require,
while import('foo.bar') will set up the foo.bar namespace for you.

Regarding your other question in the post below, require() returns the
module scope, i.e. the object the scope was evaluated on. I'll see if
I can clear that up in the proposal.

Hannes

Starr Horne

unread,
Jan 31, 2009, 9:07:35 AM1/31/09
to serverjs
> That's ideally how it would work, but I suspect if we just release a
> spec and hope for the JS engine developers to implement it themselves
> it will take years. I think we'll need to actively develop at least
> one "reference implementation" of the spec.

Agreed, I think that before this thing will get off of the ground,
we'll need

1) The spec
2) A reference implementation.
3) An airtight test suite that can be run against new implementations.

Also, personally, I find that the act of implementing a spec always
shines light on ways that the spec could be improved.

SH

CB Ash

unread,
Jan 31, 2009, 10:49:12 AM1/31/09
to serverjs
I can very much see the use of "include" and "require" as you
described in the Pythonic Modules proposal. Very clear use cases in my
mind. However I would like to see more on the use cases between
"include" and "import". To me those would seem to be use cases so
similar that they could be handled by just "include". Again, I'd love
to know your thoughts on those use cases.

CB Ash

unread,
Jan 31, 2009, 10:55:05 AM1/31/09
to serverjs
So starting with the spec, we've got a lot of information filling up
at https://developer.mozilla.org/ServerJS, lets open up a discussion
thread on the spec and distill it out from the ideas so far? Just a
thought ...

Mario Valente

unread,
Jan 31, 2009, 11:52:59 AM1/31/09
to serv...@googlegroups.com
Breton wrote:
>
>
> Adobe Extendscript also has a File object with seek abilities. I think
> it's similar, or the same as the one in Spidermonkey.
>

This is a good point yall...

There is some stuff that we could use, copy or be compatible
with, both in Adobe PDF-side javascript and in ActionScript (which
also has a serverside version). I'll try to add these to the
wiki...

-- MV

Mario Valente

unread,
Jan 31, 2009, 12:08:23 PM1/31/09
to serv...@googlegroups.com
Thomas Robinson wrote:

> Destructuring assignment is a JavaScript 1.7 feature. I don't know if
> we've determined what version of the language to support, but I would
> prefer 1.6 or maybe even 1.5. (SM and Rhino implement at least 1.7,
> but JSC and V8 only implement 1.6, I think)
>

The latest one, 1.8. Spidermonkey is the reference implementation,
that should be the target.

-- MV

Ross Boucher

unread,
Jan 31, 2009, 1:12:37 PM1/31/09
to serv...@googlegroups.com
Completely disagree. Not targeting the most common versions of
JavaScript is a huge mistake. It's like building a website that only
runs in Firefox.

Personally I'd be in favor of just targeting 1.3, but since the
majority of server side libraries probably support JS 1.5 that may be
doable.

Peter Svensson

unread,
Jan 31, 2009, 1:15:53 PM1/31/09
to serv...@googlegroups.com
Actually, I agree here. We should strive to create an API that is easy and possible to implement across all current VMs

Cheers,
PS

Mario Valente

unread,
Jan 31, 2009, 1:26:17 PM1/31/09
to serv...@googlegroups.com
Ross Boucher wrote:
> Completely disagree. Not targeting the most common versions of
> JavaScript is a huge mistake. It's like building a website that only
> runs in Firefox.
>

Targeting JS 1.3 or 1.5 is like building a website that
only runs in IE 5.

-- MV

Peter Svensson

unread,
Jan 31, 2009, 1:30:27 PM1/31/09
to serv...@googlegroups.com
Well, my point is that I think that the API specs might not need o depend on JS version at all. As long as the calling convention is the same (and it is!), there no reason we should deliberately break compatibility when there is no need. The outspoken reason for this group is of course to ensure portability of higher complexity across VMs.

Cheers,
PS

Peter Michaux

unread,
Jan 31, 2009, 1:35:22 PM1/31/09
to serv...@googlegroups.com

I think the foundational things like module loading and package
management can be done safely with ECMAScript v3 standard (JavaScript
1.5). This has been around for a long time now and is certainly very
common.

Other, non-standard packages could specify newer language versions
with the version number in the package's meta data file. Then it is up
to application authors to decide.

Peter

Davey Waterson

unread,
Jan 31, 2009, 3:26:14 PM1/31/09
to serv...@googlegroups.com
serverside is different from client, in that we are in a much more controlled
environment. __noSuchMethod__ or method not found support is something i would
not want to give up to provide a lowest common denominator implementation.

The API will be the API but the implementation is only of concern to the
implementors, as long as the API itself doesn't surface any unsupported features
of spidermonkey/v8 i'm cool with that.

Peter Michaux

unread,
Jan 31, 2009, 11:54:13 PM1/31/09
to serv...@googlegroups.com
Hannes,

For the global eval loading system, a file one.js might be written like this

(function() {
global = this;
global.foo = function() {};
global.bar = 33;
})();

Another library file two.js might use the above by evaluating it in
the global scope with "load"

load('one');
var ff = function() {
foo();
};

Wouldn't a file in Helma still be able to reuse the code in the above
files? If Helma overrides "load" with something like the Helma
"include" semantics but where there is no associated export in the
included file I think it would work. That is, Helma would have
something like "include('modulename', '*')" where the * means include
all symbols. I think in Python this would be like "from modulename
import *".

Then if a Helma file has the following it should still work as
expected and not pollute the global namespace.

var two = require('two');
two.ff() // works
two.foo() // error

This would allow Helma to use files intended for the global eval
loading system but not vice versa which actually seems ok.

The only catch is the author of a script intended for the global eval
system would need to explicitly write all load statements even if he
had reason to believe the module is loaded into the global scope in
another file. A library author should have all possible explicit load
statements everywhere anyway, in my opinion.

Peter

Hannes Wallnoefer

unread,
Feb 1, 2009, 5:34:35 AM2/1/09
to serverjs
On Jan 31, 4:49 pm, CB Ash <the.shadow....@gmail.com> wrote:
> I can very much see the use of "include" and "require" as you
> described in the Pythonic Modules proposal. Very clear use cases in my
> mind. However I would like to see more on the use cases between
> "include" and "import". To me those would seem to be use cases so
> similar that they could be handled by just "include". Again, I'd love
> to know your thoughts on those use cases.

import() defines a property in the local scope containing the imported
module scope, while iclude() defines one property for each property
the included module scope defines. For example, the helma.file module
exports the File constructor. With import('helma.file') you can access
it as helma.file.File(), with include('helma.file') you can access it
directly as File().

Hannes

Hannes Wallnoefer

unread,
Feb 1, 2009, 6:41:40 AM2/1/09
to serverjs
Yes, it is quite easy to mimic more 'traditional' loading mechanisms
in Helma NG. The difference with include() is that the included file
is still evaluated on an empty scope object, and only then are the
exported properties copied over to the including scope.

This is actually a great feature, because included functions are
closures around their 'home' module scope, so a foo() in an included
function will always call function foo in its origin module, not the
one that is including it.

If you really want to implement browser-like script loading, you have
to actually use the same scope for each evaluation. There's a
helma.system.evaluate(module, scope) method in Helma NG that lets you
do this if you need it.

> The only catch is the author of a script intended for the global eval
> system would need to explicitly write all load statements even if he
> had reason to believe the module is loaded into the global scope in
> another file. A library author should have all possible explicit load
> statements everywhere anyway, in my opinion.

Yes, loading modules into a shared global scope makes you really
sloppy. For example, if you have modules A and B that both require
module C, you will never notice you forgot to load C in B until you
use B without A. There are modules in Helma NG that augment the global
JavaScript objects like Object, String, Array, and it happens all the
time. This is another reason why I think having a module system
without per-module scoping is a half-assed solution.

Hannes

> Peter

George Moschovitis

unread,
Feb 1, 2009, 10:51:29 AM2/1/09
to serverjs
> (also, I think ssjs is a misleading name, since you'll be able to use
> it for things other than servers)

I couldn't agree more here. Even the name of the group is misleading.
The lines between server and client are blurring by the day.
I think we should be working towards a Standard js library (not a
server js library).

-g.

http://www.gmosx.com

Peter Michaux

unread,
Feb 1, 2009, 11:08:04 AM2/1/09
to serverjs
On Jan 30, 1:02 pm, Hannes Wallnoefer <hann...@gmail.com> wrote:

> I added my proposal, too. I'm calling it 'Pythonic Modules', which is
> catchy and gives a good idea what it is about.
>
> https://developer.mozilla.org/ServerJS/Modules/Pythonic_Modules

In an IRC chat, I think Hannes won me over that standardizing only
"require" on the above page would be a good way to go. The "import"
and "include" are not needed to be standardized and Helma could have
them as extensions. Shared code would be limited to "require".
Standardizing "require" is certainly enough of a standard that
implementations can actually start writing sharable code.

Advantages of require:

- explicitly shows all things used in a particular file. Better than
wondering where something was loaded.

- fully "namespaced" code with an object hierarchy as is popular in
browser scripting can still be used here when needed to allow for code
sharing with the browser. I think this needs to be encouraged when any
code is not server-dependent.

- protection against missing var statements

- it seems more "grown up" and appropriate for larger projects.

I'm going to mull it over some more but I'm not seeing disadvantages
with "require" anymore.

Peter
Reply all
Reply to author
Forward
0 new messages