Partager via


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
}
</script>
...

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

  • Anonymous
    June 24, 2009
    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...

  • Anonymous
    June 24, 2009
    The comment has been removed

  • Anonymous
    June 24, 2009
    @Jeff, 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.

  • Anonymous
    June 24, 2009
    The comment has been removed

  • Anonymous
    June 24, 2009
    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.

  • Anonymous
    June 24, 2009
    The comment has been removed

  • Anonymous
    June 24, 2009
    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 ASP.net/SharePoint 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? :-)

  • Anonymous
    June 24, 2009
    There are other programming languages that already have the properties you desire from C#.

  • Anonymous
    June 24, 2009
    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.

  • Anonymous
    June 24, 2009
    +1 for doing.. It is the one thing that I would most like to be more compatible with Python and F#!

  • Anonymous
    June 24, 2009
    <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).

  • Anonymous
    June 24, 2009
    have a look to the mono guys at http://tirania.org/blog/archive/2008/Sep-08.html they implemented a REPL almost a year ago

  • Anonymous
    June 24, 2009
    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!

  • Anonymous
    June 24, 2009
    Eric, 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.

  • Anonymous
    June 25, 2009
    The comment has been removed

  • Anonymous
    June 25, 2009
    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.

  • Anonymous
    June 25, 2009
    C# and VB.net, 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.  

  • Anonymous
    June 25, 2009
    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.

  • Anonymous
    June 25, 2009
    "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

  • Anonymous
    June 25, 2009
    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

  • Anonymous
    June 25, 2009
    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#.

  • Anonymous
    June 26, 2009
    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

  • Anonymous
    June 30, 2009
    If you add top level methods the global scape will become cluttered like PHP.

  • Anonymous
    July 01, 2009
    Eric, 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. :)

  • Anonymous
    July 01, 2009
    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.

  • Anonymous
    July 02, 2009
    Interesting use of c# in scripting for Unity 3D (http://www.unity3d.com) you should check it out..

  • Anonymous
    July 02, 2009
    The comment has been removed

  • Anonymous
    July 02, 2009
    The comment has been removed

  • Anonymous
    July 05, 2009
    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.

  • Anonymous
    July 05, 2009
    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.....

  • Anonymous
    July 05, 2009
    The comment has been removed

  • Anonymous
    July 05, 2009
    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. http://boo.codehaus.org/

  • Anonymous
    July 06, 2009
    The comment has been removed

  • Anonymous
    July 06, 2009
    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.

  • Anonymous
    July 06, 2009
    Eric, 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 {      HttpContext.Current.Session;   } } 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 {      HttpContext.Current.Session;   } } } 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.

  • Anonymous
    July 07, 2009
    The comment has been removed

  • Anonymous
    July 07, 2009
    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?

  • Anonymous
    July 08, 2009
    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? Cheers!

  • Anonymous
    July 09, 2009
    The comment has been removed

  • Anonymous
    July 09, 2009
    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 (http://www.cs.rice.edu/~javaplt/papers/dennis-ms-thesis.pdf) 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 (http://tirania.org/blog/archive/2008/Sep-08.html), 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

  • Anonymous
    July 09, 2009
    The comment has been removed

  • Anonymous
    July 09, 2009
    The comment has been removed

  • Anonymous
    July 13, 2009
    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.

  • Anonymous
    July 15, 2009
    The comment has been removed

  • Anonymous
    July 16, 2009
    The comment has been removed

  • Anonymous
    July 16, 2009
    The comment has been removed

  • Anonymous
    July 19, 2009
    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.
  • Anonymous
    July 31, 2009
    The comment has been removed

  • Anonymous
    August 01, 2009
    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.

  • Anonymous
    August 17, 2009
    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
  • Anonymous
    April 17, 2010
    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# ?": http://stackoverflow.com/questions/1423809 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):            DBQuery.Select()            .Field(CustomerID)            .Count(OrderID)            .From(Orders)            .GroupBy(CustomerID)            .OrderBy(CustomerID)            .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. /Peter