Friday, October 20, 2006

Scripting in C# - take 2

Yesterday I complained that I want a way to run scripts in C#. Funnily, Leon Bambrick (The Secret Geek) published an add-in to VS (for VB) that does part of what I'm searching for approximately at the same time. This add-in lets you mark some VB code and execute it on-the-fly. That's great, and it's part of what I am looking for (although his add-in is for VB only, and I'm looking for a solution for C#). What I want in addition to that, is a command-like UI where every expression you type gets executed once it's completely written.

Here's an example of a scripting session as I perceive it (Matlab users will probably feel at home):

>> int number = 5;
ans:
     number = 5
>> for (int i=0; i < number; i++)
     {
         Console.WriteLine(i.ToString());
     }
ans:
     0
     1
     2
     3
     4
>> $Clear(number);
ans:
     number cleared from memory

>> class MyClass
     {
          MyMethod(string input) 
          {
                    Console.WriteLine(input);
          }
     }
ans:
     MyClass declared successfully

>> MyClass myObject = new MyClass();
ans:
     myObject created successfully

>> myObject.MyMethod(1234);
ans:
     Syntax error - MyClass.MyMethod(string input) does not accept input (1234)

>> myObject.MyMethod("Hello World!");
ans:
     Hello World!

A few notes:

  1. As you can see above, expressions can span more than one single line. The engine simply waits for the expression to be completed (semi-colon or brackets). So the for loop or the class declaration are being executed only when the closing bracket is typed.
  2. Although I wouldn't use this for very large and complicated classes, there should be support for classes and any other construct of the language.
  3. Each expression ends with a feedback from the engine about its execution (the "ans" regions - taken from Matlab)
  4. Errors don't throw exeptions, but rather give you as meaningful an explanation as possible
  5. Since the engine must keep some data in memory, we need to be able to free it at will. That's what the $Clear command would do. I suppose we might need support for a few more such scripting commands (the less the better).
  6. Once you have such a scripting engine, evaluating portions of some code (like Leon's add-in) becomes trivial.

P.S: For all those who say - "Dude, with Powershell you can do that and much more", I say: "Dude, as long as it's in another language it's not the same. It means I can't take it for granted any C# programmer will know the scripting language as well as he knows C#. It also means I can't easily copy code from my scripting console to my code - I have to first translate it into C#. So no - unfortunately Powershel is still not there in terms of ease-of-use."
Still about Powershell - I have nothing against Powershell. Actually, it was about time decent scripting became available for Windows users (and sure enough Powershell is way beyond decent!!!). What I don't understand, though, is why was there a need for a new language? Wouldn't it have been nicer to have an additional set of libraries to support the various functionalities available in Powershell (WMI, IIS, File System, etc.) - add these libraries to the .NET Framework and add a scripting engine as described above? Everyone would be able to pick his favorite language and use it for scripting. Granted, Powershell provides some functionalities with just a single command, that would have required much more lines of code in any other language. But I think that's not a good excuse - you can always wrap those commonly-used functionalities inside some static function, providing the same final result (single function call to do a rather complicated task).

No comments: