Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is JScript.NET between a script language and a traditionnal language ?

11 views
Skip to first unread message

Frederic Claux

unread,
Jul 9, 2001, 1:20:43 PM7/9/01
to
Hello,

I had no time to have a look at JScript.NET at the moment - unfortunately -
but I really love JScript 5.5 as it is today already. I think I love this
language because it's not typed at all. I also _love_ the dynamic evaluation
of code, which makes JScript one of the most powerful tool in my opinion. On
the other hand, this weak typing also makes it completely different from
.NET languages, which are strongly typed.
Note : I know the advantages of strong typing and weak typing since I'm both
a C++ and a JScript user. I often use both languages in my application,
intensively using active scripting and COM objects. Playing with the two
worlds is a game and know I have to make up my mind about the .NET strategy
regarding scripting languages.

Peter would you mind, please, explain me what JScript.NET, evidently a "mix"
of those two worlds, is really all about ?

I'd also like to know if JScript.NET can dynamically evaluate its own
(JScript.NET) code.

Thank you - all - a lot in advance.

--
Frederic Claux


Peter Torr (MS)

unread,
Jul 9, 2001, 9:53:43 PM7/9/01
to

"Frederic Claux" <nospam_f.claux@nospam_techbase.fr> wrote in message
news:eoUmhvJCBHA.1992@tkmsftngp02...
> Hello,

Hi there,

> I had no time to have a look at JScript.NET at the moment -
unfortunately -
> but I really love JScript 5.5 as it is today already.

Cool! You should love JScript.NET then!

> I think I love this
> language because it's not typed at all. I also _love_ the dynamic
evaluation
> of code, which makes JScript one of the most powerful tool in my opinion.

Yes, this makes it very easy to write code quickly, and to do funky cool
stuff.

> On
> the other hand, this weak typing also makes it completely different from
> .NET languages, which are strongly typed.

Well... the runtime doesn't make any statements about that. Both VB .NET and
JScript.NET support both typed and untyped programming. There is nothing in
the runtime that stops you writing untyped code.

> Playing with the two
> worlds is a game and know I have to make up my mind about the .NET
strategy
> regarding scripting languages.

.NET is all about supporting languages -- all sorts of languages -- be they
commercial (eg C++) script (eg Perl), academic (eg Mercury) or whatever. The
two technologies in .NET specifically designed to support scripting are
called VSA and Script for the .NET Framework (bit of a mouthful, I know).
VSA is really a super-set of script. These allow 3rd party applications to
host script code, just as applications host IActiveScript (or the Script
Control) today with COM.

> Peter would you mind, please, explain me what JScript.NET, evidently a
"mix"
> of those two worlds, is really all about ?

JScript supports both worlds -- untyped, late bound, dynamic code, and fully
typed, early bound, static code. Everything you could do in 5.x, you can do
in .NET (although some features are limited when you are running inside
ASP.NET). And most things you can do in C#, you can also do in JScript.NET

> I'd also like to know if JScript.NET can dynamically evaluate its own
> (JScript.NET) code.

Sure -- it wouldn't be JScript if it couldn't! Some things, like eval-ing
classes, are not supported, but pretty much everything else is. (Note though
that Beta 2 has a bug whereby you can't create objects via the "new"
operator -- this will be fixed though)

Peter

--
Peter Torr - pt...@microsoft.com
JScript .NET / VSA Runtime Program Manager
Please post all questions to the group. Thanks.


Frederic Claux

unread,
Jul 10, 2001, 5:13:09 AM7/10/01
to
"Peter Torr (MS)" <pt...@microsoft.com> a écrit dans le message news:

> > I'd also like to know if JScript.NET can dynamically evaluate its own
> > (JScript.NET) code.
>
> Sure -- it wouldn't be JScript if it couldn't! Some things, like eval-ing
> classes, are not supported, but pretty much everything else is. (Note
though
> that Beta 2 has a bug whereby you can't create objects via the "new"
> operator -- this will be fixed though)

Eval-ing classes was precisely one of the most interesting functionnality I
am looking for...
Will this be considered in future releases ?

--
Frederic Claux

Peter Torr (MS)

unread,
Jul 10, 2001, 6:47:34 PM7/10/01
to
"Frederic Claux" <nospam_f.claux@nospam_techbase.fr> wrote in message
news:uQb#vDSCBHA.1648@tkmsftngp07...

> Eval-ing classes was precisely one of the most interesting functionnality
I
> am looking for...
> Will this be considered in future releases ?

Maybe. It's hard to tell.

Note that I was bending the truth a little when I said you couldn't eval
classes in JScript.NET. You *can* eval a class, but with the following
constraints:

1) It must be done at the global level (not inside a method)

2) It is not a "real" .NET object, so it won't interoperate well with other
languages

#1 makes it impossible to eval a class inside ASP.NET or a DLL (since there
is no global code). You can only do it inside an EXE or inside a VSA runtime
host.

#2 makes it hard to do inheritance or pass objects to .NET methods, etc.

The reason for #1 is that the semantics of having a class inside a method
are unclear. We don't allow you to declare a class inside a method, so we
also don't allow you to eval a class inside a method. If we did (and we may
do in the future, although there's no guarantee), we'd have to figure out
things like scoping, and get the closure semantics correct -- difficult
stuff. And we'd need to get ECMA approval, too.

The reason for #2 is that although the runtime will do garbage collection on
data, it won't do it on code. So every time you eval-ed a class, that class
would stay around in memory. If 1,000 people hit your web page, you've got
1,000 chunks of IL that will never die (until ASP.NET recycles itself, or
you reboot, or whatever). To get around this, we have a kind of
"interpreted" class object that JScript.NET knows about, and can deal with,
but other languages don't.

Also note that although eval-ing a class "works" in global code, this is not
something we really support -- it was just too much effort to disable it
(which could introduce other bugs, etc). If you *really* want dynamic
classes, you could just host the VSA runtime engines and do a real
compilation.

Frederic Claux

unread,
Jul 11, 2001, 5:19:28 AM7/11/01
to
"Peter Torr (MS)" <pt...@microsoft.com> a écrit dans le message news:

> Also note that although eval-ing a class "works" in global code, this is


not
> something we really support -- it was just too much effort to disable it
> (which could introduce other bugs, etc). If you *really* want dynamic
> classes, you could just host the VSA runtime engines and do a real
> compilation.

Thanks a lot for this useful information.

The functionnality I am looking for is a runtime inheritance mechanism. If I
can declare a class in .NET using C# or JScript.NET, then use the VSA
"runtime compiler" to declare a class that inherits from the class
mentionned previously, and then use the latter (top level) class from the
original program in C# for example, I'll be very happy.

--
Frederic Claux

Peter Torr (MS)

unread,
Jul 11, 2001, 12:32:27 PM7/11/01
to
"Frederic Claux" <nospam_f.claux@nospam_techbase.fr> wrote in message
news:uvCa8reCBHA.2020@tkmsftngp07...

> The functionnality I am looking for is a runtime inheritance mechanism. If
I
> can declare a class in .NET using C# or JScript.NET, then use the VSA
> "runtime compiler" to declare a class that inherits from the class
> mentionned previously, and then use the latter (top level) class from the
> original program in C# for example, I'll be very happy.

Sure -- check the sample at the end of this post. It uses an interface
rather than a class, but it's trivial to change.

You *must* compile it into an EXE called "inheritance.exe", or else change
the line that sets a reference to "inheritance.exe", otherwise it won't
work.

This shows both early-bound and late-bound access to the class in the VSA
code; use one of the following command-lines:

jsc /t:winexe /d:early_bound_demo inheritance.js

or

jsc /t:winexe /d:late_bound_demo inheritance.js

Peter

--
Peter Torr - pt...@microsoft.com
JScript .NET / VSA Runtime Program Manager
Please post all questions to the group. Thanks.


// Script comment to make Visual InterDev do colour-coding
// <script>

// Some constants for the GUI
const FORM_WIDTH : int= 600
const FORM_HEIGHT : int = 600
const CODE_WIDTH : int = FORM_WIDTH - 16
const CODE_HEIGHT : int = 200
const BUTTON_WIDTH : int = 64
const BUTTON_HEIGHT : int = 24
const OUTPUT_WIDTH : int = (FORM_WIDTH - 24) / 2
const OUTPUT_START : int = CODE_HEIGHT + BUTTON_HEIGHT + 24
const OUTPUT_HEIGHT : int = (FORM_HEIGHT - CODE_HEIGHT - BUTTON_HEIGHT - 40)
/ 2

// Run the application ;-)
Application.Run(new InheritanceDemo)

import System
import System.Threading
import System.ComponentModel
import System.Drawing
import System.Windows.Forms
import Microsoft.Vsa
import Microsoft.JScript
import Microsoft.JScript.Vsa
import System.Reflection


// The interface used by the customisation code
// that the user writes
interface ICustomisation
{
function Process(context : ContextObject) : String
}

// The context object that each thread passes to the customisation
class ContextObject
{
var id : int

function ContextObject(id : int)
{
this.id = id
}

// This is the only useful thing that Context does
// (Put your own useful stuff in this class)
function get Info() : String
{
return "This is object " + id
}
}

// Represents a worker thread.
// Just calls the customisation code repeatedly until told
// to stop
class WorkerThread
{
var id : int

@if(@early_bound_demo)
var customisation : ICustomisation
@else
var customisation
@end

var output : TextBox

var running : boolean

@if(@early_bound_demo)
function WorkerThread(id : int, customisation : ICustomisation, output :
TextBox)
@else
function WorkerThread(id : int, customisation, output : TextBox)
@end
{
this.id = id
this.customisation = customisation
this.output = output
running = true
}

function Go()
{
var ob = new ContextObject(id)

while (running)
{
@if(@early_bound_demo)
output.Text += customisation.Process(ob) + "\r\n"
@else
try
{
output.Text += customisation.GetType().InvokeMember("Process",
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
null, customisation, [ob]) + "\r\n"
}
catch(e : Exception)
{
output.Text += e + "\r\n\r\n"
}
@end
output.SelectionLength = 0
Thread.Sleep(int(Math.random() * 1000))
}
}
}

class InheritanceDemo extends Form
{
var txtCode : TextBox
var cmdStart : Button
var cmdStop : Button
var txtOutputs : TextBox[]
var workers : WorkerThread[]
var engine : IVsaEngine

var errors = []

function InheritanceDemo()
{
Initialise()
}

function Stop(o : Object, e : EventArgs)
{
if (workers != null)
{
for (var i in workers)
{
workers[i].running = false
}
}

engine.Reset()
}

function Run(o : Object, e : EventArgs)
{
var items : IVsaItems
var src : IVsaCodeItem

@if(@early_bound_demo)
var customisation : ICustomisation
@else
var customisation
@end

for (var x in txtOutputs)
{
txtOutputs[x].Text = ""
}

try
{
engine = new VsaEngine();
engine.RootMoniker = "Inheritance://demo/"
engine.Site = new VsaSite(this)
engine.InitNew()
engine.RootNamespace = "Inheritance"

engine.SetOption("fast", true);

items = engine.Items
items.CreateItem("mscorlib.dll", VsaItemType.Reference,
VsaItemFlag.None)
items.CreateItem("Inheritance.exe", VsaItemType.Reference,
VsaItemFlag.None)

src = IVsaCodeItem(items.CreateItem("src", VsaItemType.Code,
VsaItemFlag.None))
src.SourceText = txtCode.Text
}
catch(err1 : Exception)
{
MessageBox.Show("Error initialising engine: " + err1, "Error")
}

try
{
errors.length = 0
engine.Compile()
if (errors.length == 0)
{
engine.Run()

@if(@early_bound_demo)
customisation =
ICustomisation(engine.Assembly.CreateInstance("Inheritance.MyClass"))
@else
customisation =
engine.Assembly.CreateInstance("Inheritance.MyClass")
@end

workers = new WorkerThread[12]
for (var i = 0; i < 12; i++)
{
workers[i] = new WorkerThread(i, customisation, txtOutputs[i % 4])
new Thread(workers[i].Go).Start()
}
}
else
{
MessageBox.Show(errors.join("\n"))
}
}
catch(err2 : Exception)
{
MessageBox.Show("Error running engine: " + err2, "Error")
}
}

function Initialise()
{
this.SuspendLayout()

txtCode = new TextBox
txtCode.AcceptsReturn = true
txtCode.AcceptsTab = true
txtCode.Anchor = AnchorStyles.Top | AnchorStyles.Bottom |
AnchorStyles.Left | AnchorStyles.Right

txtCode.Location = new System.Drawing.Point(8, 8)
txtCode.Multiline = true
txtCode.Name = "txtCode"
txtCode.ScrollBars = ScrollBars.Both
txtCode.Size = new System.Drawing.Size(CODE_WIDTH, CODE_HEIGHT)
txtCode.Text = "\
//\r\n\
// Running the " + (@early_bound_demo ? "early" : "late") + " bound
demo\r\n\
//\r\n\
\r\n\
class MyClass" + (@early_bound_demo ? " implements ICustomisation" : "") +
"\r\n\
{\r\n\
\tfunction Process(context : ContextObject) : String\r\n\
\t{\r\n\
\t\treturn \"You've got script! \" + context.Info\r\n\
\t}\r\n\
}\r\n"

cmdStart = new Button
cmdStart.Anchor = AnchorStyles.Bottom | AnchorStyles.Left
cmdStart.Location = new System.Drawing.Point(8, CODE_HEIGHT + 16)
cmdStart.Name = "cmdStart"
cmdStart.Size = new System.Drawing.Size(BUTTON_WIDTH, BUTTON_HEIGHT)
cmdStart.Text = "Start"
cmdStart.add_Click(Run)

cmdStop = new Button
cmdStop.Anchor = AnchorStyles.Bottom | AnchorStyles.Left
cmdStop.Location = new System.Drawing.Point(BUTTON_WIDTH + 16,
CODE_HEIGHT + 16)
cmdStop.Name = "cmdStop"
cmdStop.Size = new System.Drawing.Size(BUTTON_WIDTH, BUTTON_HEIGHT)
cmdStop.Text = "Stop"
cmdStop.add_Click(Stop)

txtOutputs = new TextBox[4]
var xCoords = [8, OUTPUT_WIDTH + 16, 8, OUTPUT_WIDTH + 16]
var yCoords = [OUTPUT_START, OUTPUT_START,
OUTPUT_START + OUTPUT_HEIGHT + 8, OUTPUT_START + OUTPUT_HEIGHT + 8]

for (var i = 0; i < 4; i++)
{
txtOutputs[i] = new TextBox
txtOutputs[i].Anchor = AnchorStyles.Bottom | AnchorStyles.Left
txtOutputs[i].Location = new System.Drawing.Point(xCoords[i],
yCoords[i])
txtOutputs[i].Size = new System.Drawing.Size(OUTPUT_WIDTH,
OUTPUT_HEIGHT)
txtOutputs[i].Multiline = true
txtOutputs[i].ScrollBars = ScrollBars.Both
}

this.ClientSize = new System.Drawing.Size(FORM_WIDTH, FORM_HEIGHT)
// this.Controls.AddRange([txtCode, cmdStart].concat(Control[](txtOutput
s)))
this.Controls.AddRange([txtCode, cmdStart, cmdStop,
txtOutputs[0], txtOutputs[1], txtOutputs[2], txtOutputs[3]])
this.Name = "Inheritance Demo"
this.Text = "Inheritance Demo"

this.ResumeLayout(true)
}
}

// Simple site that just records errors by pushing them
// back to the host.
// In a C# application, your main class could simply
// implement IVsaSite, but in JScript we have to extend
// a base class because the interface uses output parameters,
// which JScript does not support.
class VsaSite extends BaseVsaSite
{
var host : InheritanceDemo

function VsaSite(host : InheritanceDemo)
{
this.host = host
}

function OnCompilerError(err : IVsaError) : boolean
{
// ignore warnings
if (err.Severity != 0)
return true

host.errors.push(err)
return true;
}
}

Frederic Claux

unread,
Jul 13, 2001, 3:44:10 AM7/13/01
to
Peter, what can I say ?
Dieu te protège.

--
Frederic Claux

"Peter Torr (MS)" <pt...@microsoft.com> a écrit dans le message news:

eQ1aeciCBHA.1644@tkmsftngp05...

Peter Torr (MS)

unread,
Jul 13, 2001, 8:56:42 PM7/13/01
to
"Frederic Claux" <nospam_f.claux@nospam_techbase.fr> wrote in message
news:Og0B$$2CBHA.1480@tkmsftngp05...

> Peter, what can I say ?
> Dieu te protège.

Something in English? :-)

AltaVista translated it as:

God you protects

but that sounds pretty good so I'll take it!

Willy Denoyette

unread,
Jul 14, 2001, 2:13:49 PM7/14/01
to
May God protect you, or God bless you.

Willy.

"Peter Torr (MS)" <pt...@microsoft.com> wrote in message news:uRSll$$CBHA.1548@tkmsftngp02...

0 new messages