Resurgange of the shell.

Two things happened in such short proximity time-wise that I can't help but thing they're somehow related to the larger shift to interpreters. Earlier this week Miguel introduced csharp shell which forced me to dust off my shoddy Mono 1.9 build and rebuild Mono from Subversion just because this is too interesting to pass up on.

One of my favorite aspects of using IronPyhton, or Python for that matter is the interpreter which allows for prototyping that doesn't involve creating little test apps that I have to build to prove a point. For example, I can work through fetching a web page in the csharp shell really easily, instead of creating a silly little application, compiling, fixing errors, and recompiling:

tyler@pineapple:~/source/mono-project/mono> csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> using System;
csharp> Console.WriteLine("This changes everything.");
This changes everything.
csharp> String url = "";
csharp> using System.Web;
csharp> using System.Net;
csharp> using System.IO;
csharp> using System.Text;
csharp> HttpWebRequest req = HttpWebRequest.Create(url);
(1,17): error CS0266: Cannot implicitly convert type `System.Net.WebRequest' to `System.Net.HttpWebRequest'. An explicit conversion exists (are you missing a cast?)
csharp> HttpWebRequest req = HttpWebRequest.Create(url) as HttpWebRequest;
csharp> HttpWebResponse response = req.GetResponse() as HttpWebResponse;
csharp> StreamReader reader = new StreamReader(req.GetResponseStream() as Stream, Encoding.UTF8);
(1,45): error CS1061: Type `System.Net.HttpWebRequest' does not contain a definition for `GetResponseStream' and no extension method `GetResponseStream' of type `System.Net.HttpWebRequest' could be found (are you missing a using directive or an assembly reference?)
csharp> StreamReader reader = new StreamReader(response.GetResponseStream() as Stream, Encoding.UTF8);
csharp> String result = reader.ReadToEnd();
csharp> Console.WriteLine(result);

What time is it?

US Naval Observatory Master Clock Time

Sep. 11, 07:29:02 UTC

Sep. 11, 03:29:02 AM EDT

Sep. 11, 02:29:02 AM CDT

Sep. 11, 01:29:02 AM MDT

Sep. 11, 12:29:02 AM PDT

Sep. 10, 11:29:02 PM AKDT

Sep. 10, 09:29:02 PM HAST

Time Service Department, US Naval Observatory

csharp> reader.Close();
csharp> response.Close();

I really think Miguel and Co. have adding something infinitely more useful in this Hackweek project than anything I've seen come out of recent hackweeks at Novell. The only feature request that I'd add along to the csharp shell would be "recording", i.e.:

tyler@pineapple:~/source/mono-project/mono> csharp
Mono C# Shell, type "help;" for help

Enter statements below.
csharp> Shell.record("public void Main(string[] args)");
csharp> using System;
csharp> Console.WriteLien("I prototyped this in csharp shell!");
(1,10): error CS0117: `System.Console' does not contain a definition for `WriteLien'
/home/tyler/basket/lib/mono/2.0/mscorlib.dll (Location of the symbol related to previous error)
csharp> Console.WriteLine("I prototyped this in csharp shell!");
csharp> Shell.save_record("Hello.cs");
recording saved to "Hello.cs"
Which could conceptually generate the following file:
using System;

public class Hello
public void Main(string[] args)
Console.WriteLine("I prototyped this in csharp shell!");

JavaScript Shell

In addition to the C# shell, I've been playing with v8, the JavaScript engine that powers Google Chrome. The V8 engine is capable of being embedded easily, or running standalone, one of the examples they ship with is a JavaScript shell. I've created a little wrapper script to give me the ability to load jQuery into the V8 shell to prototype jQuery code without requiring a browser to be up and running:

tyler@pineapple:~/source/v8> ./shell
V8 version 0.3.0
> load("window-compat.js");
> load("jquery.js");
> $ = window.$
function (selector,context){return new jQuery.fn.init(selector,context);}
> x = [1, 5, 6, 12, 42];
> $.each(x, function(index) { print("x[" + index + "] = " + this); });
x[0] = 1
x[1] = 5
x[2] = 6
x[3] = 12
x[4] = 42
The contents of "window-compat.js" being:

* Providing stub "window" objects for jQuery

if (typeof(window) == 'undefined') {
window = new Object();
document = window;
self = window;

navigator = new Object();
navigator.userAgent = navigator.userAgent || 'Chrome v8 Shell';

location = new Object();
location.href = 'file:///dev/null';
location.protocol = 'file:'; = '';

In general I don't really have anything insightful or especially interesting to add, but I wanted to put out my "+1" in support of both of these projects. Making any language or API more easily accessible through these shells/interpreters can really help developers double-check syntax, expected API behavior etc. Thanks Novell/Google, interpreters rock!