Script#

Script# brings the C# developer experience (programming and tooling) to Javascript/Ajax world. This post shares a project for enabling script authoring via C#...

Script# brings the C# developer experience (programming and tooling) to Javascript/Ajax world. Yep, I am finally publicly sharing a spare time project I've been working on the side in an off and on manner for some time now.

A Better Scripting Environment

The fundamental goal was to improve the state of the art in scripting. This goes way beyond the usual things that come to mind at first thought: compile-time checking, and intellisense or statement completion. I do think these are super-useful, and would be valuable in and of themselves. As we worked on Atlas we were also thinking of a great tools experience, and we explored different approaches and technologies for achieving this. Script# is a prototype of one such exploration. It attempts to address some programming environment requirements:

  • A clean language with the natural constructs. Today with script, you can go a long ways in simulating OOP (classes, interfaces, inheritance etc.), but the simulations are thrown at the face of the developer. Various C# constructs such as properties, events, and syntax for defining inheritance go a long way in making the code readable. Similarly modifier keywords like public vs. protected vs. internal, sealed vs. virtual etc. help define a better object model. All of this can be brought into the scripting world.
  • Easier refactoring and exploration. Script development could benefit immensely from the refactoring, and class browsing support already present in the IDE and in tools such as .NET Reflector. Both lend themselves to having a more manageable code base over time.
  • Ability to generate documentation. Again doc-comments from C# and the existing infrastructure could be leveraged here.
  • Ability to customize the script code easily. For example, I'll show debug vs. release and minimization below. The same idea could apply to building a version of the script that had more error checking or logging built in when you do need to run diagnostics. The approach could also be used to include instrumentation for the purposes of profiling, measuring code coverage, etc. Another interesting aspect of this project is that it will be able to generate script catering to multiple script profiles such as the current Javascript language, as well as Javascript 2 when it appears.

Demonstration

I'll use the Ajax version of the timeless Hello World scenario to illustrate the model. Imagine a simple page with textbox, button and label:

<input type="text" id="nameTextBox" />
<input type="button" id="okButton" value="OK" />
<span id="helloLabel"></span>
Now I want to write the script for this page to add some UI logic. I'll create HelloWorld.cs with the following code to handle the button click, extract the name entered into the textbox, make a request using XMLHttp and finally display the result in a label.

using System;
using ScriptFX;
using ScriptFX.UI;

namespace HelloWorld {

    public class HelloWorldScriptlet : IScriptlet {

        private Button _okButton;
        private TextBox _nameTextBox;
        private Label _helloLabel;

        private XMLHttpRequest _request;

        public void Start() {
            _okButton = new Button(Document.GetElementById("okButton"));
            _nameTextBox = new TextBox(Document.GetElementById("nameTextBox"));
            _helloLabel = new Label(Document.GetElementById("helloLabel"));

            _okButton.Click += new EventHandler(OnOKButtonClick);
        }

        private void OnOKButtonClick(object sender, EventArgs e) {
            Callback completedCallback = new Callback(this.OnRequestComplete);

            _request = new XMLHttpRequest();
            _request.Onreadystatechange = Delegate.Unwrap(completedCallback);
            _request.Open("GET", "Hello.axd?name=" + _nameTextBox.Text, /* async */ true);
            _request.Send(null);
        }

        private void OnRequestComplete() {
            if (_request.ReadyState == 4) {
                _request.Onreadystatechange = null;

                string greeting = _request.ResponseText;
                _helloLabel.Text = greeting;
            }
        }
    }
}
Basically this shows a couple of super-simple class HelloWorldScriptlet class. It's a pleasure to write it in C#. Now its time for some Script# magic.
ssc /ref:sscorlib.dll /ref:Script.ScriptFX.Core.dll /debug /out:HelloWorld.js HelloWorld.cs
Running the Script# compiler (ssc.exe) generates HelloWorld.js which looks like this:
Type.registerNamespace('HelloWorld');

////////////////////////////////////////////////////////////////////////////////
// HelloWorld.HelloWorldScriptlet

HelloWorld.HelloWorldScriptlet = function Scenarios_HelloWorldScriptlet() {
}
HelloWorld.HelloWorldScriptlet.prototype = {
    _okButton: null,
    _nameTextBox: null,
    _helloLabel: null,
    _request: null,
    
    start: function Scenarios_HelloWorldScriptlet$start() {
        this._okButton = new ScriptFX.UI.Button(document.getElementById('okButton'));
        this._nameTextBox = new ScriptFX.UI.TextBox(document.getElementById('nameTextBox'));
        this._helloLabel = new ScriptFX.UI.Label(document.getElementById('helloLabel'));
        this._okButton.add_click(new Delegate(this, this._onOKButtonClick));
    },
    
    _onOKButtonClick: function Scenarios_HelloWorldScriptlet$_onOKButtonClick(sender, e) {
        var completedCallback = new Delegate(this, this._onRequestComplete);
        this._request = new XMLHttpRequest();
        this._request.onreadystatechange = Delegate.unwrap(completedCallback);
        this._request.open('GET', 'Hello.axd?name=' + this._nameTextBox.get_text(), true);
        this._request.send(null);
    },
    
    _onRequestComplete: function Scenarios_HelloWorldScriptlet$_onRequestComplete() {
        if (this._request.readyState == 4) {
            this._request.onreadystatechange = null;
            var greeting = this._request.responseText;
            this._helloLabel.set_text(greeting);
        }
    }
}

HelloWorld.HelloWorldScriptlet.registerClass('HelloWorld.HelloWorldScriptlet', null, ScriptFX.IScriptlet);
Notice how the class is converted into its Javascript equivalent: a function, and methods on its prototype. Further, notice how this automatically generates calls to register the function as a class. The compiler provides a nice natural model for declaring the inheritance hierarchy. Other things to call out are conversion of of C#-based event and property accesses with Javascript simulations. Essentially, let the compiler do the hard work, so you don't have to mentally work against an OOP simulation. Finally, since the compiler was passed the /debug flag, it provides a name to each method (anonymous methods aren't friendly in the debugger)... again this happens automagically. There is a lot more to show that a simple sample doesn't get across in terms of the capabilities of the conversion.

The generated code can now be used in the page via a regular <script> tag.
<script type="text/javascript" src="sscorlib.js"></script>
<script type="text/javascript" src="ssfxcore.js"></script>
<script type="text/javascript" src="HelloWorld.js"></script>
<script type="text/javascript">
ScriptFX.Application.Current.run(new HelloWorld.HelloWorldScriptlet());
</script>
The Script# compiler can optionally generate an assembly containing the .js file as a resource. An associated server control can then use the ASP.NET WebResources feature to include the scriptlet into the page in a simpler manner.
ssc /ref:sscorlib.dll /ref:Script.ScriptFX.Core.dll /debug /assembly:HelloWorld.dll /out:HelloWorld.js HelloWorld.cs
<nStuff:Scriptlet runat="server"
    ScriptAssembly="HelloWorld" ScriptletType="HelloWorld.HelloWorldScriptlet" />
The compiler has the notion of debug and release builds.
ssc /ref:sscorlib.dll /ref:Script.ScriptFX.Core.dll /minimize /out:HelloWorld.js HelloWorld.cs
Running the compiler without /debug and with /minimize produces a release build as shown below (I've intentionally added some line breaks for display purposes):
Type.registerNamespace('HelloWorld');
HelloWorld.HelloWorldScriptlet=function(){}
HelloWorld.HelloWorldScriptlet.prototype={$0:null,$1:null,$2:null,$3:null,
start:function(){
this.$0=new ScriptFX.UI.Button(document.getElementById('okButton'));
this.$1=new ScriptFX.UI.TextBox(document.getElementById('nameTextBox'));
this.$2=new ScriptFX.UI.Label(document.getElementById('helloLabel'));
this.$0.add_click(new Delegate(this,this.$4));},
$4:function(sender,e){
var $2=new Delegate(this,this.$5);
this.$3=new XMLHttpRequest();
this.$3.onreadystatechange=Delegate.unwrap($2);
this.$3.open('GET','Hello.axd?name='+this.$1.get_text(),true);
this.$3.send(null);},
$5:function(){
if(this.$3.readyState==4){
this.$3.onreadystatechange=null;
var $0=this.$3.responseText;
this.$2.set_text($0);}}}
HelloWorld.HelloWorldScriptlet.registerClass('HelloWorld.HelloWorldScriptlet',null,ScriptFX.IScriptlet);
As you'll notice all insignificant whitespace has been trimmed out. Furthermore, there is minimization of identifiers (which are amongst the biggest contributors to script size) with identifiers named as $0, $1 etc. What is super exciting is that the Script# compiler can use all the information present in C# source code to allow it to maximize the minimization. This includes information about which members are internal/private vs. which ones are public. For example, the _okButton member of the class is now $0 and the OnRequestComplete method is $5.

Beyond generation of script in a smarter way, Script# helps improve the script authoring model within the IDE. Despite programming the DOM for several months now, I still need a browser window constantly open to browse MSDN reference documentation on the DOM. With Script# here is what I get:




Specific things to notice are the intellisense and statement completion popups and tooltips offered by the C# editor, as it reflects on the sscorlib assembly referenced by this project.

Essentially, I've introduced the notion of a Script# class library project, and associated msbuild targets file and task for integrating the experience into Visual Studio 2005. Building builds both a .dll assembly, and an associated .js file, that you can now deploy with your web project.

I have put together a 10 min video of this scenario. This is an experiment in itself with me putting out a video to get some concepts out (so feedback appreciated on this as well).

How does it work?

Essentially the Script# compiler is a C# compiler that generates Javascript instead of IL. A key driving goal of the design is to produce readable Javascript that you may have authored yourself, and would be ok deploying into real apps. Hence the translation works at the C# level, as opposed to converting from IL to script, and the converter doesn't add any levels of abstraction itself.

There are a set of C# things that don't make sense (eg. lock, unsafe etc.) and set of things I don't support yet (like generics). The converter does however provide support for key C# patterns such as foreach, delegates, and things like Debug conditionals. The associated class library (sscorlib, equivalent of mscorlib) is also tuned to Javascript. It doesn't contain the same stuff as mscorlib does. The approach I have taken is not to create a converter that converts an arbitrary existing application written in C#, and convert it to Javascript with something like a winforms abstraction layer. Instead, like Atlas, the idea behind Script# is oriented at providing an engineering approach and superior environment to developing applications using HTML/CSS and Javascript in a more productive, scalable and maintainable manner.

There is a small set of Javascript specific things (specifically closures and more functional style programming) that aren't supported in the conversion. I think there are equivalent alternatives, but I'd be interested in feedback nonetheless. The implementation does allow you to hand-code some Javascript and expose it to the C# code in the form of assembly metadata. This provides a nice out for incorporating something that exists already, or something that needs more hand tuning. I'll go into this some in a later post.

Some historical context and downloadable bits...

A number of people have wondered if our OOP-based type system in Atlas was a precursor to enabling C#-based development in the browser, and I'll answer to that directly now. The idea of using C# to author script emerged at almost the same time we started actively writing script, and I missed everything I took for granted from C#. In December, while on vacation, I decided to finally get down to writing a compiler that could enable this.

Since then, the work has proceeded to a point where it can be used to generate useful script. I was planning on posting an announcement just last week. It's very coincidental that the folks at Google have been thinking along similar lines. I guess I should have posted this stuff a few days back :-) Regardless, I have an initial release ready... You can download the Script# compiler along with the sample. Keep in mind it is raw in quite the literal sense (and if you do try it, make sure your code compiles as valid C# first). I'll need some more time to get it to a crisper state, providing better integration into Web projects, and simplifying some key C# scenarios. This will happen over time as this is a spare time prototype. In the meantime, the download will give you a sense of the experience. I'm definitely open to feedback, and look forward to comments.

Scripting Challenges and Future Vision

Recently, I posted my wish list for the browser and scripting world, and I wanted to speak to things relating and coming together from an overall vision perspective. At the end of the day, the end result of translation is still script. There are still some unsolved challenges in terms of a limited runtime environment in the browser, cross-browser differences etc. Furthermore translation-based models add a wrinkle to the debugging experience. Script# provides a tool to incrementally improve script authoring in the short term. We want to provide great tools and frameworks that target native scripting as it exists today with things like Atlas. Longer term, the real solution for rich Web applications is a combination of WPF/E (as shown at MIX06), and a cross-platform CLR that can be hosted in the browser allowing direct authoring and execution of managed code and fully benefiting from the model.


[ Tags: | | | | ]
Posted on Monday, 5/22/2006 @ 4:11 PM | #Script#


Comments

158 comments have been posted.

David Taylo

Posted on 5/22/2006 @ 4:45 PM
Hi Nikhil,

I asked/begged for this directly from you at the 2005 PDC, and ever since GWT was released a few days ago, I have been meaning to ask for your views on it.

It brings a simle to my face to know you have been working on this.

I spent a bit of time over the weekend looking at GWT, and playing with the demos. My initial thougt was that I could probably write something more useful with GTW than with Atlas using JavaScript, just because I know C#/Java really well. Of course, using the ASP.NET controls that come with Atlas and the control pack (UpdatePanel, etc), Atlas is really simpe, but my head is just not in the JavaScript space.

However after looking at GWT, it is way to code centric - ie no templating, no real integration with a web intrastructure. I give GWT 100% for the ability to write code in Java, while 0 points for everything else. While with Atlas and ASP.NET combined, you are really talking about a much more well thought out and powerful platform. Of course, if you can really allow us to program it in C#, that is a great thing.

Thanks!

Steve

Posted on 5/22/2006 @ 5:06 PM
I think they found mecca after all!

Is this why you have been so quiet lately Nikhil? :)

Fnustle

Posted on 5/22/2006 @ 5:28 PM
Ugh. It has been my experience that it is the less talented developers who are enamored with trying to shoe-horn foreign environments into their cozy little world. Same goes with databases and crap like LINQ. I enjoy javascript more than C# because I am much more productive in it, and 90% of that productivity can be attributed to the ease of data manipulation using associative arrays. C# is quite verbose when it comes to manipulation of data structures, even with generics.

Different domains benefit from different languages. There will never be an environment to rule them all. Give it up.

Nikhil Kothari

Posted on 5/22/2006 @ 5:40 PM
Thanks for the first few comments. I sort of expected the comments at both ends of the spectrum... one of the reasons I am sharing this, is in fact to get feedback on the model, and understand from the opinions of others as to where to take this next. This is great... please keep the feedback coming!

I was also expecting to hear something about OOP vs. Functional style programming... perhaps those comments will also surface in a bit.

I will mention that the HelloWorld sample is in some sense unsuited to the technology... its much simpler to write HelloWorld in script; I admit it. Quick and dirty experimentation is also quicker in script (atleast now that I feel comfortable in that environment as well). However, I think there is something to having an environment better than what you get with today's script the moment one tries to write complex apps, or frameworks (in my opinion). I initially had a much more realistic sample to get some of this across, but alas that would be too complex for an intro post, and I was recommended by folks who reviewed my post to pick something simpler, so I don't completely loose folks. So to sum it up, I think you'll want to extrapolate a bit from where this sample ends, and think about programming in the large.

Barry Kelly

Posted on 5/22/2006 @ 5:52 PM
Hey Nkhil! I've had an idea for something like this for some time now, but I was far too busy to take time out to implement it as anything releasable. I called it 'JSafe': the idea was adding compile-time type-safety (i.e. static typing) to JavaScript.

I implemented a lexer, parser and code generator that got far enough to read typed 'var' declarations (along the lines of the new JavaScript, and similar enough to JScript), and type-checked expressions that used constants and these declared variables. That was as far as I could go in a weekend or two. Was far to busy with real work to pursue it with the energy it needed.

Now, nearly a year later, I find people from MS and Google coming out with real-world implementation of that idea!

A key part of my implementation idea was to permit quoted blocks of javascript to be outputted, in both statement and expression contexts (for you, you'd have to include declaration contexts too).

Keep up the work and don't mind the nay-sayers who are happy with JavaScript as it is. Those of us who work with static languages and appreciate their aid recognize that this is a useful tool for us. It isn't like it's forced down anyone's throat.

(Oh, and are you aware that the "Name" and "Email Address" text boxes above are white text on a yellow (green? I'm colour-blind) background in Firefox, and are very hard to read?)

Josh

Posted on 5/22/2006 @ 5:53 PM
This is cool stuff! Any chance of making it open source on codeplex?

Dimitri Glazkov

Posted on 5/22/2006 @ 7:23 PM
When I read the title, I got really excited -- I thought you finally wrote a full-fledged JS CLR compiler. But it's the opposite. Oh well.

But seriously, you'd take C# over JS? Really?

C# is like a farm tractor: it's got bare metal plate for a seat, looks ugly, smells funny, but eventually gets the job done. On the other hand, JS is like a Ferrari: it's beautiful, elegant, comfortable to work with, and yes, dangerous (potentially lethal) for a novice.

Am I being too subjective?

Sahil Malik

Posted on 5/22/2006 @ 7:29 PM
Nikhil,

I was at an Ajax Conference recently and I voiced my opinion about a dire need for such a platform.

Damn - you're way too cool.

SM

Nikhil Kothari

Posted on 5/22/2006 @ 7:52 PM
Dimitri, three things:
- I think you need tools that get the job done most of the time. The Lethal devices are good for fun! :-)
- The CLR version of JS would require new bits on the client, which unfortunately becomes an adoption obstacle for a small-scale project like I am doing. As mentioned in the post, we are working on that end as well... though its more about any .NET language, and not specifically Javascript.
- The full-fledged JS CLR compiler would look more like JScript.NET or Javascript 2 (if I understand what you're after), rather than Javascript as it exists today, so you'd be giving up some of that scripty touch and feel as well.

Sahil, Thanks! :-)

Dimitri Glazkov

Posted on 5/22/2006 @ 8:23 PM
Appreciate the quick response. I am rapidly spiraling out of topic, but I think you need tools that get the job done _and_ are fun to work with. I can't help but think Rails vs. ASP.NET -- or maybe I am doing this on purpose to start a whole different conversation :)

Dimitri Glazkov

Posted on 5/22/2006 @ 8:28 PM
And one more, before I forget. I gave it some more thought and I think the idea of Script# and GWT is abominable. It creates an abstraction layer where the developer doesn't need it.

All this will do is create an opportunity for abuse. If you shield the developer from learning JS and knowing how it works, you will only get loads of insanely crappy code in return. It will work (some|most of the time), but it will cause countless hours, headache and induced hatred of technology of those who come behind.

Manuel Abadia

Posted on 5/22/2006 @ 10:54 PM
IMHO script# is a great idea, but I think Microsoft is falling behind in the web 2.0 competition. You're doing this in your free time while google seems to have more people doing GWT. Also Atlas is evolving nicely but slowly compared with other AJAX libraries... I don't know how many people work on the different asp.net/web related projects that Microsoft have at the moment but maybe it's time to hire more people?

I love the idea of a cross-platform CLR that can be hosted in the browser!

AsbjornM

Posted on 5/22/2006 @ 11:47 PM
I think this is spot-on, I like the Idea about GWT, and was hoping someone could do something similar for C#, I will test this to see what I can do of it. I am not an js-head, but I need to do js because of ajax, and anything that can help making the transition here is great.

Host CLR in browser?, uhm, what about firefox, opera etc?, perhaps in the next decade or so.

Can Erten

Posted on 5/23/2006 @ 12:38 AM
This is what I was expecting from microsoft after the lunch of gwt. So I can use type checked, syntax checked javascript. Ah that's very nice and cool. I really appreciate that. I am looking forward to extend that project in a community site.

can.

Hermann Klinke

Posted on 5/23/2006 @ 1:00 AM
Nikhil, Script# is great. I've been planning to create something similar reading the IL instead of the C# code. I am wondering if Script# supports overloaded methods, calling of base methods and more of that OOP goodness. I've am working on framework (80% done) in javascript that makes javascript 100% object oriented (namespaces, abstract & sealed classes, inheritance, interfaces, access modifiers, real properties, events, enums; overloadable, virtual, abstract, static and stronly typed methods and constructors that can call base methods when overridden; and even assemblies) and it would be very useful if you provided an interface (provider) to your javascript generation engine, so that you could plug your own style. That way you could make Script# generate Javascript 2 (when it's out) or other implementations such as mine. What do you think?

http://www.paketim.com

Posted on 5/23/2006 @ 2:10 AM
There are couple of spare time projects on Ajax and Javascript that excite me. But this is the most exiting project i've heard.

RichB

Posted on 5/23/2006 @ 2:37 AM
Fnustle - The problem is that the majority of developers in the world are "less talented". The multi-disciplinary nature of AJAX/Web 2.0 development is an insurmountable barrier to most developers out there.

Perhaps you'd be surprised how many ASP.Net web developers rely on 3rd party controls (grids etc) and have absolutely no idea how they would actually go about building these controls themselves - both in terms of the client side Javascript/CSS/HTML and in terms of the server side WebControl infrastructure.

So we need to find a way to get the masses who are unable to gain the multi-disciplinary skills to write modern AJAX web apps.

Sure Javascript development is faster than C# development (for Javascript <50K) and that Javascript is in some ways a much more advanced language than C# - covering all the functional-style semantics that Nikhil eluded to. But that doesn't help the Mort's out there.

Nick

Posted on 5/23/2006 @ 5:14 AM
Nikhil Keep Rocking ...

Really great step towards bringing ease to developers door step. Unfortunately the sample files don't seems to work properly as indicated by 10 minutes marvellous video. Instead resulted with following message
[Error 39 The type 'string' exists in both 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll' and 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\site\95a671b8\fff3cac6\assembly\dl3\3dbf1b45\00daa161_5f7dc601\sscorlib.DLL' C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\Site\Hello.ashx 18]

Nick

RichB

Posted on 5/23/2006 @ 5:34 AM
Nikhil, I suppose an alternative approach would be an IL->Javascript translator using MSR's Phoenix project. As IL maps almost 1:1 with C# v1 I can't envisage much in the way of semantic loss.

Coleman

Posted on 5/23/2006 @ 5:58 AM
How does/will this play with Atlas and it's various bindings, etc. It looks like you gen out the XmlHttpRequest object directly in your code?

Overall, I think this is awesome. Despite what some will say, ECMAscript is a pain to deal with. The notion of the CLR on various platforms and browsers... way too cool... many will complain... but like I've said in the past... the people that hate MS the most... are the ones that want to be MS the most... I've looked at the GDK, and it looks pretty nice. We're using Atlas now on a couple enterprise apps and are mainly using the UpdatePanel letting the toolkit and other pieces flush out. It will be nice when finished and incorporated in VS. I think where you're headed is in the right direction, but wondering if it will be absorbed into the VS mix and how soon...? And back to my orginal question... how does it fit in with Atlas.

MikeParsons

Posted on 5/23/2006 @ 6:02 AM
Great Job Nikhil!

Interesting to see the various approaches about auto-generating JavaScript code from traditional development environments . Script# and the GWK will no doubt appeal to those individuals who disregard JavaScript and the Browser as "real development tools". While I applaud your efforts here, I think we (as an industry) are missing out on a fundamental opportunity here to create an entirely new development experience for creating browser-based applications. While Microsoft and other vendors have made some great advances in providing better tools for developers, they come with a steep learning curve and require quite an investment to do anything useful. We still seem to be caught in this spiral of making cool technology for developers at the expense of productivity and end-user usefulness. The abstractions provided by the tools and the associated frameworks, etc still require pretty intimate knowledge of the the various bits and pieces required to actually create something useful.

While creating more abstractions on top of complexity (i.e. javacript, DOM, etc) can initially be viewed as a good thing, this approach aften lends itself to becoming more complex over time as you need to add more and more code to support the "full set" of underlying language/runtime features. I am sure you are already seeing this with ATLAS, etc and you will no doubt see it with Script#. By trying to "mimic" the behavior/functionality of the C# language and CLR contructs within the browser, you set yourself up for the demands that will inevitably come from this ... how do I support more and more of C# and the CLR within the browser? You keep adding more and more functionality to adress these concerns all the while making your solution more and more complex and as a result, make consumption of your technology harder and harder.

The price to be paid for this is that we spend less and less time on "real innovation" and toil away at trying to make incremental benefits to the overall developer experience. Inspite of the advances in tools/frameworks over the past decade, have we "really" seen any major breakthroughs in terms of being able to deliver more compelling features to end users any faster? I would argue that we have seem marginal benefits at best. Creating something useful for end users still takes a long time, requires detailed knowledge of a large set of tools and technologies and are a pain to extend and customize.

Maybe it's time to fundamentally rethink how we build applications and the tools we use to construct them. Unfortunately, Script# and/or the GWT ties us to past and sometimes you have to forget the past and pave a whole new future.

Alb

Posted on 5/23/2006 @ 7:27 AM
Seems to be a grate job!

Just for Information, if you do a ScreenCast (e.g. with Window Media Encode) you can improve the visual quality a lot if you disable ClearType during the Screencast.

I you disable ClearType you also should not use ClearType optimized Fonts like Consolas or Segeo UI. With the XP Standard Fonts and disable ClearType you get sharp Screencasts (i twiddle a lot wihtin the screencast options, but nothing help ... only disabling ClearType).

rodrigo

Posted on 5/23/2006 @ 7:29 AM
Hi..This is very cool stuff. I was just reading about GWT and thinking when someone would do something similar to it in C #.
I will be testing your framework and giving you feedback.I Hope to see more complex examples soon... like accessing a database, returning a class from an AJAX method.

Darren Kopp

Posted on 5/23/2006 @ 8:57 AM
All I have to say is that... I LOVE YOU!!! This is an amazingly simple (well, from my end, probably not yours :D) solution to a big problem. Thank you so much.

Kevin Dente

Posted on 5/23/2006 @ 9:40 AM
Nikhil,
Very cool stuff. Interesting that you and the Google guys took very similar approaches and announced them at almost the same time.

Can you comment on the longer term intent for this project? Is it simply a bit of after-hours, experimental, proof-of-concept code? Or is the goal that it be rolled into the Atlas project?

Nikhil Kothari

Posted on 5/23/2006 @ 10:14 AM
Thanks all so far. Some specific responses...

Hermann: please contact me offline via the contact link on the top-right about your ideas - I'd like to understand the OOP simulations you are building. Regarding the idea of creating extensibility for generators, I haven't thought a whole lot about public extensibility just yet, but I have been thinking about this feature atleast since I saw a Javascript 2 presentation.

Nick: Sounds like you are referencing both sscorlib.dll and mscorlib.dll - both have a System.Object - sscorlib is what you want. The Readme.txt has some notes on how you remove the implicit mscorlib reference. The project files included in the vs template and sample also have this setting.

RichB: IL -> Javascript - I optimized for source level matching, since debugging matching source in script allows much easier mapping of debugging results back to C# source. I think debugging at the IL level is an interesting thought, but I think debugging at some point or the other needs to be done without layers of indirection. That said, I think there is some value in IL -> Javascript investigation. I know of one project that is doing that, but its very early.

Coleman/Kevin: Still need to figure out the exact Atlas story and how these two unify over time. As and when that happens, I am sure I'll blog about it.

Alb: Thanks for the tip. Pretty sure I didn't have cleartype turned on...

Mike Parsons: I agree Script# and these types of technologies are more focused on making the available technologies today more approachable/better. They don't "really" innovate. As mentioned in the post there is work going on that I am also involved in for getting things like the CLR running in the browser, and creating a better programming environment overall. Also read my wish list for the browser and scripting in general, for my ideas and thoughts on "real" innovation. I think we live in a world where there is a lot of value in incremental enhancements, esp. on the development side of things such that the end results can run without any adoption blockers.

Hermann Klinke

Posted on 5/23/2006 @ 10:40 AM
Hi RichB, what is this "MSR's Phoenix project" you are talking about? I tried googling it, but did not find any information on it. Could you please give us a link?

Alex Osipov

Posted on 5/23/2006 @ 10:40 AM
Nikhil - this is pretty great project. I really think it could benefit from being posted on Codeplex or even integrated as part of Atlas development. I think I would have definitely used something like this to write Atlas-based code.

The most welcome feature is intellisense for DOM, I too have been using DOM (a lot) for a few months but from time to time have to use a reference. Now if the code completion only worked on real JS code rather than C#.

Something that is missing in Script# (after spending a few minutes with it) that gets to the root of one of the problems with such an approach is Script# does not contain mechanism for testing functionality on the client side. A lot of javascript (for whatever reason) is scattered with ifs testing for special features (e.g. if (typeof(el.innerHTML) == 'undefined'))), the few minutes I spent using Script# did not seem as if this was possible. It would be important to have this feature to support the dynamic scripting nature of JS and add complexity to the C# side. There will be a lot of complexity bringing over such a "loose" language into a strict rigid structure of C#. I am really not sure if there is the a right balance between the C# and JS. XAML really seems to be the next evolutionary step for browsers but I guess everyone is trying to make things work with current technologies.

With this model I also see beginners and advanced people alike losing track of what they are working on and attempting to mix server side with client side. At this point you begin to lose track of what is happening, where and when. From first glance I guess transparency is great but there will be a lot of conflicts and lots of FAQs...

Have you figured out a way to use anonymous methods in C# and in JS? I tried experimenting here but found out that delegates aren't supported. Automatic destructors would also be a welcome addition (this would have to be an extra layer of JS).

Other than the problems with the model I think this is a great attempt on your part to experiment and involve the community. This experiment also missed an important problem that is at the root of this model, the communication between the server and the client side. I have not spent any time on this but it seems to only support using XHR to access web methods. I thhink in order for a project such as this to be successful as a product it will need to elegantly deal with this issue as well as the model itself. While an Atlas approach such as creating proxy methods for web methods is great it would not really integrate JS and C# development on server and client side. Everything seems to skirting around this issue.

As a side note, a combination of your javascript utilities project and Script# can definitely help to optimize the resulting javascript.

Great work!

Regards,
Alex Osipov

Joel Rumerman

Posted on 5/23/2006 @ 10:57 AM
Nikhil et al.,

I think that Script# is a fantastic idea and that an exploration into a tool that abstracts the developer away from the subtlies and complexities of JavaScript is a worthy undertaking. Making clientside programming more "approachable" for the less experienced JS developer is a good start. Something like 80% of the developers out there are used to the server side model. Whether it's php, asp.net, jsp, asp, perl, etc.., its always been about the server. Finally, a better clientside development environment.

And for those who claim that "it creates an abstraction layer where the developer doesn't need it." They forget the days when people said the same about functional and OOP programming. If we adhered to this point of view we'd all still be programming in assembly language against the CPU stack and needing to know about regsiters and memory addresses!

I'm not claiming that Script# is the answer to clientside programming, but the exploration of a better programming experience is.

Just my 3 cents.

Steve

Posted on 5/23/2006 @ 11:00 AM
I am shocked by some of these responses. I don't want to sound negative, but I am bothered by the negativity I see here in regards to C#.

"C# is like a farm tractor: it's got bare metal plate for a seat, looks ugly, smells funny, but eventually gets the job done. On the other hand, JS is like a Ferrari: it's beautiful, elegant, comfortable to work with, and yes, dangerous (potentially lethal) for a novice."

"So we need to find a way to get the masses who are unable to gain the multi-disciplinary skills to write modern AJAX web apps."

? why do you assume people who use these tools do not know this. Actually, you don't know. This statement is unwarranted. ie. I wrote 'AJAX' before 'AJAX' was a term. I use Atlas today. I understand how Atlas works - I know javascript well. AJAX isn't really that difficult to understand.

"will no doubt appeal to those individuals who disregard JavaScript and the Browser as "real development tools". "
javascript is a scripting language. It has a purpose and serves a purpose. Making tools to help do tasks is a normal thing. That doesn't mean there is a 'disregard as a real development tool'. This is not some holy grail here, we make tools to abstract away the rudimentary things we do over and over again repititiously.

"is that we spend less and less time on "real innovation""

My first thought is - you guys need to go back and write assembly language to do your websites. Sorry folks, but innovation for the masses is that we don't have to recreate the wheel everytime we need to 'bind data to a grid'. I assume from these posts that you really enjoyed the asp/vbscript model of jangled spaghetti code with td tags and recordset movenext. Or better yet, perhaps create ATL objects to make com objects that output html.

It is quite costly to build applications and pay your salaries to have you down in the weeds "innovating" at every step rather than supplying the customers needs and meeting their requirements in a timely manner. I think there is a place for innovation, what Nikhil is doing for example is 'innovative'. If you want 'innovation' you can do the same - it's all possible obviously this and tools like Atlas show that it is! Perhaps you work in R&D ?

I for one think Javascript is not the ferrari - I see it different - to me, C# is the cadillac. It's far superior in many many ways. I would think that if Javascript is the ferrari, I'd like to see your ScriptJS Prototype that creates server-side C# for me :) We have a well written object oriented language that is highly extensible to build applications.

For all the reasons Nikhil has developed this prototype are the reasons that I find C# to be a powerful language.

I'm curious Nikhil on items such as 'drag and drop'. How will Script# work with Atlas declarative script? Can they work hand in hand. I think this is same question above.

Also - question on the getElementById - will ID's have the same issues that we have now with asp.net and javascript with ClientID (ie. a control in a panel or masterpage). If so, how will we pass these id's to the code?

Lastly, at what point Nikhil do we end up moving away from the 'server-side' model? Already I see that with Atlas in combination with WebServices - entire applications can be created with this in mind. If you need a trip to the server, you call a webservice, otherwise, most of the processing then is on the client for the UI, with validation, drag and drop, behaviors, etc...

James Curran

Posted on 5/23/2006 @ 11:11 AM
Dimitri,
>> C# is like a farm tractor: it's got bare metal plate for a seat, looks ugly, smells funny, but eventually gets the job done. On the other hand, JS is like a Ferrari: it's beautiful, elegant, comfortable to work with, and yes, dangerous (potentially lethal) for a novice. <<

huh? JavaScript is a Ferrari?? What have you been smokin'?

Let me give it a try...

C# is a drag racer. Not the prettiest, but loaded with power. (as the prophet says "I wasn't built for comfort, I was built for speed")
JS is a rickshaw -- But the best engine, but since you have a comfortable seat and someone else is doing the work, you don't care. Beside, if you whip it hard enough, it will do what you want.

James Curran

Posted on 5/23/2006 @ 11:18 AM
Nikhil,

This brings up an interesting topic. Is there a roadpath in MSFT for such employee hobbies to become fully-supported products. Does MS owned it, or would they have to buy it off you (and if the latter, is that something they do?). (Actually, I think Lutz Roeder's Reflector should be the first on that list).

P.S. To echo Barry's comments, the text boxes and the CAPTCHA are very hard on us color-blind folk). If, between refreshes, you could vary the colors used in the CAPTCHA, that would be very helpful)

Steve

Posted on 5/23/2006 @ 11:44 AM
Nikhil - is it possible to set breakpoints and step inside this for debugging purposes as well?

Hermann Klinke

Posted on 5/23/2006 @ 11:58 AM
"Now if the code completion only worked on real JS code rather than C#."

Try JSEclipse (www.interaktonline.com/Products/Eclipse/JSEclipse/Overview/) . It does exactly that and much more. It requires Eclipse (which is a piece of crap IMO) though since JSEclipse is a plugin for Eclipse.

I second Steve with the CAPTCHA box. I am not color-blinded and it is still very difficult to read. And what is this "spam-protection code has expired" all about? I get this all the time. There is no enough time to read a few comments and then post a comment without having to refresh the page to get a new spam-protection code.

Mark

Posted on 5/23/2006 @ 12:10 PM
I'm not 100% convinced by a C# JS compiler. I can't explain it - it just seem natural. It's not that I don't like C# - it's pretty cool (except for not forcing exceptions to be managed). Will Script# be more productive than JS bearing in mind how verbose C# is?

Calling JS a rickshaw is a bit over the top. Have you ever actually used it? It is extremely flexible (e.g. ability to redefine behaviour of native objects).

Mark

Posted on 5/23/2006 @ 12:11 PM
Oops - I meant to type "it just seems unnatural".

Nikhil Kothari

Posted on 5/23/2006 @ 12:18 PM
Alex:
You can test for the something being set as follows:
if (Type.GetField(el, "innerHTML) != null) { ... }
This gets translated to:
if (el.innerHTML) { ... }
I am not sure you need to check for the type being "undefined". Unless, I am missing some scenario, the above test should suffice. There are a number of statics on Type that allow you to turn explicit late-bound calls in C# to implicit late-bound calls in generated script.

Currently, this is pretty much a translator and in some sense a runtime. Building abstractions on XHR etc. is the job of a framework on top of the runtime. These will come eventually. Part of the response to that which others have also asked is integration with Atlas... still working this out with the team.

Steve:
Drag/drop, declarative markup - all these are frameworky concepts that need to be layered on top. Clearly there is a ways to go. Still need to think about the client ID problem - fundamentally the mixing of server-side model and client-side model leads to ID problems... which leads to your next question - when can web apps become client-centric: for some apps it makes sense, and for some it doesn't. Example: Virtual Earth is a client-centric application. Amazon is a server-centric application. There are lots of criteria to evaluate, and I don't think there is one right answer. The goal of Script# started out as making it possible to write script components (think Atlas) where you can glue them together to create client-centric apps, or encapsulate the script in server controls to create server-centric apps. So it applies in both paradigms.

Captcha issues:
Thanks for pointing it out guys. Unfortunately its the google toolbar recognizing some fields and completely disregarding the site author's CSS stylesheets. Please turn off the google bar feature that tries to find form fields it thinks it knows about. It doesn't provide any mechanism for the site author to annotate input fields. Otherwise, use my light theme (switch using the two buttons on the top-right). I simply haven't found the time to update the site look/feel etc. because I've been devoting all my time to Atlas, and projects like this one :-)

Spam protection issue:
Spammers play replay attacks. So any particular spam code needs to have an expiry, otherwise, its purpose would be defeated almost instantaneously. Unfortunately this negatively impacts real people making real comments. Not sure what I can do to counteract the spammers while still allowing people to enter comments. Such is the Web...

Brennan Stehling

Posted on 5/23/2006 @ 12:27 PM
http://www.codeplex.com/

Perhaps you could release Script# on the new MS website for shared projects. It would really give a kick start to that website.

Steve

Posted on 5/23/2006 @ 1:26 PM
"The goal of Script# started out as making it possible to write script components (think Atlas) where you can glue them together to create client-centric apps, or encapsulate the script in server controls to create server-centric apps. So it applies in both paradigms"

I think that is a good goal in and of itself. Even if Script# was used for the creation of the javascript side of the Atlas server control it would be a powerful way to create these reusable Atlas controls. (It would provide an alternative - granted, the javascript fanatics would still be able to produce javascript).

In reviewing the code written on the other controls - the amount of work to produce the javascript was outweighing the added benefits. But here I see a tool that creates the correct output to work hand in hand with the Atlas controls. This would make development of the client-side script for these controls easier in that they would provide intellisense, compile time error reporting, cross browser ability. In addition it helps ensure a standardized output that would be less error prone when moving the components to the page.

Jurgen

Posted on 5/23/2006 @ 5:22 PM
Nikhil, I'm pretty darned excited about this - I'm definitely going to try it out. I love c# with a passion, and I like Javascript too, but given a choice I'd rather write client side code in C#. Well done and thanks so much for sharing this. I think Script# has an enormously bright future! I'm at the start of a fairly serious webapp which will embrace the Web 2.0 philiosophies - I'll provide some feedback when I've had a play.

Keith J. Farmer

Posted on 5/24/2006 @ 12:42 AM
This is *exactly* what I was begging ScottGu for after the first releases of Atlas back when there was a horrible mess of Javascript -- before it got nicely encapsulated.

One thing that might be more useful would be an IL->JS translator. It might be more difficult in places, but you could just compile everything to verifiable IL and produce the JS on the fly.

It'd be interesting to see what DLinq expressions would look like... perhaps translated to WS calls?

Keith J. Farmer

Posted on 5/24/2006 @ 12:46 AM
Oh, and I don't suppose you've made an ASP.NET BuildProvider for this? Register some .csjs extension to be targetted by ssc, and let the engine do the work for you.

RichB

Posted on 5/24/2006 @ 1:01 AM
Hermann>
http://research.microsoft.com/phoenix/

RichB

Posted on 5/24/2006 @ 1:25 AM
Steve wrote:
> RichB wrote:
> > "So we need to find a way to get the masses who are unable to gain the
> > multi-disciplinary skills to write modern AJAX web apps."
> >
> ? why do you assume people who use these tools do not know this. Actually, you don't
> know. This statement is unwarranted. ie. I wrote 'AJAX' before 'AJAX' was a term. I use
> Atlas today. I understand how Atlas works - I know javascript well. AJAX isn't really
> that difficult to understand.

I don't assume. I know from working with people. Clearly, I'm not talking about people like you or me (I used Nikhil's remote scripting extensively back in 1999 - the pre-cursor to AJAX if ever there was one). I'm talking about the vast majority of developers. The developers who would never read Nikhil's blog. The web developers who haven't heard of Atlas (and believe me, there are more ASP.Net web developers who have yet to hear about Atlas than those who have).

> to me, C# is the cadillac. It's far superior in many many ways.

Yes it is. But also Javascript is far superior in many other ways. And Nikhil showed that in his recent comment where he wrote:

> if (Type.GetField(el, "innerHTML) != null) { ... }
> This gets translated to:
> if (el.innerHTML) { ... }

I wonder which one is more natural.....

sys

Posted on 5/24/2006 @ 2:02 AM
I like the script#.
Cool

Michael Schwarz

Posted on 5/24/2006 @ 2:27 AM
I still wonder why Microsoft doesn't focus on creating a great JavaScript IDE/debugger. Instead Script# will use the intellisence is available in Visual Studio. I think I'm not the only developer who is searching for JavaScript debugger. If you are using Script# is it possible to include JavaScript files that are currently used in my web sites, or do I have to write any JavaScript code now in C#/Script#?

Shtong

Posted on 5/24/2006 @ 2:43 AM
This is a great tool, congrats to Nikhil !

However, if making a framework like Atlas is absolutely useful and justified, I'd prefer see base Javascript improvement like JS2 (and browsers implementing it) instead of such turnaround.

Radek Domin

Posted on 5/24/2006 @ 3:14 AM
Great Job

I (maybe) found one bug. When I try to use delegates, it does not work.

public delegate void MyDelegate();
...
public void move()
{
MyDelegate my_delegate = new MyDelegate(this.interval_move);
Window.SetInterval(my_delegate, 1000);
}

public void interval_move()
{
increment++;
this.Text = increment.ToString();
}

It compiles well, but on client side o always get error on Window.setInterval row: "missing ] after element list [object Object]"

Do I something wrong? Can anybody help me?

JasonBsteele

Posted on 5/24/2006 @ 6:15 AM
This is great stuff - I look forward to the day that I never have to spend an hour looking for a missing semi-colon of an "If" instead of "if" !

The video was pretty good at demonstrating how to use it within your solution - a couple of comments though: it was a bit quiet and you spoke a bit quickly! However, I wouldn't want to ever see a video replacing very heavily commented code examples.

Whilst I think this is a very good idea I am slightly surprised and confused by MS's approach to all this: I am surprised that you can work on a secret project and then attempt to get it integrated with ATLAS - this strikes me as being a bit TOO unstructured and organic; and I am confused because this is yet another thing to consider alongside XAML and ATLAS.

Having said that, I guess I would be whinging that we hadn't been given the opportunity to provide feedback if it was suddenly sprung upon us and the next MS "standard"! ;)

JP

Posted on 5/24/2006 @ 9:09 AM
can this be used with vb.net instead of C# ?

Nikhil Kothari

Posted on 5/24/2006 @ 9:59 AM
Loving the discussion!

RichB: There are definitely small pockets of code where dynamic typing helps... undoubtably! However, what I want is primarily strong typing with some blocks of late-bound code. That would provide the best of both worlds. C# doesn't do that just yet.

Michael Schwarz: Visual Studio 2005/Visual Web Developer have a script debugger. There is a way to expose existing jscript to the C# type system - I'll blog more in the future - short story is you write a metadata assembly which isn't used for conversion where you define types and OM; its only used as a reference in another project. An example of this is sscorlib.dll - it provides metadata for the bootstrapper present in sscorlib.js, which was hand-written javascript.

Shtong: Covered couple of times; JS2 will offer some much needed constructs in the language. Until that is available *and* becomes ubiquitous on end-users machines, its a little bit of a toy, and real apps would need to wait until it grows beyond that.

Radek Domin: You need to pass SetInterval the value of Delegate.Unwrap(my_delegate) like I did in the video to pass a callback to the XHR object. This is temporary, and hopefully will go away at some point.

JasonBsteele: This project could only be started when one has enough experience with raw scripting to understand what is possible with JScript, what are the problems... so in some sense solutions like these come about organically while trying to analyze what is there with that base level of understanding, and experimenting a bit with what you think might be a reasonable solution.

JP: Sorry no vb.net support. Theoretically, it would be possible for someone to build a vb parser that translates source code into the internal AST structures I build from C#, and the rest of the codebase would be none the wiser. I just haven't found the time to look at this end of the problem.

Kelly Stuard

Posted on 5/24/2006 @ 10:17 AM
Generally I can avoid JS. (I know JS.)

One place I just cannot avoid it is when using CustomValidators. Is there any way to place a value in CustomValidator.ClientScript that would call a method in nStuff:Scriptlet. This would not keep me from having to rewrite the validation code; but at least it would allow the same "environment" throughout the process.

Do you have any advice on integrating your new, fancy technology with old, boring CustomValidators?

Hermann Klinke

Posted on 5/24/2006 @ 11:41 AM
"I think I'm not the only developer who is searching for JavaScript debugger."

You are right, but there are already 4 Javascript debuggers: Microsoft Script Debugger, Microsoft Visual Studio can debug Javascript, Venkman for Firefox, and the new version (0.4) of FireBug (Firefox extension) will include a Javascript debugger.

Nikhil Kothari

Posted on 5/24/2006 @ 11:48 AM
Kelly, good scenario. Thanks for bringing it up. Its not fully supported today, but should be straightforward to - I'll add it to my list for a future build - essentially what is required is building support for generating global methods. You wouldn't use the scriptlet control; rather you'd take the .js and include it into your page directly via a script tag.

Rydal

Posted on 5/24/2006 @ 2:27 PM
So this is why you have been so quite!

Julien Couvreur

Posted on 5/24/2006 @ 2:27 PM
Nice job.
I'll have to experiment with this cross-compilation concept more before being convinced, but it's definitely intriguing.
Are you planning to have a "hosted" mode like GWT? That would probably require a .Net implementation of the widgets and a scriptlet runner. But it would enable to debug some of the UI logic bugs without leaving the C# world.

Also, what is your approach to ensure that the generated code doesn't have too many memory leaks?

Steve

Posted on 5/24/2006 @ 2:31 PM
I'm still curious how you plan to handle the generated ClientID's - wouldn't this be required to validate a server-side control (ie. TextBox) ?

I agree with Kelly there, building in some validation logic using Script# for the customvalidator javascript code would be great.

Probably been mentioned, but without reading through all this: I've written Atlas client side javascript to solve a few problems in some projects I've done.

I did a walkthrough of your sample - I liked what I saw - my questions above mostly deal with how to handle asp.net controls.

I really see value in using Script# to do this in the future, I see some things that would be helpful to have:

1. radiobuttonlist & checkboxlists - do you have or plan on supporting these objects in Script# ?
2. listview and client.datatable - would you support these? If you had a listview - ie. would you support templates?
3. is there a way to pass values into the compiled code from the page? ie. If I did have a server-side control I wanted to work with - would it be possible to pass it's ClientID to the page at runtime? Perhaps to the Scriptlet control on the page?

The current custom validator supplies an args, source to the custom javascript as it's signature, which is able to pass the clientID to the javascript - I'm wondering if the same type approach could occur in Script# ? (Although, I'd rather the signature support a key pair for multiple args/sources)

Jurgen

Posted on 5/24/2006 @ 6:53 PM
If I have an asp:HiddenField element in my page, how would I access the Value property of this object in the scriptlet?

I'm assuming something like this:

private Element _hiddenField;

public void Start() {
_hiddenField = (Element)Document.GetElementById("myHiddenField");
}

private void OnOKButtonClick(object sender, EventArgs e) {
Callback completedCallback = new Callback(this.OnRequestComplete);
_request = new XMLHttpRequest();
_request.Onreadystatechange = Delegate.Unwrap(completedCallback);
_request.Open("GET", "myscripthandler.ashx?myhiddenvalue=" + _hiddenField.DOMElement.Value, true);
_request.Send();
}

or can I access the Value directly:

_request.Open("GET", "myscripthandler.ashx?myhiddenvalue=" + _hiddenField.Value, true);

or do I cast to DOMElement?

_request.Open("GET", "myscripthandler.ashx?myhiddenvalue=" + (DOMElement)_hiddenField.Value, true);

I'm a little confused because the Script.UI namespace only handles Element, Button, Label and Textbox it seems.

Any help would be appreciated.

George

Posted on 5/24/2006 @ 7:02 PM
Hi Nikhil,
Congratulation on a wonderful project. Hope it's has been as much fun creating as it will be for us using :). I'm posting to present a slightly different angle. It's strange this point has not been made before. As a side note whereas it's true that Javascript is extremely powerful I'd rather give importance to it's AOP capabilities and not to functional programming or dynamic types or what else which often come in my way. Anyways I might still prefer using pure javascript in place of C#-like framework if not for one thing - who has time to implement all that ASP.NET already provides us free from the ground up? Who has the time to deal with browser quirks and the DOM? To this regard I don't remember when I've written custom javascript last... long time ago. I use Dojo instead (http://dojotoolkit.org). Dojo is how I do the Web 2.0 magic and dojo is IMHO how it should be done. Now picture this - Script# wrappers to bridge dojo components to .NET development. Here we'll have something more than Google&Yahoo put together. And if you want the true power of javascript dojo make it very easy to truly be powerful without reinventing the wheel.

What do you think about that? Why write a whole web framework (time, bugs) when there is one that can be easily wrapped. This will give Script# space to develop as the wondeful language and dev-oriented tool it is without having it go into deep waters with lots of competitors and requirements.

Jurgen

Posted on 5/24/2006 @ 7:46 PM
None of the above looks like it'll work - Is Element abstract?

So perhaps the following:

private DOMElement _hiddenField;

public void Start() {
_hiddenField = Document.GetElementById("myHiddenField");
}

private void OnOKButtonClick(object sender, EventArgs e) {
// previous guff here...
_request.Open("GET", "myscripthandler.ashx?myhiddenvalue=" + _hiddenField.GetAttribute("Value").ToString(), true);
_request.Send();
}

Nikhil Kothari

Posted on 5/24/2006 @ 10:48 PM
Julien: The subject of hosted mode running has come up before with another person on the asp.net team. However, its not been investigated so far. In terms of memory leaks, objects will implement IDisposable... this gives a point to place cleanup logic - next is either some code will explicitly call dispose, or every IDisposable will be disposed automatically on window.onunload. This will hopefully take care of majority of cases. There are still some cases. No shortcut other than being careful. This is the same as what we do in Atlas.

Jurgen: Try making _hiddenField of type DOMInputElement, which has a Value property you're trying to access. The types in the System namespace represent the raw DOM. The types in ScriptFX.UI namespace represent higher level controls (eg. TextBox with Text property). Over time there will be more controls in that namespace, so you can choose to work at the right level of abstraction based on your needs and choice.

Simen

Posted on 5/25/2006 @ 4:22 AM
I could have understood it if you'd done this as a learning project, but are you seriously hoping people will use this instead of Javascript directly? You've gone to great lengths just to let people write *more* boilerplate code to do the same thing?

Daniel

Posted on 5/25/2006 @ 8:59 AM
I really think that would be more useful to translate from IL to JavaScript, as you know one of the major design goals of the Common Language Runtime, was to be a "common" runtime :)
What about VB programmers? J# programers? Perl.NET? F#? Ok, you got the idea.
I love C# and do not like VB.NET honestly, but there are a lot, a lot, a lot of VB programmers arround this globe.
Thanks,

Rick Strahl

Posted on 5/25/2006 @ 10:56 AM
George, I'm guessing they're thinking about this becoming a possible front end for the ATLAS client side framework :-} Some sort of abstraction for this is needed anyway and this would address a number of scenarios directly - Intellisense support, compile time checking and IDE support.

Jurgen

Posted on 5/25/2006 @ 4:45 PM
Nikhil - thanks for pointing me at the right object - that part works well.

I am however having a problem trying to get the provided example to work as a usercontrol. I have tried every I know, but the page seems to refresh, taking it back to it's original state. Is there a chance you can provide the same example (with the async request) but where the controls are on a usercontrol?

Steve

Posted on 5/25/2006 @ 4:52 PM
Nikhil - I'd love to see Script# produce the atlas script that Garbin has posted here: http://aspadvice.com/blogs/garbin/archive/2006/03/29/14715.aspx

Is this possible in this code you have provided?

Jurgen

Posted on 5/25/2006 @ 6:43 PM
OK I just worked out if I use a standard input element same as you have on the usercontrol, it works - but if I use an asp:button it works but then causes the page to refresh. I have set options like UseSubmitBehavior=false but it makes no difference. Anyway I'm happy it all works now. Thanks anyway.

Kans Parmar

Posted on 5/25/2006 @ 11:07 PM
Great job! We were looking something like this since quite sometime with respec to javascript and here you provided. Kudos goes to you.

Thanks & Regards,
Kans

Mateusz Kierepka

Posted on 5/25/2006 @ 11:59 PM
Hi!

Script# for JavaScript (AJAX) translator is good idea.
Did you think about making Script# open for addins? For example this will be good idea to allow Script# generate real ActionScript files. ActionScript (used Flash) is just another JavaScript...

Igor Kononuchenko

Posted on 5/26/2006 @ 4:46 AM
I write a lot of pure JavaScript preferably for
creating some cool effects or controls on the client side. Last time it has such scenarios:

1. Some javascript control - I'm using prototype.js(helper functions, "class" declaration)
and some lib for effects(usually Yahoo). If I need js control to be presented on the
server side I write asp.net wrapper WebControl which constructs js
control(main script embedded in dll). Ajax implemented using client callbacks.

2. Atlas framework which works cool with asp.net controls(using update panel) but
too complex to do the simple things...

What I like in this framework is OOP of C# but I don't like idea of writing the simple
javascript tasks in c#... I'd rather want to see great Javascript IDE with intellisense
and refactoring support(I think it wants a huge amount of developers)...

But I think for big javascript task maybe Nikhil's lib have sense... some suggestions and questions:
Does it generates cross browser JS or its on my care?

Do you think about runtime javascript generation in to WebResource?

It could be really interesting if we can interact from script# with asp.net webcontrols(
to add some cool effects)?

Stefan Dobrev

Posted on 5/26/2006 @ 4:57 AM
Hi Nikhil

I was wondering when this will happen. So the time is now. Thanks for the great work. You've done pretty well for the first release.

My list for the next releases:
1. Integration/Support for Atlas.
2. Support for framework/Atlas controls.
3. Fully support javascript (closures, functional programming, aspects) - integration with LINQ project (C# 3.0)

P.S.: "I've been devoting all my time to Atlas, and projects like this one :-)" - I wonder what are the other projects :) Hope they are blast like this one.

jonmeyer

Posted on 5/26/2006 @ 5:24 AM
Hi Nikhil,

My team has built a large Ajax UI framework with an Xml syntax that we compile to JS. (Think XAML for web apps). Scripting is done in an extended JavaScript syntax (we added class, method, #if / #endif for example). Our compiler is written in C#.

Script# might be a great alternative for scripting. Some questions:

* Do you have any plans to make any part of Script# open source? What about the runtime itself? If this isn't open source I probably can't use it. (GWT is open source, if that makes any difference).

* Does the Script# compiler run under Mono? Much as I love Visual Studio, we've got mac-head and linux-head team members to placate. We'd be sunk without Mono.

* Is there a C# API to the compiler, or must it be used from the command line?

* Can Script# generate .js code which preserves the linebreak formatting of the .cs source code? Our compiler (really a translator, as you say), ensures that .jsx source code line 32 matches .js output line 32. Although occasionally lines in the .js files are less readable (some translated lines are long), we've found this critical for debugging - when we get a JavaScript runtime error on line 1137 we know where to look in the source.

* Finally, looking at the Release code I notice that although you shorten private identifiers, you don't shorten public identifiers. Since you are compiling everything at once, is there a reason you can't shorten them too? (Our current compiler shortens everything, public and private).

Nikhil Kothari

Posted on 5/26/2006 @ 10:01 AM
Steve: Drag/drop type of code should be possible to implement. You do need the implementation of the framework itself (classes such as DragDropManager) before you can write this code in C#.

Jurgen: In your usercontrol scenario, the ID of the rendered HTML input is fully qualified... so it likely your document.getElementById is failing.

Mateusz Kierepka: I have thought of plugins for different Javascript profiles. Nothing in the code is geared around enabling that just yet. ActionScript would be interesting (though I don't fully know the flash authoring model). JavaScript 2 will also be interesting in the future. Are there folks interested in this?

Igor Kononuchenko: I did think about runtime generation of javascript; However, this won't fully help - the c# sources are unlikely to be in your web project (which only knows about server-side code), because you want the full power of C# projects. That said, I am talking to folks about how you can get the full power of a c# project for client-code within a web project. Then the dynamic generation would make complete sense.
It does generate javascript that should run cross-browser. However Script# as a language/authoring tool doesn't abstract DOM differences which are much more painful. A framework built on top of Script# can address that. Makes sense?

Stefan Dobrev: Regarding the Atlas end, I am hoping things will work out eventually... currently these two aren't integrated as you note. There is a fair amount of work to be done before I can really get to things like LINQ, and some of the other things you mention. Other projects: time will tell ;-)

jonmeyer:
- I was contemplating making the script framework itself (not the compiler) open source. I have to think through a few things, incl. how this relates to Atlas. I am hoping to see folks put together libraries built using this as well...
- I haven't tried it under Mono. If someone would try and let me know it would be great to even know where things stand at the moment.
- Yes there is a C# API, and an msbuild task as well. Look at the public classes in nStuff.ScriptSharp.dll.
- Preserving line-breaks: sorry, this information is pretty much lost at the lexing stage in the current design. Its also becomes near impossible when you turn natural constructs like class declaration in c# into simulated OOP patterns in script. There are more lines in script needed to define a class. Other things that play into this are conditional compilation (eg. #if DEBUG) where the preprocessor might just throw chunks of the code even before the lexer sees it.
- When creating a framework, the consumers of your API need public APIs to not be mangled. Hence the distinction. Perhaps for an app, the compiler could shorten everything - though even there there are issues: you may have an event handler in your HTML that points to a method in generated code.

Mike Parsons

Posted on 5/26/2006 @ 2:02 PM
Yet another AJAX toolkit to add to the mix ...

http://www.michaelparsons.ca/ajax/MyAJAXToolKit.html

Hey Nikhil ... I would be interested in your take on this approach as I see a Philosophical intersection with Script#.

Hermann Klinke

Posted on 5/27/2006 @ 8:38 AM
"Mateusz Kierepka: I have thought of plugins for different Javascript profiles. Nothing in the code is geared around enabling that just yet. ActionScript would be interesting (though I don't fully know the flash authoring model). JavaScript 2 will also be interesting in the future. Are there folks interested in this?"

Yes, I am!

Lukasz Sklodowski

Posted on 5/28/2006 @ 3:13 AM
Hi Nikhil - that is greet idea. And webcast sample is greeat to. Thanks from Poland.

Alexnaldo Santos

Posted on 5/28/2006 @ 6:53 AM
Hi Nikhil,

How to return a object from a request using script# ?

I think that you can do it using JSON, like it :

public class Person
{
private string _name;

public string Name
{
get { return _name; }
set { _name = value; }
}
}

private void OnRequestComplete() {
if (_request.ReadyState == 4) {
_request.Onreadystatechange = Function.Empty;

object ret = JSON.eval(_request.ResponseText);
Person person = (Person)ret;
_helloLabel.Text = person.Name;
}
}

Thanks,
Alexnaldo Santos

Nik Donets

Posted on 5/28/2006 @ 6:27 PM
I can say only one thing: Thanks Nikhil!

I had an idea of making something similar for Java, but as soon as I started to think about how it would feel to program JavaScript in Java I realized that C# with it's support for delegates would be more suitable for this task. And that's as far as I got with that idea.

What you did is great! This is exactly what I always wanted but never had. All the people who are saying that this is just adding another layer of abstraction to an otherwise elegant language have never worked on a large project in JavaScript. No, I'm not talking about a web-store that has 100s of pages all with pieces of JavaScript in them. I'm talking about projects with hundreds or even thousands of lines of JS code. Projects such as Virtual Places by Nikhil (http://apps.nikhilk.net/VirtualPlaces/), Virtual Earth by MS (http://local.live.com/), Windows Live by MS (http://www.live.com/) and my own project Virtual Address Book for MSN (http://www.worldsbestapp.com/EntryDetail.aspx?Value=Uy93pNRLNoO3qe9J8t6cM0QSYo84zQakN1rg00%252fxlsA%253d) which won the second place in the MSN World's Best App contest.

Yes, I agree that for something quick such as an Alert() message on button click I would use plain JavaScript but for projects that utilize OOP features of JS (if you could call them such) and are pretty large in codebase size I would definitely use Script#. But when you factor in Script#'s support for AJAX, it becomes invluable! Frameworks such as Dojo do make our life easier somewhat, but JS code is still JS code - it's still difficult to edit, manage and refactor.

A couple of suggestions for the next release of Script#:

- I noticed that the Script# Core Runtime JS file and ScriptFX JS file have a lot of whitespace and some comments in them. Have you thought about somehow providing two versions of these files, one for Debug builds and another, more compact one for Release builds? I'm not familiar with web resourses and have no idea if this can be accomplished.

- Also, have you thought of providing the two JS files I mentioned in Raw .js format so that we could use Script# outside of ASP .NET world?

- That's about it! I'll try to make a more comprehensive list as I continue to experiment with Script#

Time to rewrite my Virtual Address Book in C#!

PS: Microsoft, this guy definitely deserves a pay increase or at least a bonus! :)

Radek Domín

Posted on 5/30/2006 @ 8:52 AM
On 5/24/2006 you advice me to use Delegate.Unwrap(my_delegate) in Window.SetInterval. But Delegate.Unwrap returns Function type and Unwrap expects Delegate type or string. So I try to add .ToString() after Unwrap method, but it doesn`t work. In this case it can be compiled, but interval function isn`t calling.

Nikhil Kothari

Posted on 5/30/2006 @ 5:20 PM
Alexnaldo Santos: JSON typically gives you back plain script objects and not classes. I'll be putting out a doc that covers pieces of the solution - hopefully at some point there will also be a topic on how to use all this with JSON very easily.

Nik Donets: Eventually the core runtime js files will be minimized (using my other tool: JavaScript utilities). The next update will provide the script files in raw form as well.

Radek Domín: There was a bug. It will be fixed in the next release (soon).

Radek Domín

Posted on 5/31/2006 @ 4:15 AM
Ok, thanks. I appreciate your work.

Fnustle

Posted on 5/31/2006 @ 11:25 AM
RichB - We have to remember that the goal of Atlas is to allow control developers the power to develop rich ajax controls. Controls developers are a different breed from the enterprise developer who just wants to use existing controls. Atlas is targeting a specific developer, and therefore the toolset needs to be constructed with this developer in mind. Keeping this in mind we can see that Script# is an inappropriate technology for control developers and useless for control utilizers.

Dan Lichtenfeld

Posted on 6/1/2006 @ 10:53 AM
Hi Nikhil,

I think that we'd all wish for a better version of Javascript to come along with full object orientation, strong-typing and a standard IDE for both client-side and server-side development. In the meantime we are stuck with either learning the intricacies of Javascript and how to overcome its limitations or just trying to do so using generators, convertors and alot of "love". From my experience managing large Javascript projects with limited tools and development aids I can say that C# (or .net development at large) is a blessing.

The complexity and need for deep skills involved in hard-core Javascript programming have led me and some of my team members to develop an alternative paradigm. We call it "Empty Client" computing and it basically means that instead of trying to convert object oriented capabilities to Javascript in order to work on browsers, we simply leave them to run on the server and have the output sent to the browser for rendering. This means we employ a "Server Based Computing" approach to the application architecture and use de-coupled GUI components to bind between the GUI rendering and the GUI logic. The GUI components and in fact the entire devleopment platform that we employ is based on Winforms. This means that development is done in .net languages such as C# or VB.net and layout is done via Winforms design time components within Visual Studio .net.

If you'd like to get some more information on how this works, see samples and even download our community edition you are welcome to go to http://www.visualwebgui.com

There will always be room for complex Javascript (client side) based logic, however many applications could benefit from an Empty Client style approach that enables developers to take advantage of the best development patterns without compromising for browser/javascript limitations.

Dhtml Guy

Posted on 6/1/2006 @ 4:36 PM
Here is an interesting review of Script# versus Google GWT
http://www.eweek.com/article2/0,1895,1970702,00.asp

Alex Ma

Posted on 6/1/2006 @ 4:59 PM
Visual Web GUI, http://www.visualwebgui.com/, does the similiar thing. Basically WebGui is WinForms Over Web which enables development of rich web applications with WinForms functionality and interactivity using Visual Studio's rich design, coding and debugging features. The tech