Using C# like a scripting language

Clift Norris wrote a clever little batch file csrun.bat several years ago. I thought I’d posted it here, but apparently not. If you have a C# program in foo.cs, you can type csrun foo.cs to compile and run the program.

The batch file doesn’t do much at all, but it might change how you think about a C# program. The C# code is still compiled, but since the compilation step is hidden, it feels more like an interpreted language.

When someone says they like interpreted languages, maybe what they really mean is that they enjoy running code quickly without the overhead of starting up an IDE, compiling the code, navigating to the directory containing the compiled executable, etc. This has nothing to do with whether a language is compiled or interpreted.

@echo off
REM : Compile and run a C# source file.
REM : The C# compiler (csc.exe) must be in your PATH.
REM : The command line argument is expected to be something like foo.cs

if "%1"=="" goto USAGE

csc.exe /nologo /out:%1.exe  %1
if ERRORLEVEL 1 goto EXIT

%1.exe	%2  %3  %4  %5
goto EXIT

:USAGE
echo You must specify an argument representing the C# file you want to run.

:EXIT

This batch file does not set references; you’d need to modify it if you want to reference an assembly.

Update: CsharpRepl is a REPL (read-evaluate-print-loop) that lets you write C# at the command line as you would most scripting languages. CsharpRepl is part of Mono and works cross-platform. Thanks to MikeG in the comments.

Related post: Visual Studio 2010 is a pig

21 thoughts on “Using C# like a scripting language

  1. Don’t suppose Windows batch scripting has anything like sh’s $@ for globbing all the passed options instead of just passing positional ones? What do you do when your app needs more than four passed options? Maybe Powershell scripting would be better on Windows.

  2. Matthieu Villeneuve

    (I would argue that there is no such thing as an “interpreted language”, as far as I know, no language spec forbids compilation nor interpretation. I guess that expression could generally be replaced with “language in which programs are usually interpreted”…)

    Actually, I think that in that family of languages, there are two things people enjoy even more than being able to start a program without going through the whole compilation process:

    1. the ability to interact with the code being written (the CsharpRepl project fills this need),

    2. the (relative) high level of abstraction that comes with those languages: programs generally take less developer time and lines of code in Python or Lisp than in C or Java (except of course when for the most part, program features come already implemented in libraries).

  3. Michael M: PowerShell is far better than batch files, and this script could be extended in numerous ways. But in my opinion, the script’s charm lies in being so simple and so low tech, just a few lines of code in the most primitive programming language.

  4. It is also worth noting that MS is moving into that direction. The whole Roslyn C#.next tech preview has an interactive C# command prompt, and a new C# script file type where you can just write statements and don’t need to wrap things in classes etc. Probably all still a couple of years away, but still.

  5. davidacoder: I would like to see that. Requiring all functions to be part of a class is annoying, especially on small projects.

  6. I’ve been working intermittently on a small project called coderunner intended to do something like this for “any” language. One command (cr, nice and short) to execute any source file, possibly compiling first if the language is a compiled one. It is written in C++ for Linux, since I have no personal experience with Windows programming.

    The project is still in an early stage, but the basics are there. I don’t often find a lot of time to work on it.

  7. @Michael M: you can use the special %* syntax to get all parameters. However, in this case it won’t work because the first argument is used as the name of the executable.

    PowerShell would be better, but that would complicate the command line invocation (unless running from the psh command line).

  8. There’s also Linqpad (http://www.linqpad.net/), which handles a little like the Visual Studio “Immediate” window on crack – for me it’s the best way to explore new APIs, prototype small pieces of code, etc without dealing with the Visual Studio IDE in all its bloat.

    That said, one of its nicer features (“intellisense”) is pay-only.

  9. Compiling and executing in one sequence is hardly interpreting, is it? The difference between compiled and interpreted code is surely that interpreting ‘compiles’ and executes the code statement by statement, which is vastly different from what this batch file does.

  10. haughtonomous: Tthe simple idea of compiling and executing in one sequence is nothing like interpreting as far as the computer is concerned. But I think it makes a psychological difference when you first see it. If you firmly associate C# with Visual Studio, this creates a little mental separation between the ideas.

  11. reminds me of using TCC with c++ you can make a script like this:
    #!/usr/local/bin/tcc -run
    #include
    int main()
    {
    printf(“Hello Worldn”);
    return 0;
    }
    save as whatever.c and call it with ./whatever.c and it will compile and run.

  12. Why mess around with lamo command files as described here when you can do much better with LinqPad: http://www.linqpad.net/

    They have a free version but I’d pay extra for the intellisense (it aint much).

    p.s.: I have no economic interest in the product or company. I’m just a happy customer.

  13. Live coding against unit tests

    I use a kind of live-coding setup when developing small pieces of code, particularly against unit tests. You put the compilation and test execution commands in a bash script (cygwin where needed) in an infinite while loop. Each time around, the loop compares the timestamp on the source file to the compiled file, and if it sees that the source has been updated, recompiles and reruns.

    The upshot is that every time you hit save in your editor, the tests rerun and the output updates. Having these two windows side-by-side give an immediacy beyond even interpreting or REPL.

Leave a Reply

Your email address will not be published. Required fields are marked *