It Already Is A Scripting Language

My recent post about the possibility of considering maybe someday perhaps adding "top level" methods to C# in order to better enable "scripty" scenarios generated a surprising amount of immediate emphatic pushback. Check out the comments to see what I mean.

Two things immediately come to mind.

First off, the suggestion made by a significant number of the commenters is "instead of allowing top-level methods, strengthen the using directive." That is, if you said "using System.Math;" then all the static members of that class could be used without qualification.

Though that is a perfectly reasonable idea that is requested frequently, it does not actually address the problem that top-level methods solve. A better "using" makes things easier for the developer writing the call. The point of top-level methods for scripty scenarios is to make it easier on the developer writing the declaration. The point is to eliminate the "ritual" of declaring an unnecessary class solely to act as a container for code.

Second, and more generally, I am surprised by this pushback because of course C# already is a scripting language, and has had this feature for almost a decade. Does this code fragment look familiar?

<%@ Page Language="C#" %>   
<script runat="server">   
  void Page_Load(object sender, EventArgs e) 
      // whatever

Where's the class? Where are the using directives that allow "EventArgs" to be used without qualification? Where's the code that adds this method group to the event's delegate? All the ritual seems to have been eliminated somehow. That sure looks like a "top-level method" to me.

Of course we know that behind the scenes it isn't any such thing. ASP.NET does textual transformations on the page to generate a class file. And of course, we recommend that you use the "code behind" technique to make a file that actually contains the methods in the context of an explicit (partial) page class, to emphasize that yes, this is a class-based approach to server-side processing.

But you certainly do not have to use "code behind". If you're an ASP traditionalist (like me!) and would rather see C# as a "scripting language" that "scripts" the creation of content on a web server, you go right ahead. You can put your "top level" methods in "script" blocks and your "top level" statements in "<% %>" blocks and you'll thereby avoid the ritual of having to be explicit about the containers for those code elements. The ASP.NET code automatically reorganizes your "script" code into something that the C# compiler can deal with, adding all the boring boilerplate code that has to be there to keep the compiler happy.

But consider now the burden placed upon the developers of ASP.NET by the language design. Those guys cannot simply parse out the C# text and hand it to the C# compiler. They've got to have a solid understanding of what the legal code container topologies are, and jump through hoops -- not particularly difficult hoops, but hoops nevertheless -- to generate a class that can actually be compiled and executed.

This same burden is placed upon every developer who would like to expose the ability to add execution of end-user-supplied code to their application, whether that's in the form of adding extensibility via scripting, or by enabling evaluation of user-supplied expressions (such as queries). It's a burden placed on developers of productivity tools, like Jon Skeet's "snippet compiler", or LINQPad. It's a burden on developers who wish to experiment with REPL-like approaches to rapid development of prototypes, test cases, and so on.

I am not particularly excited about the convenience of the ability to save five characters by eliding the "Math." when trying to calculate a cosine. The exciting value props are that we might be able to lower the cost of building tools that extend the power of the C# language into third-party applications, and at the same time enable new ways to rapidly experiment and develop high-quality code.

Of course we do not want to wreck the existing value props of the language in doing so; as I said last time, we also believe that there is huge value in the language design naturally leading professional, large-scale application developers towards building well-factored component-based programs.

Like all design decisions, when we're faced with a number of competing, compelling, valuable and noncompossible ideas, we've got to find a workable compromise. We don't do that except by considering all the possibilites, which is what we're doing in this case.

Comments (51)
  1. Jonathan Pryor says:

    To take another view on this…

    C# could use a REPL interface.  REPL interactivity must support, at minimum, statements (though I’ll admit that methods & classes would also be useful).

    From this perspective, we already have "top-level" methods: anonymous delegates. πŸ™‚

    Anonymous delegates are statements, and thus can be entered within a REPL wherever a statement is permitted (i.e. ~everywhere).

    Of course, the downside is that the syntax to declare a "method" is different, but the call-site is the same…

  2. Jeff Yates says:

    For me, the concerns of a top-level declaration are the abuses of a "global" namespace. I think that if the compiler treated the file as a class (i.e. when compiling it wrapped the file contents in a class if there were globally defined methods or variables), then this would mitigate that issue and allow for both implicit and explicit cross-file method references by using the filename like a classname. Of course, that brings other issues such as file names containing illegal characters.

  3. Ben Voigt [C++ MVP] says:


    I guess you are suggesting file scope for top-level functions and variables (they aren’t really methods and fields any more), such that they aren’t visible outside the file?  That sounds like a good solution to the problem of pollution in the global namespace and fears of action-at-a-distance.  C++ offers this via the nameless namespace.

    But you wouldn’t simply wrap the entire file content in a class, you’d want type definitions to still be visible outside the file.  Note that including this anonymous static class in the lookup order for unqualified names without containment or inheritance is perfectly alright, the name resolution rules are part of the language/compiler, not the .NET runtime.

  4. Matthew Kane says:

    I would prefer if you had a toolkit that made it cheaper and easier to build tools and REPL interfaces, but under the hood it still doesn’t allow global abuse. Think globally, act locally!

  5. configurator says:

    I agree with Matthew. If you do make it possible to introduce top-level functions, I’d suggest making them internal only; having no public top-level functions would also solve the pollution problem.

  6. Jason says:

    "It Already Is A Scripting Language" – by various technical criteria, sure. You, however, used the term "scripty" regarding programming languages which I think captures what you meant well.

    So while C# may be a scripting language because it meets various technical criteria, that technical criteria doesn’t mean the language itself is "scripty". Programming in C# certainly doesn’t feel like working in VBScript or JavaScript or any of the zillions of scripty/functional languages out there. It doesn’t lend itself to super rapid development, and there is nothing wrong with that.

    So even though it already is a scripting language, from the comments it seems clear most developers using C# don’t want to have it feel like a "scripty" language.

    Speaking as someone with years of experience in ASP.Net, under no circumstances would you embed C# "script" in the page for anything substantial anyway. It’s not about emphasizing a class based approach; it’s about creating something that can be maintained and enhanced because it was constructed in an organized manner, out of many smaller components.

    Global functions are pretty hard to build reusable components out of. Not to mention even with top level functions in ASP.Net it still needs custom syntax / custom implementation to import namespaces / implement interfaces / hook up the event handler to the event / etc.

    Adding execution of user supplied code to applications is trivial (thanks to you guys, of course!) –  Heck, you can always just generate the code yourself and compile it at runtime ( If you want to add really good support for user extensibility, you need a lot more features than just a scripting ability anyway.

    So what exactly are you making easier? The 1% of the overall task?

  7. Denis says:

    Why not concentrate on improving the interoperability between C# and the existing scripting languages, rather than making it more "scripty", or "scriptical", or "scriptified", than it already is?

    Just a couple of weeks ago we were chewing rocks with frustration on our next project, trying to implement a tree view that reflects a SharePoint list with folder structure AND does not jump back to the top node after the post-back, when the user selects something in it (we HAD to handle the SelectedNodeChanged event on the server side, hence the post-back).

    With better interaction between JavaScript on the client side and C# on the server side – by being able to directly refer the C# objects in JavaScript and JavaScript functions in C# – it would be A LOT easier to tame that SharePoint beast (and no, I have not forgotten ICallbackEventHandler: it didn’t work too well, either, in that case; and using Something.Attributes["attribute"] = "value" does not look very intuitive to me).

    The dynamic type from C# 4 solves most of these problems on the server side; how about being able to control, on the client side, whether or not a server-side event handler should be called, and if yes, then with what parameters? How about better control over the post-backs, so that only the controls that have been changed are re-rendered, and only enough to reflect the change, rather than re-rendering the whole thing?

    Some would say, just use Silverlight/WPF, and I would agree, but not our Government client who only just (!!!) switched to Win XP SP 2 for their workstations. And the customer is always right, isn’t he? πŸ™‚

  8. Linus Torvaldz says:

    There are other programming languages that already have the properties you desire from C#.

  9. Ben says:

    The ‘scriptyness’ of F# is one of its major selling points for me. I even find myself using F# to test out future C# algorithms, or even bits of the .Net framework – so much easier than creating a solution/project/gumpf, just for two lines of code.

  10. Anthony Tarlano says:

    +1 for doing..

    It is the one thing that I would most like to be more compatible with Python and F#!

  11. <script runat="server"> is not a good design anyway, my understanding is that it exists for compatibility with classic ASP?

    Now <%= %> and <%# %> expressions are another matter, but they demonstrate that theoretically speaking top-level methods would not be enough — top level expressions/statements are more like what is required (this is true for LINQPad as well).

    While it is probably possible to support these on compiler level, just providing a managed library to compile such code would be more than enough (and that library internally may use class wrapping/method wrapping, or somewhat else entirely). In this case, you would have a solution for LINQPad/ASP.NET (do snippet compilation with new library is you want globals, but use standard compiler for classic development).

  12. Leopold says:

    have a look to the mono guys at

    they implemented a REPL almost a year ago

  13. Great response Eric.  Fundamental changes like this tend to worry me, even if they’re only proposed! lol.  It’s great to see these things being discussed and it’s also reassuring to see how they are regarded by you guys at Microsoft.

    +1 respect to your blog (I’d click the upvote button but this isn’t SO).

    Very good point about the ASP.Net scripting by the way!

  14. TheCPUWizard says:


    Your point is valid, but leaves out what I believe to be one important fact. The ASP.NET features you posted do not exist (except possibly as literals) in a .cs file!

    As soon as one sees an .aspx or .asmx they are aware that they are dealing with a different syntactical domain.

  15. commongenius says:

    The fact that ASP.NET allows you to declare a method without a class does NOT make C# a scripting language. The defining features of a scripting language is not top-level methods, its top-level statements (PLEASE tell me you are not considering adding top level statements).

    No, the defining feature of a scripting language is that it can be used to extend existing applications by programmatically controlling the functionality exposed by those applications.

    But that said, of course we are considering the consequences of adding “top level” statements. You want to be in a REPL environment and have to have every statement you type in be in a method? That would be silly.

    Now, supposing we do make more things top-level, how to package it? Whether this syntax makes it in to the mainline language, or whether we expose a special “repl/script mode” on the compiler service that changes the allowable syntax to be more accepting, while keeping the mainline language the same, is a question about how the functionality is packaged

    Frankly, that does not interest me very much; I am more interested in how the semantic analysis of the language changes if the functionality exists at all. If it exists at all, someone has to design all possible interactions of new “top level” entities with the existing ones, and that’s a potentially hard problem. Changing the packaging is easy; we already have lots of logic in the parser to allow or disallow parsing of certain features depending on switches. — Eric

    Regardless, anyone who has done any significant ASP.NET development understands that the ASP.NET inline model is exactly the reason why we don’t want that model spreading to the rest of the language: it is extremely difficult to maintain and does not lend itself toward good design.

    Again, I think the C# team needs to stop thinking of itself as the only player in the field. There are several good scripting languages on the .NET platform already, and I imagine more will emerge. C# should stay focused on what it was designed for: component-oriented application development.

    You think that we think of ourselves as the only player? We just spent a year adding features that let us more easily interoperate with Python. Is that the action of a team that considers itself the only player? We are well aware that the .NET platform is a multi-language platform; we spend a lot of our time trying to make it easier for C# to interoperate seamlessly with many other players in this space. We love that there are lots of players in this playground because ultimately we are about making the platform more attractive to all developers. — Eric

  16. Joel says:

    I’m of the opinion that the .NET languages should not become one kitchen sink language.  Which is what appears to be happening.  If you want to have free scope functions and variables, use C++/CLI.  If you want a true OO language, stick to C#.  If you want a hybrid functional/OO language,  use F#.  They are all interoperable with C# via the .NET framework and runtime.

    There are plenty of scripty languages out there already.  The joy of the .NET framework is that interop between the various language domains is relatively painless.  To complicate C# by adding dynamic types (as opposed to inferred types) and free functions IMHO dilutes its usefulness, and its utility in its core development space.

  17. Greg says:

    C# and, as joel said, not be a catch-all for any type of language or language feature.  This will make them less and less desirable to use for production code.  

  18. Scott says:

    I’d be excited about losing the Math. since it means that I could just type cos(whatever) instead of ComplexMath.cos(whatever) or similar for cosines of non-double types.

  19. commongenius says:

    “No, the defining feature of a scripting language is that it can be used to extend existing applications by programmatically controlling the functionality exposed by those applications.”

    Such a definition is meaningless, especially in the managed world. The ability to extend an application is entirely dependent on what capabilities that application exposes to be extended; it has nothing to do with the language used to create the extension.

    It’s very meaningful to the person who has to write the extension. — Eric

    “We just spent a year adding features that let us more easily interoperate with Python. Is that the action of a team that considers itself the only player?”

    Yes, in my opinion, the addition of dynamic (or rather the way in which it was implemented) is further evidence that the C# sees itself as the only legitimate language in the .NET world.

    Maybe I’m just getting grumpy in my advanced old age, but I am finding myself increasing irked by people who are not me telling me what my thoughts, beliefs, opinions and principles are. Particularly irksome is when my alleged opinions are in fact the opposite of my actual opinions.

    A common criticism levelled many times in the comments to my last couple of posts is that the language has “everything including the kitchen sink”, or “is trying to be all things to all people”. Though I understand how one might come to that conclusion, nothing could be further from the truth.

    It certainly is the case that we seek to increase the scope of the language by “making it easier”. As I pointed out in my recent blog article of that name, by making some tasks easier in the language, we run the risk of unnecessarily complicating the tool. We take that risk very seriously and carefully weigh the potential damage caused by every change; we have extensive design reviews with industry experts to make sure that the risk is worth the benefit.

    But it certainly is not the case that we seek to make the language all things to all people. We intend C# and VB to be the premiere language tools for professional developers of real-world bet-the-company-on-them business applications, whether those applications are traditional forms applications or server-side content generation, or something else entirely. That is the core unchanging principle underlying the design of the language; that cannot change because that is the business justification for the whole product. The purpose of this product is to lower the costs of professional application development and thereby make our platforms — which we sell for money — attractive.

    So now consider what the costs and risks are to different kinds of customers. Suppose you’re running a team of professional C# coders, and you have the belief that a particular problem is better solved in Python than in C#. It is entirely reasonable to ask questions like “will it be cheap and easy to adapt our existing C# codebase to make use of the new Python functionality?” or “will our testers be able to adapt their C# test framework to test the Python code?” If the answer to those questions is “no” then that is a barrier to adopting Iron Python into the software ecosystem of the team.

    If that were the case, and if we on the C# team actually had the belief that C# should be all things to all people then we would be rubbing our hands in glee and chortling evilly at this point. Another customer trapped in C#, yay! But that is not our belief; our belief is that customers should be free to use all the powerful CLR-based tools at their disposal to solve their problem as they best see fit. Every time we on the C# team make it harder for those tools to interoperate, we create a barrier to our customers getting their problems solved. I WANT people to use Python and F# and VB and JScript and Ruby to solve their problems, and I do not want their existing investments in C# or VB to create disincentives to use new languages.

    — Eric

    Dynamic compromises the design principles of the language in an attempt to influence developers to implement functionality in C# that would be better suited to other languages.

    You seem to believe those design principles are carved in stone. They are not. Those design principles evolve as the needs of our customers evolve. The design principles of the language are what the design team say they are, and we say that the design principle of “.NET is a multi-language paradigm; C# interoperates well with as many other languages as possible” is a more important design principle than “the C# language is strictly typesafe”. (And besides, the language was never strictly typesafe in the first place. Reflection, unsafe code, runtime code spitting, array covariance, and allowing casts that might fail at runtime all break type safety in some way. We have already “compromised” that principle many, many times while always trying to remain true to its core concept.)

    We have altered many design principles of the language over the years as the industry has changed; if you were to read the 10+ year deep archive of language design notes, you would see that an original explicitly stated core design principle was “no magic” — that is, it should be easy for the reader of the code to imagine at a pretty low level of abstraction exactly what is happening on the machine level. And now we have anonymous functions, iterator blocks, local variable type inference, query comprehensions and dynamic calls implemented by spitting new IL at runtime and caching the results in a call site object — the language is chock full of “magic”.

    Of course, when faced with a conflict between two design principles, we always attempt to find the compromise that meets our needs while conforming to the spirit of all our principles. Finding such a compromise is not always easy, and there are many disagreements both within the team and in the industry that the right compromises were reached. You can’t please everyone.

    Second, no, the feature is not intended to encourage dynamic programming in C#. It is intended to facilitate interoperability with libraries and objects designed for use in dynamic environments (including legacy COM objects which use IDispatch as their primary interface to the world.)

    Had we intended to encourage “dynamic language style” development in C#, we certainly would not have stopped at enabling dynamic call sites! C# 4.0 is embarrassingly weak as a dynamic language; compare it to, say, JScript, with its prototype inheritance, ubiquitous “expando” objects and ability to redefine basic parts of the language, like the Number prototype. Even the fact that “dynamic” was made a part of the statically analyzed type system indicates the primal importance of static type analysis to the design of the C# language. We want rigidly defined areas of doubt and uncertainty, as Douglas Adams famously wrote. — Eric

    Implementing the desired interoperability using interfaces, and remaining type safe, would have been more consistent with the design and purpose of the language;

    Every design decision entails a compromise. You are of course free to disagree that we achieved a compromise that adequately meets our goals. There are many ways to design this feature; I prototyped up several different ways to do “dynamic” before we arrived at the implemented solution. — Eric

    but it also would have made it more likely that developers who prefer dynamic typing would remain in the dynamic world as much as possible, and only move to C# when they had to. This, in my opinion, would have been a good thing!

    Dynamic programming should be done in dynamic languages; C# doesn’t have to be everything to every programmer.

    I completely agree. We seek to increase the number of programmers who can successfully work in dynamic languages in .NET by lowering the cost of modifying existing bodies of C# code to work well with code written in dynamic languages. — Eric

    But instead, the C# team is throwing caution to the wind and encouraging dynamic programming to be done in C#, which is ill suited for it.

    I completely disagree. First, we take caution extremely seriously, and I take great offense to the utterly unfounded accusation that we do not. We spent multiple hundreds of person-hours — and some of those persons are exceedingly well paid — considering the impact of this design decision. Second, we are not encouraging dynamic programming to be done in C#; we are encouraging rich interoperability of a traditional statically-typed programming model with both new code written in dynamic languages, and legacy COM objects designed for use in dynamic language environments. Of course, any tool can be misused; I encourage you to not misuse it. — Eric

  20. MaBerY says:

    I suppose many of those features expressed here are covered in Microsoft’s own PowerShell language.

    Why would anyone want an interpreted C#

    Who said anything at all about “interpreted”? — Eric

  21. Steven says:

    Calling methods without qualification, like your example with System.Math, is exactly what troubled me last year when I was working on a big VB.NET project. VB allows this kind of syntax and it is terrible for readability and thus maintainability. By allowing this syntax, we might gain 5% while typing code, but we loose 30% while reading code. Therefore I am against adding such a feature to C#.

  22. Thomas Krause says:

    Ok, first of all, don’t take the comments on these posts personally. You know how easy it is to exaggerate or even throw unbased accusations at you or your team on the internet if you are not speaking face to face.

    Indeed, I am well aware! — Eric

    These people don’t even mean it personally. They are just concerned that their voice is not heard by the C# team, even if your blog alone is proof enough, that this is not the case.

    I know. But I find it pragmatic to occasionally firmly remind people that the C# team is made up entirely of people. Moreover, people who take their responsibilities extremely seriously and care deeply about the long-term viability of the whole developer ecology on our platforms. — Eric

    As for extending C# with top level methods:

    When I’m developing with VS I don’t mind the overhead of declaring a class for my methods, because that is largely handled by the IDE and file templates. So tooling is an important thing to consider.

    However as I said in my last comment, I can see the benefit of global methods in embedded screnarios, where you use C# to script a third-party application, but this can be done without extending the general language. You could do this with special library support (exposing the functionality from e.g. ASP.NET or T4 to “embed” C#) or by making the compiler pipeline more flexible.

    Sure. Those are all ideas that we’re knocking around. But no matter how we package the functionality, the fact remains that if we do the feature in any form, we’re going to need to fully design the semantics of all interactions between new and existing “top-level” entities. That’s going to be the interesting and difficult problem in this space. — Eric

  23. Marcjon Louwers says:

    If you add top level methods the global scape will become cluttered like PHP.

  24. concerned says:


    My big concern is how "top-level" the methods/functions are.  Are these truly global?  Or will they always be contained in within a namespace, giving the user control over which are visible within a particular scope?

    I think many people are worried a potential "global" mess – every ex-C++ programmer has run into this before. πŸ™‚

  25. Alex O. says:

    Good discussion.

    I agree with MaBerY that PowerShell lends itself nicely for executing user-supplied code, when late-bound extensibility is desired. Since PS can access .NET classes it is a great batching tool and lowers the entry bar on the technical skill required to write simple (or quite sophisticated) scripts.

  26. Don Burnett says:

    Interesting use of c# in scripting for Unity 3D ( you should check it out..

  27. Craig B says:

    I don’t get the entirety of this post, nor the responses of people.

    What are we talking about? Is this for adding a feature to a strongly-typed language in order to make method invocation ambiguous in order to lower development cost?

    No, to my knowledge, that’s not what this post is talking about. This post has nothing to do with ambiguous method invocations. Some of the comments might be about that, but that’s not what this post is about. This post is about evaluating the benefits and costs of providing a standard mechanism whereby tool providers can make it easy to let their users define what look like “top level” methods in C#. — Eric

    Wouldn’t it be smarter to lower development cost in this case by choosing a different language that already offers the feature you’re talking about? Why add it to C#?

    It might be smarter. We will not know whether that is smarter or not until we evaluate the costs and benefits of a number of different alternatives. We add features to C# because we believe that the benefits of enabling the compelling scenarios outweighs the costs. — Eric

    To me, the value of the various languages offered within the .NET family are their differences, and the boundaries around each of them. This is what provides developers choice, and funnels different classes of developers (organized by goals/priorities) to appropriate languages/grammars. To me, the power of C# is the rules of the game it employs, and in turn the higher quality of code and maintenance ensues therein.

    And this is meant to be personal, but not meant to be offenseive… I did read your About section below, and the fact that I read that you started off working on runtimes for scripting environments makes me immediately understand why you are looking to bring those ideals to C#. But if scripting is your hammer, don’t let C# be your nail.

    Though that is relevant, what is probably more relevant is my years on the VSTO team, trying to figure out how to make C# extensions to Office work in a seamless and attractive way. It was very difficult to do so; the new C# 4.0 features will make it easier, and I hope we can make it even better in the future. — Eric

    In light of features that would be useful in this sort of arena, there have got to be better, more openly reusable ideas for C#. Like, for example, why I cannot create a String populated with what looks like a class and, at runtime, compile it to get a Type. Can I not do this in VB.NET? Is this not purely a .NET problem, what possible reason other than feature selection woudl it be offered in VB.NET and not C#?

    This feature is supported by JScript.NET. Baking in that feature required careful compiler design from the ground up. It would be quite difficult to shoehorn such a feature into C# or VB, when the compilers were not designed for that. — Eric

    In the end, there are bigger fish to fry than getting rid of “Math.”. I have not encountered a senior engineer that complains (especially, to the point that they refuse to do it at all) about how extension methods also must exist in an arbitrary static class. At least, then, the class name matches the file’s name, which makes maintenance straightforward.

    As I’ve said a couple of times, the compelling benefit of top level methods has little to do with the call side. Saving those five keystrokes is not interesting. The compelling benefit is for the convenience of the people writing the callee side. — Eric

    And in the end, it can’t always be about cranking out code faster. Quality engineering devotes time and energy to concerns with maintenance, to the point that we sacrifice productivity during invention to produce an elegant solution our business can live with once we’ve completed. What we have to live with is ultimately more important than how we manufacture it… ask any engineer starting a new job that has to inherit someone else’s code. πŸ™‚

    It’s our goal to make tools that make it possible for users to produce high-quality implementations in low time. That’s the definition of “productivity”. We want to improve both on the quality and the time side of the equation. — Eric


  28. Wardy says:


    You have made many valid points and thus far I have been impressed with the path the C# language is taking but along my travels I have seen many people complain about the language.

    When I ask what the issue is the reply after some debate is simply "Because Microsoft are still trying to take over the world" … personally, if a product is great it will flourish, you guys know your stuff and do it well, that’s why your technology and tooling is used by mmost of the planet not because Bill threw money and beat people in to submission with lawyers.

    I think that this does however highlight that whilst Microsoft generally get it right they often make a mess of things too (eg. Vista) and this could be one of those situations if it’s done wrong.

    I agree with some of the suggestions above like the math class for example, it’s used everywhere so why not, even half the system namespace could likely be used this way if it was really thought out, but lets not forget that one of the main pulling points for the C# language is that core structure, it works after all and this could be fatal overkill if it’s introduced to heavily.

    Whilst in principle I agree, I think its a potential very thin line to walk.

    On the other hand ….

    Just because a feature is there it doesn’t have to be used right?

  29. Ryan says:

    I’m responsible for making sure other developers are writing quality code.  My concern is that C# is quickly becoming a language that is too easily abused and that I’ll spend more time telling junior developers what not to do other than what to do.  I understand Msoft’s business need to make a highly interoperable platform that allows easy integration in heterogeneous enterprise environments.  However a new feature like this would be more appealing to me if there were someway I could turn it off (like a compiler switch) when I know that I, and everyone else on my team for that matter, shouldn’t be using it.  

     Var is a great example of a well intended and quite essential new language feature that is being severely abused (imho).  Since the arrival of var, I rarely see developers type out the actual type anymore.  If I remember correctly, both Richter and Lowy recommended not even using type aliases because they could lead to confusion.  Now I don’t even see those anymore.  I just see var everywhere.  It hurts readability when used like that.  Its not that big a deal, however it does seem to be an indication of things to come.  I’m just waiting to see dynamic popup for parameters everywhere.  Also, Hearing that VB and C# are going to be on the same roadmap going forward is disturbing.  Will C# become more like VB or VB like C#?  I hope the latter.  To sum up what I’m trying to say, if you guys want to enhance C#’s scripting features, please at least give me some way to turn them off.  Thanks for taking the time to read this.

  30. TheCPUWizard says:

    Ryan’s comments echo mine. Being able to "audit" usage of features which can be abused is [imho] VERY significant. Yet it can still be bypassed…

    I had a client a while back that had very reasonable restrictions on what .NET assemblies could be referneced by various types of developed code (e.g. no using Windows.Forms in a "Server" application.)

    One developer really wanted to use a helper from an assembly, but knew that the process would flag it if he referenced it. So he loaded it dynalically and accessed the desired routine via reflection. This made it all the way through the QA cycles and was actually deployed into product for a few months before it was detected. [He no longer works there, for this and other similar "cleverness"]

    Ryan’s concern that "I’ll spend more time telling junior developers what not to do other than what to do.", is already a regular and significant part of my time with many clients…..

  31. Michael Ginn says:

    Steve Jobs said, "Be careful who you sell to, because they will control your future."

    Your audience is biased toward strong typing because no one survives in the C# without going through the motions of strong typing.

    I respect the strong-typers if only because of their numbers.

    There is also a huge dynamic programming userbase I’ll call the "dynamics".

    The dynamics know there’s a huge group of strong-typers and they respect that. So dynamic programming shouldn’t be done under the ".cs" extension, but rather under the ".css" extension.

    Dynamics grew up on Lisp and Perl and then Ruby. But they’re weary of languages defined by implementation rather than specification. They also hate calling .Net when it means marshalling native types into strings and back out into .Net types.

    Dynamics want C# with dynamic typing, functional programming (F#), and unrestricted Linq usage. They love the enhancements of C# and just want to see them rounded out so that syntax isn’t so awkward for Monads and map-concats and backtracking predicates and local variable-binding pattern matching. They would please also like symbols.

    But strong typers say there’s no need for this in C#. Strong typing is discipline which yields code which can be by a theorom-proven to be less buggy than untyped code. I spend  about five times more time fussing with types than I ever spent tracing incorrect code usage.

    I think C# was designed with only one mistake: C# was advertised as a "safe" language like Java, but some people think it’s free of GPF’s only because of compile-time method binding. Those who were raised on Pascal were suffering wound’s from abuse of C’s (void *).

    But functional programming techniques combine well with optional strict typing. Like the "unsafe" keyword, there should be a "dynamic" keyword for use only by trained professionals who will take responsibility to ensure the objects they pass to a function respond to the right interfaces. In return, they are liberated from time spent typing and coercing and so forth.

    A dynamic function takes either a fixed or possibly varying number of arguments and has the value of the last expression it evaluates. A yield from a called function causes a yield from the innermost nested iterator. The syntax is C#, but the programming is two times faster.

    Dynamism is needed in C# for these reasons:

      – rapid prototyping

      – maintaining code

      – programmer productivity

      – code clarity

    Example 1: Clarity

    Here’s a line from my recent program C# 3.0:

    g.DrawLine((float)(Math.Abs(4*Math.Sin(Math.PI*v)+CenterX), 0,0,0);

    This is fine for people who are religious about strong typing. But is it really less bug-prone than:

    g.DrawLine(abs(4*sin(PI*v)+CenterX), 0,0,0);

    I know the strong typers need to be satisfied and let’s give them the entire ".cs" filespace, past, present and future, to litter with their restrictions.

    But if we’re honest, which is faster to write? Which is easier to maintain? I’ve made several mistakes with the SIN function and the parentheses, but I never forgot my typing.

    What about:

    float i = (float)Math.Sin(1/2);

    Have we really solved the obvious problem? The compile-time strong-type policeman didn’t warn me about this being the same as:

    float i = (float)Math.Sin(0);

    In any dynamic typing language I would have known I had to take personal responsibility for passing the correct arguments to my functions and I would have written:

    i = sin(1.0/2.0);

    Strong typing didn’t save me here. It doesn’t save me from subtle issues governing decimal conversions.

    A method written to an ultra-specific type won’t generalize to work with other objects. I’ll have to create an interface and integrate it into the code.

    And I’d better have access to the source code because I can’t extend certain classes, etc.

    See, most of the time strong typing requires that I think about distinctions which have little to do with the problem I’m trying to solve.

    There are two things which come from Functional Programming. From the "neat" side come strong typing, Monads, and unchanging structures (these are already present in C# but are way to ugly when defining functions as first-class objects). From the "powerful" sometimes scruffy side comes dynamic typing, implied type coercion (if I go to the trouble to define methods to convert between types I want it to be used all the time!!), continuations, parallel processing integration, asynchronous IO integration, better control over calls between browsers and servers, and fully extending Linq’s power into C#. (I know you’re doing some of this anyway; please be orthogonal in your approach!)

    I am creating a huge library with my current application and I may have to go to extra-ordinary lengths to make my library methods into non-brittle generalizable utility functions which are plasable for both maintanance (my religion on maintanance is the opposite of other posters- I find strongly typed libraries to be so brittle that significant changes require re-writing a HUGE amount of code. I have never used a library in a dynamic language which had problems because of typing errors. Range checks within conversino functions is all that’s needed!  Yes strong typing increases the theoretical analyzability of a program, but proving a program works using logic is and always will be too expensive a proposition. True program-theorom-proving neatness in programs is the hope of madmen).

    My bottom line: your current user base is a SUBSET of who WILL use C# in the future (just about every programmer will use it– it will be like English– because alternatives are dying).

    There’s no reason for F# to exist– it offers a different syntax from C# without need. The features should be integrated into C# and DISABLED by default through a compiler directive. The directive could be something like "–PROTOTYPE" to emphasize a buy-in to the strong-typing religion.

    I use C# all the time. What else would I use on .Net? A language like Ruby or Perl which is defined ad hoc by its implementation??

    If C# doesn’t become more dynamic, I will have to turn to F# or else create my own programming environment in order to make progress.

    I can discuss this from any perspective. I just fear this perspective is absent.

  32. Fredrik Bonde says:

    Hey,   Michael Ginn, why don’t you check out the Boo language, which is can use static typing (but with automatic type  inference) OR dynamic typing, all running on top of the CLR.

  33. Craig B says:

    To clarify some points you made:

    “This post is about evaluating the benefits and costs of providing a standard mechanism whereby tool providers can make it easy to let their users define what look like “top level” methods in C#”

    I wholly disagree. At no point do you examine the costs of maintaining the code you propose writing. The examination does not go far enough. There are too many respondents that consider your proposal a potential victim of abuse (and it WOULD be rampant), and there seems no appreciation for having to live in the house you build. Ryan and TheCPUWizard, above, seem to understand that. Most professionals that live with their own code as well as others’ code understand that.

    I find it fascinating the number of comments I’ve received that assume that we on the language design team are cowboys who will add any old thing to the language. How anyone can look at the design of C# and deduce that the designers don’t care about discouraging bad coding practices is quite beyond my comprehension.

    As I’ve stated many times, first off, this is an idea for a possible future language feature. We don’t have a design, we don’t have a budget, we have an idea. How we “package” the feature in order to ensure that we continue to meet our goal of being a “pit of quality” language is completely unclear; what seems likeliest if we do it at all is to make the feature a part of the “compiler as a service” API, such that the compiler itself will provide a service whereby it can accept “top level” methods and statements, and provide the same services on those guys that it provides today on sets of files: design-time analysis and code generation. Whether that would then drive changes into the actual language itself, or a variant on the language, is unclear. Either way, we have to design the semantics of the feature, which is the interesting part.

    — Eric

    Moreover, productivity is not defined simply by shortest time vs highest quality; it does not stop at the end of construction. You are using a manufacturer’s definition, but I think most of us engineers can agree, producing code doesn’t stop at manufacturer. Quality engineering requires planning, implementation, documentation, testing, and maintenance. Adding less-typed features to a strongly-typed language, at best, accelerates implementation, but increases the need on documentation, and ambiguates testing and maintenance.

    This is what I meant by ambiguous methods calls… if you’re reading code and the method call or “var”‘d Type is one of your own, and you can’t immediately recognize it because it’s been made unclear, then you’re wasting your time. And then, imagine it’s code using a Type that you’re learning, and your eyes don’t pick it up because your brain is too busy trying to find what you just read about, that’s just nonsense waste.

    “As I’ve said a couple of times, the compelling benefit of top level methods has little to do with the call side. Saving those five keystrokes is not interesting.”

    But you’re only addressing the first of my 3 sentences there… What benefit ARE you talking about that we’re not already paying with extension methods? Do engineers really care? It sounds like No.

    “This feature is supported by JScript.NET. Baking in that feature required careful compiler design from the ground up. It would be quite difficult to shoehorn such a feature into C# or VB, when the compilers were not designed for that.”

    Actually, I may have fibbed a bit. Microsoft.VisualBasic.VBCodeProvider and Microsoft.CSharp.CSharpCodeProvider each get a CompileAssemblyFromSource() method from CodeDomProvider, I think that fits the bill, and has been around since 1.1. So apologies for the poor example, though to the point, it’s not just JScript.

    But JScript can accept new code that runs in the context of already-running code. In JScript you can spit new code at runtime that accesses local variables by name, for example. Fully-fledged “eval” is a hard feature to add to a language post-hoc. Just providing an API that lets you spit a new assembly is comparatively trivial. — Eric

    Moving aside from the academic, how about we examine collision of such a feature? If I buy 3rd-party control X, which has a PI “global” property or method in it, it would collide with the one .NET comes with (I’m assuming you’d have them move it out of Math), or even one of my own. How do I call the one I want? How do I read the code and know which one I’m calling? How does the reader, 16 months and one generation of developer removed, not get utterly confused? And how does any solution garner an implementation that doesn’t look like namespacing (which is what we’d be trying to avoid!)? Is this a fair trade between inventor and user?

    Oh, and to Micheal Ginn, my man, why are you using 1/2 instead of 0.5? In any case, the proposals in this article wouldn’t resolve that issue either, what you’re shooting for is called VB.NET. If you’re writing a huge library, and you consider changes to be important to support, then how do your unit tests behave? Don’t you find them brittle as well? Therefore, is this really a C# problem? Moreover, your g.DrawLine() sample is not made more clear by removing namespaces, it’s made more clear by breaking that one line of code into multiple, separate, well-commented lines. It may look like more code, but you’ll thank yourself for it in 2 years when you revisit it. And it can’t be about performance, because there’s no way EITHER line you presented is performant in any way.

    I also believe libraries like you describe are perfect candidates for F#. It is a language of What, not How, and is specifically engineered to help solve problems in your kind of way.

    And back to Eric, seriously, as a consumer, I don’t care whether or not something is easy or hard to do. “Impossible” I might consider caring about, but I don’t see that word often in software, with good reason. I don’t want to know how difficult it would be to allow enums to define methods (like Java already has!), I want the feature because I’m doing it anyway (in a quirky way, via extension methods).

    All in all, the “cleverness” that CPU refers to is often a dangerous thing for business. Forcing a group of engineers to work with, maintain, code that someone created because it was neat, because they did it fast, did something clever (and therefore is the best judge of quality of their own code, right? Please note the sarcasm), is simple risk. Make the language more powerful, but don’t make it into another language (go invent that other language elsewhere!).

    And above all else, heed the feedback you’re receiving, as most of it seems negative.

    I do heed it. But most of it also seems to be massive overreaction, frankly.

    Luce was right. No good deed goes unpunished. People asked us loudly to have a more transparent design process. So when we come up with a completely unbaked idea that we’re kicking around to see if it might possibly work in some context, I mention it, because that’s transparency. And as a result I get fifty comments criticizing my unbaked idea for being unbaked. A little more positivity would be appreciated. — Eric

  34. Ryan says:

    Thank you Eric for taking the time to make this post.  I appreciate you guys reaching out to us.  I hope the input is useful.

  35. Dave Bacher says:


    When you are talking about top level functions — what you are really talking about is namespace global functions, correct?  That actually is a good idea — to have functions that are namespace global, and that when you include the namespace, become global to whatever module did the using statement.

    The classic example would be ASP.NET, where you have this all over the place:

    public readonly HttpSessionState Session()


      get {




    By all over the place I do, indeed, mean literally all over the place.  Usually, session and the other context variables are used heavily, and probably 95% of ASP.NET applications that are non-trivial reference it a few dozen times per request.

    The minimum scope operators to access it, however, is two — as shown.  There’s not really any advantage to that over:

    namespace System.Web.SessionState


    public readonly HttpSessionState Session()


      get {





    In the context of ASP.NET, we know we’re talking about the current Session.  We know what that means, in ASP.NET, and repeating the scope qualifier to get at a singleton then scoping that to get at the instance is not improving code clarity or quality.

    Which is why HttpRequest defines the property, and the derived classes (like Page) inherit the property.  Because having code that sprawls across the screen does not improve readability.

    The issue is that defining a convenience property like this breaks encapsulation; it is not a property of page, and it is not something page should be storing/retrieving.  It is environmental data, required to process the request.

    If aggregation were supported, it would be the "clean" way to handle it — but aggregation is not supported.  I can’t say "pull in the functionality of SessionStateConsumer and add it to the Page class" in C#.  I can say it in C++, from native code.  I could potentially delegate — but then I’m back at three qualifiers or exposing the convenience methods and repeating code.

    Also, there are legitimate functions in most applications that do not act on any object instance, and that belong to some genericly named static class that serves as a namespace just because they "have to be somewhere."  

    As long as by "top level," we’re talking "in a namespace, but outside of any class" — it makes perfect sense to provide that functionality.  There’s not any greater/lesser chance of collision than if they are in a namespace qualified class, you can always use the qualified name to get at the one you want, and it is cleaner than having a class that exists purely to scope the functions.

  36. I would love to be able to do something like:

    public class MyClass {

    public void ExecuteScript(String fileName) {

    String script = File.ReadAllText(fileName);

    ScriptingEngine engine = new ScriptingEngine();




    where my custom script would be able to interact with the code where it is running.

  37. Brad G says:

    I certainly like C# as a compiled language.  It being compiled is one of the many reasons why I like C# so much.  If people want a scriptable language, why can they just not use something else.  I guess it would be nice to have an interpreter for C# that would allow the use of "script", but for web pages, etc: isn’t scripting an old frame of mind that the language is trying to keep us away from?

  38. David Conrad says:

    Eric, the transparency is appreciated by some of us. Thank you.

    I guess I’m not seeing the cost for the developer of a snippet compiler or LINQPad. Probably because I’ve never tried to develop anything like that, but wouldn’t the necessity of generating a class wrapper around the code be a sort of one-time cost that you would pay during development, and be done with?

    Not that it would be free, but once you’ve written the code to wrap a snippet the user typed into a Snippet__Nonce$Class1, 2, 3, etc. for each snippet they enter, then Bob’s your uncle. It is a cost, surely, but a small one-time cost you would pay at the start of the project. It wouldn’t be an ongoing pain point, would it?

    Or is there something I’m not getting because I’ve never built anything like that? Like, something to do with the scope of variables created in snippets, different snippets needing to be able to see each others’ data, something like that?


  39. Mike M says:

    There are already scripting languages with top level functions that can access the FCL (JScript.NET, VBScript.NET, PowerShell).  Why not use them for your “scripty” scenarios?

    A customer says “I want to rapidly prototype up some new functionality that I’m considering adding to my two-hundred-thousand-line C# project using a REPL tool like other implementations of C# have.” You want me to tell that customer “well then, you should learn JScript!”? — Eric

    Further, you’re advocating a paradigm change, not just some syntatical sugar or new semantics that “fit” within the existing language (eg, LINQ).  Consider this scenario:

    And now I’ve got complete strangers telling me what I’m advocating. I don’t recall advocating anything. I recall stating that we’re consider some possibilities for ways to extend the reach and scope of the language. Furthermore, as I’ve stated already, various guises of C# already use the “top level” paradigm and have for a decade. That’s hardly a massive paradigm shift. — Eric

    1) Open a CS file.

    2) Look in a method implementation and see the following code:

    int i = Foo();

    3) With top level functions, you can no longer assume Foo() is a method in the current class.  As you put it, _consider the possiblities_:

    4) Have a headache just thinking about the amount of time you’ll waste debugging other people’s “scripty” code and memorizing which functions are top-level, which are in the current class, and which are in a partial class defined somewhere else.

    Yeah, I’ve learned through long experience that any time we so much as suggest the possibility of new language feature, the first feedback we always get is “other people — not me of course, but all the bozos I work with — are going to misuse this feature and make my life miserable.”

    It’s rather depressing constantly getting that deeply pessimistic feedback, but we don’t let it stop us from adding value. We got that feedback on generics, anonymous methods, iterator blocks, query comprehensions, extension methods, implicitly typed locals, lambdas, dynamic interoperability, named parameters, you name it and people will tell you that adding any feature to the language is the end of the world. I rather like all those features and I’m glad we added them. Try being optimistic about the skill level of your coworkers; you’ll be a happier person. — Eric

    Finally, using ASP.NET as a basis or justification for changing the paradigm of a language is foolish.  ASP.NET is a very heavy weight and high-level toolkit; the fact that it needs to use code transformation to achieve top level functions is to be expected.  This would be like someone arguing that Ruby needs multiple inheritance (not Mixins) because Rails uses code transformation to achieve something similar (of course it doesn’t).

  40. Mike M says:

    Thanks for your response Eric.  I hope you don’t mind me following up.

    > “using a REPL tool like other implementations of C# have”

    I don’t see how a REPL tool would _require_ top level functions as a language feature, although I’m probably missing something.  

    It does not. Rather, both features require that we carefully define the exact language syntax and semantics of “top-level” features. It would be foolish to do all the work to make, say, REPL work without even considering whether doing so enables other interesting features, like improving the story for “scripty” hosts. As I’ve stated several times, whether the “top level” feature ever gets moved into the main language or not is merely a “packaging” question. The interesting question for the language designers and implementers is what the rules are. As I’ve stated several times, the most likely scenario, were we to do the feature in a hypothetical future version, is that top-level methods would be part of the “compiler as a service” package that we would expose to compiler hosts. But why would we not consider the benefits and costs of exposing a language feature, if we were going to do all the work already to make it possible, albeit for other reasons? — Eric


    Dennis Lu’s thesis paper on a C# REPL ( seems to indicate that no syntax changes would be necessary.  If anything the lack of a “true” interpreter is what makes REPL tricky in C#, as Mr Lu points out in his thesis (page 15).  And as Miguel de Icaza points out in his post about the Mono REPL (, the top level functions are a “monoism”: part of their REPL tool and not the C# language itself.

    I agree that it’s inconvenient for a developer to learn a new language to do rapid prototyping.

    > And now I’ve got complete strangers telling me what I’m advocating.

    Sorry, I should have said “propose” instead of “advocate”.  I’m interested in what guises of C# already use the top level paradigm; perhaps you could add this information to your original post?

    > It’s rather depressing constantly getting that deeply pessimistic feedback,

    Many of the new features in C# 2.0 and 3.0 got me very excited, especially LINQ and generics.  LINQ to SQL & ADO.NET Entity Framework are absolutely awesome for rapid prototyping.  Generics definitely changed the way I have to think about code organization (as in the scenario I gave), but the added value was tremendous.  Maybe I’m being selfish or shortsighted (I don’t use REPLs, am happy learning a scripting language when I want to write scripts, etc), but I don’t see top level functions adding enough value to offset the downsides.

    I feel like you made some pretty rude assumptions (and responses — “deeply pessimistic”?) about what I was trying to say.  I’m not trying to attack your post, C#, or the idea of adding language features.  This topic interests me, I love C# (and it’s evolution over time), and language design is fascinating (to observe :P).

    Indeed, I understand that it is easy to take plain text as much more rude and hostile than was intended by the author. For example, I’m sure you didn’t actually intend to imply that I was foolish when you made the argument that using ASP.NET’s behaviour to justifying the proposed feature was foolish. Someone who reads less charitably than I do might have seen that as hostile, but I do not. — Eric

  41. Mike M says:

    The “compiler as a service” and language feature packaging concepts aren’t clear to me.

    They aren’t clear to us either. The community collectively asked us to be more transparent and this is what you get as a result. That we have no particularly coherent feature set, packaging strategy, or delivery plan that we can blog about is unfortunate, but you can’t have it both ways. You either get to see everything polished and beautiful right before we ship, or you get to hear the half-baked ideas we’re kicking around in the hallway and live with them being inchoate. — Eric

    I do see now how top level functions (and expressions, variables, etc) for the REPL or other rapid prototyping or Q&D extensibility/”scriptability” scenarios would be useful.

    Sure. Not everyone does. But we get asked for this kind of thing all the time, and when we show demos and prototypes of this sort of thing at conferences and user groups, we get big cheers and high fives, so apparently someone wants it. — Eric

    You pointed out earlier that said features would have to be carefully designed into the language specification.  Is this it to make the features actually useful/reusable/flexible (unlike the “Monoisms” in their REPL) without creating specialized branches of the language?

    That would be one nice benefit, yes. But the larger benefits of careful design is that you end up with a carefully designed language — a language that can be specified, implemented, tested, debugged and shipped to customers with some level of assurance that you can actually understand what the tool does. — Eric

    Would we then end up with a flavor (“host”?) of C# (“C#Script”?) that supports additional top level entities while the default csc.exe does not?  Sort of like Windows Script Host but at a much deeper level; in a model that allows developers to embed the host(s) in their own products?

    Maybe. That’s certainly an idea we’re kicking around. Or maybe we do what Mono does and only allow the tool access to the feature. If you read my past posts on language design, you’ll see we usually have several HUNDRED ideas for language features that we’re kicking around, and we usually do a small handful of them in a given version. — Eric

    Thanks again for your responses.

  42. Michael Ryan says:

        Eric, thanks so much for listening to community needs and desires regarding C# Scripting. Thanks even more for making great progress despite the industry’s sometimes bitter and reactive bias.

    The more I study C#, the more I realize it’s possible to do just about anything one can do in a scripting language (SL) like Ruby. What do Agile/rapid-prototypers want from their scripting languages? How much does it cost in C#?

        1. SL’s are often great at manipulating text; C# has a regular expression class that provides a great deal of that functionality.

        2. SL’s allow top-level functions; in C#, one can create a NameSpace class with which I can Sin() all I want; I just embed my class in NameSpace class and delegate to chosen namespaces

        3. SL’s allow untyped variables; in C#, define a class “Var” with implicit coercions and operator overrides and you’ve got it

        4. SL’s sometimes provide functional programming power through closures, anonymous functions, etc. C#’s got most of that

    5. SL’s don’t sweat small types; in C# design “Var” to architect good, solid, formal math

        6. SL’s have REPL for debugging and incremental development; some say it’s critical to functional programming; Mono already has it, so one hopes C# could also have it

        7. SL’s add value by saving programmer time; C# triples my productivity with intellisense (is this wrong?)

    8. SL’s allow run-time method binding & symbols; I’ll wave my hand and say “look at attributes and properties in the CLI” and possibly run a macro expander on the source for @Symbol syntax.

    Complaint #1: it’s slow. SL’s are supposed to glue together high-level functionality, so dynamism at some cost is expected.

    Complaint #2: tower of bable. If every IT shop or university group has its own flavor of “var”‘s, it gets messy. Do you convert back and forth to your own type? Are they “checking” or “not checking” for math overflows (watchout– the default is not to check!).

    Sometimes it makes sense to have different math rules. For kids learning trig maybe degrees are better than radians. In Agile land I use longs and doubles to cover all the variations I need for numbers, and coercion is silent but runtime-checked for errors.  This satisfies even my corporate RPG/AS400 giant manufacturing client. (Thanks for the ref’s to Boo and F# but I have to help hire the programming team so I need to stay mainstream).

    But when I render breaking ocean waves in real time I do my math (sometimes on the GPU) in 16-bit floats (precise to about 0.01% of a pixel, but terrible at repeated addition (1/100 is a repeating decimal and it doesn’t get much of a chance to repeat).

    Since REPL was deployed on Mono, C# scripting will happen no matter what.

    The C# team is in an ideal place to set ground rules for conquering the tower of Bable; Tribes sharing C-Sharp libraries with other Tribes.

    Bottom line:

    C# already gives more than enough rope for programmers to hang themselves.  The C# team could make the process a lot easier with:

         – Syntactic sugar (e.g. each point above benefits from syntactic support, especially regex and untyped vars and top-level namespace control (with the ability to resolve individual name clashes)) Obviously allowing Linq’s “vars” to get passed around would be helpful.

         – Framework Standards and Conventions

         – Additional dynamism under the hood and eval available in the freely distributed .Net3.5 binaries (don’t know if Emit ships in those or not).

  43. Zack says:

    don’t pollute the global namespace.

    Don’t extend using to allow "globalizing" static methods of classes.

    No global methods. All methods should be attached to a class. No Top level methods.

  44. Michael Ryan says:

    OK took a while but I figured out how to do scripting iautomatically in C# and VS without actually changing the language. I’m not saying how because nobody wants former RPG programmers to shove their global-variable approach to programming (operations on objects become messy because they don’t follow a set of invariants, etc.).  

    Like it or not, people can do this.

    My hope is that Microsoft will establish some conventions (ground rules) so that scripting frameworks can inter-operate and so that namespaces are relativized to company domains, etc.

    To prevent polluting the namespace I am taking pro-active measures. Every class in my projects has a short prefix radically reducing the chances of classname clashes.

    Also, since C# is supposed to be a "safe" programming language, I really wish coercion and math had "checking" on by default instead of off. Checking is needed because it’s straightforward to design databases to handle unfinished business (not easy, but possible). It’s not possible to design programs to run well with garbage data.

    What good is strict type checking if you’re left with what might as well be C’s void * longs?

    Maybe for time testing you could state for EVERY program run, in the output window, either "Checking is off; this may lead to undetected overflows and coercion errors in numbers.", or "Checking is on; overflows and explicit coercion errors will be detected, possibly reducing performance. Compare only with checking-enabled Java ."


  45. Mike G says:

    Thanks Eric for the glimpse into things to (possibly) come.

    A lot of negative reaction has probably been overstated, especially for something which is just an incomplete idea at this time. Still, I think the comments are born from a real fear of what can happen.  Just to illustrate: I work as a consultant going from client to client sometimes creating new projects, but often being called in to modify some C# code for which the original programmer(s) are long gone. Usually there is a very tight schedule for these changes and coming up to speed on existing code is paramount. Bad code is common (hey I’m not perfect either and have written my share of ‘bad’ code when under a deadline). Lately I have been seeing a lot seen things like this: var x = ProcessIt(GetAWidget("Blah", 5, theList.Find(item => == name)));  Abuses like this would likely drive me insane if it weren’t for intellisense. I can’t wait until (inevitably) these methods start returning dynamic types and intellisense goes out the window as well because someone couldn’t be bothered to specify a type. Yes poor code is possible without var, dynamic, and ‘scripty’ code, but if we keep making it easier for people to write unmaintainable messes in the interest of making code writing faster, we run the risk of being left with nothing but unmaintainable messes. In my opinion, it doesn’t matter a damn bit how long it takes to write the code. What matters is how long it takes to read and understand it. That said, I’m sure you guys realize this . So far I enjoy programming in C# more than just about any other language. Thanks for the hard work.

  46. Seth Morris says:

    (Too many comments for me to read this morning, so I may be duplication)

    If what you want from a script form of C# is simple, ad-hoc code, check out SharpScript ( It’s a fairly nice command-line script environment for .net languages. With a few alias statements and some simple helper classes you can do most of what you want from a scripting language right in C#, either in script files (a la VBS) or as arguments on the command line (a la perl -e).

    Their solution is to wrap what you give them inside the main() function of a command-line app, compile, and run. using directives are arguments (or part of your preferred environment) and prerequisite assemblies can be configured as needed.

    If what you want from a script language is write-only obscurity, lack of type checking, quick-and-dirty-hack-something-together-that-works-until-it-runs-in-production, use something else (for example, while perl can be beautiful, but it’s more often used that way).

    Of course, these days I’d rather just use PowerShell for most of my scripting. I’m not sure what C# provides over PowerShell with C# extensions except to those people who want to use .net on non-Windows platforms (are there actually people doing that with production code, instead of just toys and samples? I wouldn’t be surprised if there were, but i would be surprised if there were a lot of them).

  47. =8)-DX says:

    Hello there Eric,

    Thanks for the transparency and the good post. I’m not sure I 100% understand all the comments and discussion, but as a C# developer I would definitely like some means of allowing global namespaces. Personally I would prefer something on the lines of upgrading the using directive, something like:

    using System.Web;

    using global System.Math;

    Which would allow me to write Abs(x); in my code .. this would be transparent and very helpful.

    I think top-level methods if enabled should:

    – be enabled through a compiler switch

    – be directly declared for a given code-block/cs file

    – have syntax for unambiguous calling of particular methods.

    But of course I defer to the opinions of all the hard-core experienced C# coders out there.. I’m happy with the way things are.

  48. BillyB says:

    It seems to me that what would really add value to C# is not scripty global-level statemetns per se, but rather an easy-to-use mechanism for creating an isolated code execution context that can then be used to run user-entered script code.

    For example, say I’ve got a desktop application that I want to add scripting features to. What I’d really like to do is create a new execution context, specify what types and/or namespaces the code that executes in this context should have access to. maybe add references to some existing object instances, and then feed it a string to compile and execute within that context (maybe with some default using statements to absolutely minimize the amount of knowledge the script author needs).

    In a more complex scenario I might want to load multiple source files defining a bunch of classes into the same context so they can reference each other, or re-use the same context to execute a bunch of code snippets that manipulate the same data. But in each case the hard part of the problem is setting up that isolated execution context in a way that protects your app from rogue script code, and limits scripts to accessing only the types you want them to be able to use.

    Trying to create the same effect with AppDomains is an imperfect solution at best, requiring an application developer to write inordinate amounts of boilerplate plumbing code and even then giving only the most coarse-grained control over what the script can do. What’s really needed here is compile-time checking of type references and some automated handling of the AppDomain instancing and cross-AppDomain communication issues.

  49. Buck Pyland says:

    Actually, I could care less how "scripty" C# is or not. While it would be nice to be able to prototype and test things in C# without having to pay the compile-link tax, I’ll live without it.

  50. I don’t know much about top-level implementation, but I wanted to comment on who ever said they would like the C# langrage to accept "using System.Math" to make all members of said class local.  This would be an awful idea in my opinion as I spend a lot of time looking at other people’s code.  If this was allowed, then someone reading code would have issues keeping track of what the code is doing.  Furthermore, I would think that this coding pattern would break suggested coding standards.  The ides should never be to make things so easy that a even a monkey cam write code.  Heck, that’s why we have VB, right?  πŸ˜‰

    – Rashad Rivera

     Omegus Prime, LLC

  51. Peter says:

    Quote: ‘I am not particularly excited about the convenience of the ability to save five characters by eliding the "Math." ‘ End Quote.

    Me neither in such small example, but I would be a lot more excited about being able to bring a class with constants into scope, to be able to avoid lots of duplication.

    An example scenario can be found here ("How to β€œimport” a static class in C# ?":

    and I am now talking about the posting with SQL constants example, which would let you write this kind of code (if static imports a la Java would be possible):







               .WhereField(OrderDate, Compare.GreaterThan, DBConst.DateTime(ordersAfter))    

    You certainly do not want to spread out hardcoded literals with names of SQL elements but they should be located in ONE place only, i.e. a class with constants, which can be reused from many other classes, and thus it should be located in a class of its own, but then you get the problem of having to duplicated the class name (or an alias) and a dot before every item from the constant class.


Comments are closed.

Skip to main content