Designing JScript .NET

A
while back a reader asked for a rundown on some of the design decisions we made when
designing JScript .NET.  That’s a huge
topic, but fortunately I started writing a book on the subject a few years ago that
never found a publisher.  “urn:schemas-microsoft-com:office:office” />Tell
you what — whenever I can’t think of something more interesting to post, I’ll put
snippets of it up on my blog.

 

There
were four main design goals for JScript .NET:

 

1)      JScript
.NET should be an extension of JScript.
This means that whenever possible a legal JScript program should be a legal JScript
.NET program. JScript .NET must continue to
be usable as a dynamic scripting language
. Further, it should be easy to take
an existing JScript Active Server Page and transform it into a JScript .NET page for
ASP.NET.

 

2)      JScript
.NET should afford the creation of highly
performant programs
. In particular, JScript .NET should work well with ASP.NET
because performance is often critical in server-side applications. Also, JScript .NET
should warn programmers when they use a language feature which could adversely impact
performance.

 

3)      JScript
.NET should work well with the .NET Common
Language Runtime (CLR).
 The CLR provides interoperability with other languages.
It also ensures that JScript .NET works well with the .NET Frameworks, a huge library
of useful packages.

 

4)      JScript
.NET should make programming in the large
easier
. It should support programming styles that make it easy to reason about
large programs. It should also provide programming constructs which make it easy to
divide up large projects among team members.

 

Today
I’ll talk a bit about the second point — how can we make JScript .NET faster than
JScript?  (I know, I said a while back
that I’d give you my rant about performance and script languages.  Maybe
if I have time tomorrow.)

 

JScript
.NET takes a three-pronged approach towards improving performance. Individually each
would help somewhat, but as is often the case, the whole is greater than the sum of
its parts. These three prongs work together to afford the creation of more performant
programs:

 

1)      JScript
.NET has a type annotation system.

2)      JScript
.NET discourages and/or restricts certain programming idioms which cause egregious
performance problems.

3)      JScript
.NET uses the Common Language Runtime.

 

The
type annotation system can be complex when you look at the details — I’ll probably
talk more about it in detail later.  But
essentially the type annotation system is quite simple: the programmer attaches annotations
to variable declarations, function argument lists and function return values. These
annotations restrict the kinds of data which may be stored, passed or returned respectively.

 

Consider
the simple example of adding two and two:

 

var Alpha
= 2, Beta = 2;

// [
many lines of code omitted ]

var Gamma
= Alpha + Beta;

 

Though Alpha and Beta starts
off their lives as numbers who knows what they are by the time Gamma is
declared? Some code may have stored a string or a date or any other kind of data into Alpha or Beta.

 

Ironically,
adding two and two thereby becomes a complicated mess. The JScript engine must determine
at run time whether a string has been assigned to either Alpha or Beta (or
both). If so then they must be both converted to strings and concatenated. If neither
is a string then both must be converted to numbers and added. This sounds simple enough
but glosses over a number of details. For instance, the conversions are themselves
possibly extremely complicated depending on what data have been stored in Alpha and Beta.
Suffice to say that a seemingly simple operation like addition can take thousands
of machine cycles, entire microseconds in some cases.

 

This
is unfortunate. If there is one thing that computers are good at it’s adding numbers
blindingly fast. If the JScript .NET compiler could somehow
know that only numbers could possibly be stored
 in Alpha and Beta then there
would be no need to determine the types at run time
. The compiler could simply
emit instructions optimized for the case of adding two numbers. This operation could
take nanoseconds instead of microseconds.

 

In
JScript .NET you annotate the type of a variable by appending a colon and the type
after the declaration.

 

var Alpha :
Number = 2, Beta :
Number = 2;

// [
many lines of code omitted ]

var Gamma :
Number = Alpha + Beta;

 

The
code generated for this addition should now be much more efficient.

 

Type
annotation also allows function calls to be much more efficient. Consider a simple
function call on a string:

 

var Delta
= 123;

// [
many lines of code omitted ]

var Zeta
= Delta.toString();

 

Again,
though Delta starts
off as a number it could be anything by the time toString is
called. This is what we mean by a late bound scenario. The type of Delta is
unknown, so at run time the object must be searched to see if it has a method named
“toString”.
This search is potentially expensive. It could be far more efficient if the compiler
knew ahead of time that Delta should
be converted to a string the same way that all numbers are converted to strings.

 

var Delta :
Number = 123;

// [
many lines of code omitted ]

var Zeta :
String = Delta.toString();

 

Note
that the JScript .NET compiler has an automatic
type inference engine
If the compiler
sees that a local variable in a function only ever has, say, strings assigned to it
then the compiler will treat the variable as though it was annotated with the 
String type. However,
it is a poor programming practice to rely upon the type inference engine. Certain
programming practices (especially the use of the eval function)
prevent the inferrer from making valid inferences. Also the inferrer can only make
inferences on local variables; the types of
unannotated global variables are not inferred.

 

There
are also other good reasons to add annotations rather than relying on the inferencer
to do it for you, but those will have to wait for another entry.

Tags JScript JScript .NET Performance Scripting

Comments (5)

You must be logged in to post a comment.

  1. AnuI have to tell you, the fact that Javascript protoyped objects are not first class dot net objects is very annoying. This ability would have been very welcome.
  2. Log in to Reply
  3. October 15, 2003 at 12:00 am
  4. dave sandermani left msft for a few years and recently went back. as far as i’m concerned, the worst thing that happened while i was gone was the proliferation of the use of the non-word “performant”. makes me cringe every time.Log in to Reply
  5. otherwise, great article. 🙂
  6. October 15, 2003 at 12:55 am
  7. Eric LippertDave: “performant” is a perfectly good word with a solid back-formation etymology, clear and obvious meaning, and has no suitable existing synonym, and is therefore a welcome addition to the language. Languages evolve. Do you also cringe at “process” as a verb? Because a hundred years ago, it wasn’t. What about “contact” as a verb? Ditto. So you might as well complain about those while you’re at it for all the good it will do you.Log in to Reply
  8. Anu: I’m not sure what exactly you mean by “not first class .NET objects”. JScript prototype objects are not CLR compilant, but they are certainly .NET objects. Can you clarify?
  9. October 15, 2003 at 2:16 am
  10. AnuI was looking to convert some code written for the Rhino Javascript engine with a java host program.Is it possible? What is the class of a JScript prototype object?function test() {
    this.main = function() {
    Console.WriteLine(“HELLO”);
    }
    }with y.js
    using System;Log in to Reply
  11. public class CSTest {
    public static void main(String [] args) {
    fred f = new fred();
    f.getTest().main();
    }
    }
  12. class fred {
    function getTest() {
    return new test();
    }
    }
  13. like x.js
    import System;
  14. Thus I would have liked to be able to access/call the JScript prototype objects from the equivilent CSharp host replacement.
    I think the only way I could do it would be turn things around and have the JScript code act as the host, and reference the CSharp code.
  15. October 15, 2003 at 3:08 am
  16. Eric LippertI’m still not 100% sure that I understand what you’re asking but I think I get the gist. If you’re asking whether a JScript function declared in global scope that can be used as a constructor for a prototype object can be exposed as a class to a C# program — no, we don’t support that scenario. The strongly typed CLR class model and the dynamic prototype model do not work well together.Log in to Reply
  17. That’s one reason why we added traditional inheritance-hierarchy classes to JScript .NET.
  18. October 15, 2003 at 1:44 pm

Skip to main content

Follow Us

Popular Tags

C# Scripting JScript VBScript Language Design COM Programming Rarefied Heights Puzzles Rants Performance Security C# 4.0 Non-computer SimpleScript JScript .NET Immutability Code Quality Pages Recursion Books

Archives

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s