89 comments

[ 3.0 ms ] story [ 68.7 ms ] thread
I should look into it, but it seems to support multiple lines. So the ideal use case would be to add a seperate window into Visual Studio
Wouldn't that more or less be the Immediate Window that Visual Studio already has? Other than the multiple lines you mention. :)

I took a look at this to see if it can replace LinqPad, which is similar. LinqPad allows for more than C# alone (VB.net, SQL, C# and F#) but it has no code completion (unless you buy it) which CShell does have.

This seems like a useful tool!

The immediate window is fairly limited. It can't evaluate lambdas for example, so you can't quickly write linq.

Possibly more like linqpad?

I highly recommend buying a LINQPad licence. I use it several times a day now and it's so much better with the extra features.

My favourite feature is the ability to point it at a DLL which has an entity data model in it - and then work with that model 'live' as if you were inside app code.

Normally, to do that, you'd have to put a breakpoint in your app and use VS's Immediate window - which doesn't support useful stuff like lambdas.

this is pretty cool, thanks for sharing! will see if I can integrate this with Excel-DNA.
What "I/O error occurred"? I mean the IntelliSense hint on the screenshot.
Looks to me like the description of `System.IO.IOException`, which is the possible exception.

I would guess the tool tips are slightly broken in that it doesn't list the exception class name or put it on a new line.

There you go, simple thing to contribute a fix for!

Good point, I might go ahead and make a patch.
That's what an IOException means. I suspect the hint text stems from a very minimal XML parse of the documentation.
This may be useful for loading GBs of data and it's quick exploration but I am wondering if there are any other uses for it besides that?
well it's as useful as any other REPL ;)

Though for things like Python the REPL serves for me mainly as a 'figure out what type this thing is here' and 'does this work'... things that static typing solve pretty well.

A C# REPL is welcome indeed, but C# is still too verbose for its own good. The F# REPL is much more useful when exploring dataset.
Although it could be improved with intellisense.
A combined REPL and editor for C# looks useful. I will try it next time I have some spare time.

The name is confusing. A C shell already exists (http://en.wikipedia.org/wiki/C_shell). An alternative name could be CSharpShell. Btw, while googling that name, I found CsharpRepl, which seems to be a somewhat similar tool.

(comment deleted)
These tools straddle some Venn circles, so the developer pitch can be confusing.

For example, I make use of both ipython and bpython, both of which I refer to as either shells or REPLs; though neither program is a proper shell (in the /bin/chsh sense), and though people also call them “interpreters” (technically, the python interpreter still interprets), “environments” (vague) or even “IDEs” (wat?) – the concept behind the tools is popular and well-understood.

Personally I think it’s particularly funny to call these Enhanced REPL Shell Interpreter Environments (or what have you) “IDEs” and lump them in with Eclipse or Visual Studio or those other behemoth coding tools; I like bpython and ipython for the myriad ways they are un-Eclipse-y, and if I did C# I would presumably get into CSharp for the same reasons. All of which, like many bicycle-shed innovations, are mere matters of taste.

Well presented. I clicked the link and spent my loading-spinner time thinking thoughts along the lines of "This is silly. Why would anybody build a C# IDE to compete with VS.NET + ReSharper? Surely nobody would ever use anything but that??? I can't believe that anybody would be cheap enough to..."

... and then I arrived at a page that spent ten seconds clearly explaining exactly why I would want to use this thing even though I have VS.NET already installed on my machine.

A lot of open source & developer-facing small product sites in the world would be well served to read the contents of this page and study exactly what the author did there.

Well done!

The title would have been better if it said C# REPL. Then you wouldn't have experienced that confusion.
To be fair, the SharpDevelop people did just that and it's actually quite good. Of course it doesn't measure up to VS.Net but if VS.Net didn't exist it would be really impressive.
Very cool and useful, thanks!
Not very often you find a hedge fund behind an open source project. I guess it makes sense really, as many quants will be happy to mess around in a python shell, having a C# shell will probably play nicer with the rest of the companies infrastructure.
(comment deleted)
There are a few hedge funds that are quite happy to contribute open-source to the world.

Blue Mountain Capital for example;

https://github.com/BlueMountainCapital

One of their projects is Deedle; an F#/C#-equivalent of the Python 'Pandas' data frame package. Which would in fact make a nice complement to CShell I imagine.

Jane Street would be another choice: http://janestreet.github.io/

Their work on OCaml is currently trending on HN.

There are others I am sure, don't have any links handy.

Who'd a thunk it, hedge funds occasionally produce some social good ;-)

wow, didn't know that. thanks for putting together that list - maybe we should start a list somewhere where people can add, this is definitely super interesting.
(comment deleted)
This is exactly what i need to test out if some code behaves how i want it to, without having to create a new test, open a new project or running code in actual project.
I've just started using scriptcs (http://scriptcs.net/) and this looks pretty similar.

I'm not sure about the name. CShell implies C not C#.

Looks like uppercased CS is a play on a file extension and a shortcut sometimes used for C#. Personally, I read it as CS-hell.
Agreed I would have gone with SharpShell
Seems dead - last commit ~1 year ago?
As much as i like C#, static typed languages are inadequate when using them in shell. You really don't want to type all that.

Powershell has access to the BCL and can do all that with a nicer syntax when using it in the shell.

It depends. I mostly use PowerShell when trying out things with .NET, sometimes before or while I'm implementing them in C# as well. But depending on what I want to do, LINQ is a very nice thing to have, even though PowerShell has similar capabilities with the pipeline. (Can't really point to anything specific right now – there are instances when I prefer PowerShell and those where I prefer LINQ.)

One major reason might be speed, though. PowerShell can be very slow on large-ish data sets. And var in C# saves you from a lot of type-typing.

>static typed languages are inadequate when using them in shell. You really don't want to type all that

I'm not sure I understand, what is wrong with dynamic in C#? You've got the anonymous types for quick data structures.

(comment deleted)
Did you even look at the link? It is about a REPL for C#.
If your language has you type more because it has a static ype system then it's just poor at inferring types and/or it's syntax has you write out things that it could infer anyway. You may have to write types in C# from time to time, but often you don't have to:

// This an array of integers.

var x = new[]{1, 2, 3};

// This is a list of integers.

var y = x.ToList();

// This is an anonymous type.

var pet = new { Age = 10, Name = "Fluffy" };

Zero type names there. Not all types can be inferred by literals though, most annoyingly dictionaries:

var myDict = new Dictionary<string, string>{ { "test", "test" }, { "test2", "test2" } };

although I'm sure that could also have been created without typing out the name if you really wanted.

Inferring types is cool, if it doesn't create bugs. But it does. Its not a lot of work to just say it outright, and it can save your life.
Can you elaborate? I'm not sure what you mean.
Unexpected conversions can add bugs. Putting a string into a table that was implicitely integer - if your string doesn't start with digits it gets converted to zero. Was that what you intended? Did you think the table would hold a string?
So it's not actually the type inference that's the problem -- it's developers who carelessly define implicit conversion operators on their classes.
Strings have built-in conversion, right?
Not the kind you seem to be thinking of.
Type inference in C# with the var keyword doesn't work like a dynamic language like javascript. It works by simply using var as a placeholder for whatever type the right hand side returns, which is determined at compile time.
So the type depends upon the initial values, which might not be representative of your full intent? A list of strings doesn't guarantee you won't want later to put something else in there.

I guess you'd just have to declare it explicitly in that case.

Yep, like if you wanted to put a list behind an IEnumerable interface or something like that, instead of an actual list. It's just a very useful shortcut for the thing you want to do 90% of the time.
Why would you want to put anything other than a string in a list of strings ? That's just looking for trouble IMHO.
But you could explicitly declare the string table and still try to put an integer into it. Your example isn't an issue of type inference, it's an issue with the developer not properly tracking what variables store what types in his/her own code.
(comment deleted)
Literally never seen a bug from using var. Please elaborate on a common bug you encounter when using var and type inference.
They're doing dictionaries in CS6.
That's sad. They should do tuples and top-level functions and solve it naturally.
They are doing a hack for top-level functions - they're adding "using" for static classes so you can pull all the static methods of a class into the local namespace. Don't see how that would help for dictionaries, though.

The ugly part of the dictionary is the type parameters, but I can't see a workaround for that without some really hard type-inferencing for all generics. I mean, you'd have to infer the type-parameters of a generic class based on the type-parameter of the IEnumerable passed into its constructor (dictionary takes an IEnumerable of KeyValuePairs of TKey, TValue). That's a little messy.

I was alluding to F#'s handling:

  > let myd = dict [ "a", 1; "the", 2; "train", 3 ];;
  val myd : System.Collections.Generic.IDictionary<string,int>

  > let myd = dict [ "a", System.String.IsNullOrEmpty ];;
  val myd : System.Collections.Generic.IDictionary<string,(string -> bool)>
If C# had tuples, then you might be able to do something like:

  var myd = createdict(new[] { {"a", 1} , { "the", 2} ...})
The tuples should get a type inferred, then the array, then that can pass the type to createdict and all good. And the array could be removed if there was some other sort of list-like literal. This might be really difficult to implement in the C# compiler, for all I know.

More likely, they'll graft in yet another special rule in the compiler (not accessible to user code!), just as they did with other collections, foreach, async, etc. I find it ugly that the compiler is happy to use static duck typing when convenient, but such a feature isn't exposed in the language.

I guess I'm old. My first thought was http://en.wikipedia.org/wiki/C_shell
It probably should have been named CSShell :-)
But I read it as CSS hell. Maybe SharpShell? Anyways, both are better than the original IMHO.

By the way, this is really useful. Loaded all our app libraries and works like a charm. I feel much more productive now except for the fact that it made me comment on HN =)

SharpShell would be a great name - fun alliteration and pretty clear what it's for.
I like it, will consider it. The naming is a bit unhappy, I agree.
And considered it harmful.
The point of scripting is to do things quickly at the expense of possibly being ugly. Most of the things we do in the UNIX shell are one-off local stuff. I want to rename all file extensions in a directory. I want to find a regex in files ending with .c and .h excluding the .svn and .git directories. Etc etc.

So I'm sorry but a "scripting" language whose print operator is longer than 5 chars is not a scripting language :)

    Action<object> print = Console.WriteLine;
I mean, it's not perfect but you can also create a .Dump() extension method for all objects like Linqpad does. It comes really handy.
Also, I like Scala REPL's automatic labels for the results.

    scala > 7 * 7
    res0:Int = 49
    
    scala > res0 - 9
    res1:Int = 40
Saves a lot of typing.
I want this, but with nuget support. LinqPad seems about the best option, but i don't need all the SQL/Database stuff that comes with it.
First of all, let me say this is something I've wanted for a while, so good job and thank you to the author.

When I try the Tutorial.csx, I can't get this snippet to work:

static class MyMath { public static long Fibonacci(long n) { //anything more than 48 will result in a stack overflow. if (n >= 48) throw new ArgumentException("Enter a number less than 48"); if (n == 0) return 0; if (n == 1) return 1; return Fibonacci(n - 1) + Fibonacci(n - 2); } }

// Now the method can be called like so: MyMath.Fibonacci(12);

It gives me : "(14,0): error CS1525: Unexpected symbol `MyMath'" in the repl, anyone knows why?

Same here. No idea. If there were any docs (other than the "tutorial" itself) I'd try to look it up :))
Yep, I see the tutorial is not clear, will change it.

Anyhow what you need to do is simply select line 35-45 with your cursor, then press Alt+Enter.

And then, after that, execute MyMath.Fibonacci(12);

I'm getting "(35,0): error CS1525: Unexpected symbol `static'" trying to run Tutorial.csx (when MyMath is uncommented), whether running the entire script or just the class and the MyMath.Fibonacci call alone, by Run Selection (then it's "Unexpected symbol `MyMath'").

public static class Foo { public static string B; } Foo.B = "5";

doesn't work either ("Unexpected symbol `Foo'").

I really don't get how to use that thing.

After fiddling around for a short while I got an index out of range exception and it crashed. It seems like a good idea, but the execution is not that powerful yet. Not stable, so I'll pass for the time being.

Error 2014-05-09 15:42:45.8796 AppBootstrapper Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index at System.Collections.ArrayList.get_Item(Int32 index) at CShell.Modules.Repl.Controls.CSRepl.ShowPreviousCommand() in c:\Users\luke\Dev\GitHub\CShell\Src\CShell\Modules\Repl\Controls\CSRepl.xaml.cs:line 241 at CShell.Modules.Repl.Controls.CSRepl.TextAreaOnPreviewKeyDown(Object sender, KeyEventArgs keyEventArgs) in c:\Users\luke\Dev\GitHub\CShell\Src\CShell\Modules\Repl\Controls\CSRepl.xaml.cs:line 377 at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) at System.Windows.Input.InputManager.ProcessStagingArea() at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) at System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32 scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey) at System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(MSG& msg, Boolean& handled) at System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(MSG& msg, ModifierKeys modifiers) at System.Windows.Interop.HwndSource.OnPreprocessMessage(Object param) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

the thing is you can't really mix class definitions and straight scripting lines in one execution. So what you need to do, is execute the class first and then execute the other part.

For the MyMath example you'd just select the lines for that class, press Alt+Enter. And then run: > MyMath.Fibonacci(12);

With your example, you would enter following in the REPL: > public static class Foo { public static string B; } > Foo.B = "hi" > Foo.B hi >

Thanks for clearing that up. I believe this should be explained more specifically in the tutorial.
Scriptcs is out there for quite some time now. http://scriptcs.net/ it also has the motto "Unleash your C# from Visual Studio."

It provides you proper scripting abilities by using other libraries, writing classes in the REPL and scripting, like proper scripting languages. CShell just seemed like a windowed application whereas Scriptcs also runs on Unix environment with Mono I guess.

I mean this as truly constructive criticism. There are several spelling errors on the site that made me want to cringe.

It allows you to use C# without any fluff right in a console like environment caled a read-eval-print-loop (REPL).

CShell is a project sponsored and maintained by Arnova Asset Management Ltd., a quant hege fund, which uses CShell daily for their research. The main contributor from Arnova is @lukebuehler.

That said I like this idea and look forward to trying it.