11 ms·
As languages go, C# may be the ultimate "middle ground" because it really excels and providing a middling implementation of [your-favorite-language-feature]. T
by jordan0day 14y ago
As languages go, C# may be the ultimate "middle ground" because it really excels and providing a middling implementation of [your-favorite-language-feature].
That is, if you're a functional programming enthusiast, you can do a lot of functional programming in C#. Sure, it's often more painful than haskell or lisp or F#, but it's workable.
If you're a dynamic programming enthusiast, C# has a perfectly workable (but ultimately unsatisfying) implementation of dynamic.
Systems programmer? Mark your code as "unsafe" and twiddle bits to your hearts content! It's not as quick or necessarily easy as C, but it's there!
Even its' OOP, which is C#'s "official" paradigm, is probably disappointing to smalltalk guys, but hey, it's better than Java, right?!
It's not glamorous or flashy, it's a workhorse language. And at being a workhorse language, I'd say it really is one of "the best".
- nnq 14y agoWhy is C#'s OOP disappointing to Smalltalk guys?
- bigdubs 14y agoWell, off the top of my head C# doesn't support mixins or multiple inheritance. You can get around the lack of mixins with extension methods and tight scoping but it's messy.
- SeanLuke 14y ago> Well, off the top of my head C# doesn't support mixins or multiple inheritance. I was not aware that Smalltalk provided either.
- dfox 14y agoThere are libraries that add both of these features at once (either by defining new (meta)metaclasses or by simulating same effect through simple copying of methods from base classes.) On the other hand, Smalltalkers are quite keen on adding new methods to almost any existing system class, so mixins are not often as useful. Also Smalltalk development often relies on IDEs that do pretty extensive code generation behind the scenes and I think that this image based development with no real source code to speak of, and lots of reflection based development tools, is more important aspect of Smalltalk than any OO features.
- king_magic 14y agoC#'s (and Java's) lack of multiple inheritance is a virtue, IMO.
- bigdubs 14y agoI generally agree that use of mixins / multiple inheritance leads to architectural missteps.
- nnq 14y ago...aren't they completely different tools? One uses mixins to keep the class hierarchy shallow, with fewer levels of inheritance. OTOH multiple inheritance tends to complicate an overly convoluted class hierarchy most of the time. It's true that in a language like Python people use multiple inheritance to "simulate mixins", but it's to the same good effect of keeping the class hierarchy short and flat, but in C++ at least I've never seen MI used to simplify things, as opposed to mixins that always seem well used...
- amirrajan 14y agoThat is a false statement. dynamic C# 4.0 can do mixins: http://amirrajan.net/Blog/dynamic-c-sharp http://amirrajan.net/Blog/dynamic-c-sharp
- bigdubs 14y agoso, yes this leveraging of dynamic metadata provider technically satisfies the requirements for a mixin, but you're still not applying this mixin to a poco, therefore i don't think it's fair to say the language/spec supports it natively. this is another example of adding mixins to .net code via 3rd party library: http://remix.codeplex.com/ http://remix.codeplex.com/
- amirrajan 14y ago"but you're still not applying this mixin to a poco" Clarify?
- bigdubs 14y agoPOCO = Plain Old (CLR) Object The distinction I'm drawing here is what is meant by 'natively supports' and 'supported via a 3rd party library'
- amirrajan 14y agoThat's what I need clarification on. the dynamic keyword wasn't provided by any 3rd party library (it's part of the C# language specification)... how is System.DynamicObject and IDynamicMetaObjectProvider different then System.Object? All poco's inherit System.Object. Do you consider System.Object as 3rd party? True, by default poco's don't inherit from System.DynamiObject. Does that make it not 'natively supported'?
- bigdubs 14y agoNo, what I mean by that is in order to use mixins, in any example I've seen, you need to inherit from a class someone else provided that gives it. Assembly provides all the mechanisms for the dynamic keyword, I wouldn't say it is a feature of x86.
- dfox 14y agoMostly because it looks like Java and on the first glance also shares Java's mostly static type system (which is not strictly true). The gist of it is: you can send arbitrary messages in Smalltalk (and ObjC) and the object itself deals with them somehow (with most of that being implemented by runtime anyway, but that is different issue). In C# you call methods defined by interface. Also, you cannot modify arbitrary parts of standard library and runtime, but that is probably for the better (doing that is pretty common in ST world).
- benzor 14y agoSorry, but you're really attacking a straw man here. Neither C# itself nor the OP's article sell C# as being a prime language for functional, dynamic, or systems programming. Rather, it has inherited some convenient little bits of each paradigm to make the language that much nicer to write. For example, don't want to redeclare that "List<List<LongTypeName>>" you're copying over because it has a scope of 2 lines? Just dynamically type it by calling it a "var" and be done with it. Boom: Cleaner code and zero performance hit because the compiler infers the type such that the resulting IL is identical at runtime. Sure, given features can be misused to produce ugly or "unsatisfying" code, but that's true of any language and is ultimately the programmer's fault. Just because said features are provided, doesn't mean you need to use them. You should ultimately be using the right tool for the job, after all. C# gives you the power of having a wider choice of tools, and I love it.
- MichaelGG 14y ago"var" is not dynamic typing. It's just a way to enable type inference - it's still as static as can be. It also has a very limited useful scope in C#, as type inference isn't supported in most areas.
- migueldeicaza 14y agoThere is only one place where the type inferencing is not supported, field declarations. Not sure how that became "most areas".
- kvb 14y agoThere are several other limitations. For instance, method signatures can't be inferred. In F#, you can write member this.AddOne(i) = i + 1 and AddOne will be inferred to have the signature (int -> int). There are plenty of other annoying restrictions, too, such as locals defined by lambdas.
- MichaelGG 14y agoMiguel I'm confused then - your experience with Mono certainly means you have a better understanding, but I thought I understood it pretty well, too. Places lacking type inference: - Parameter definitions - Method return types - Generic type parameters (sometimes) - Lambda expressions (due lack of syntax to indicate quoted code) - Field declarations The only place type inference works for declarations is in local variable declarations and lambda parameter types if the delegate type is known. Perhaps the definition of "most" is arguable, but C# has many places that need you to unnecessarily specify types, and there's no good theoretical reasons for any of it, right? (Except the whole syntax sharing for expression trees versus anonymous functions, which is debatable.)
- MichaelGG 14y agoThen why use C# over F#? F# has a more flexible dynamic system (provide your own implementation), better type inference, and even more unsafe access. So you lose nothing but goto and a bit of loop flexibility. In theory, a better JIT could provide as-good-as-C output, but in practice you end up screwing around and ending up with less-than-optimal machine code. But F# actually provides an advantage here: inlining. The F# compiler can inline any function, whereas the JIT is somewhat limited in what it will inline. This makes a big difference, as the CLR JIT does a much better job optimizing inside one function than it does cross-function.
- jordan0day 14y agoI guess one thing I left out in my post that I should have added was: it's easy for people to learn. I bet just about anyone with much programming experience can spend 5 minutes looking at C# and understand most of the language. It's familiar enough for anyone from a C/C++/Java/JavaScript/PHP background that it's not intimidating, even at first blush. I bet C# is more comfy for a lot of Ruby and Python folks, too. I really, really, really like F#. The main problem with F# isn't a language or syntax problem (in fact, it's not a problem at all). F# (or other functional-first languages) isn't just different syntax-wise, it's different thinking-wise. A "good" F# program is generally written in a fundamentally different way than a "good" C# program. This is the declarative vs. imperative split. Sometimes it's really hard to convince people to change the way they think about how to go about solving a problem.
- oddthink 14y agoJust an aside: I don't think you can really say "dynamic programming enthusiast" to mean "dynamically-typed language enthusiast", since "dynamic programming" already means something quite different. It threw me a bit, at least.
- jordan0day 14y agoNice catch, I probably should have said "dynamic programming language enthusiast".