C# 3.0: Lambda expressions. I don’t like it that much


This is the my third post on the series of post I am making on C#3.0 after it got declared on PDC. See the previous two here and here.


It’s not that I do not like lambda expression, I just don’t like that its being supported in C#. Lets first see what its like and then I’ll clarify on why I do not like it. If you are just interested on why I do not like it, go to the end of this post.


What is Lambda Expression


In C#2.0 anonymous methods were introduced ( πŸ™  I’m already using past tense on a product that is still not formally released). It required a little cumbersome syntax to create in-line function block like the ones supported by many functional languages. Lambda expressions in C# along with type inference give a cleaner (????) way of declaring and using anonymous methods.


Lambda expressions are based on lambda calculus. Many functional languages like Lisp use lambda notations to define functions. Typical lambda expressions in C# can contain both expressions and or statement blocks.


x => 2 * x // this is a expression
y => {return 2*x; } // this is a statement block

                    //
and not supported in the PDC bits.


Here the => is the lambda operator.


The following delegate and lambda expression are equivalent and the lambda expression here is automatically converted into a corresponding delegate.


delegate T Func<T>(T t);
Func
<int> funcDel = delegate(int x)
                    {
                        return
x + x;
                    };


Func<int> lambda = x => x + x;

Console
.WriteLine(funcDel(5));
Console.WriteLine(lambda(5));



For the lambda expression the type can be explicitly specified or it can be implicit and the complier can figure it out. So the above expression could be written as

Func<int> lambda = (int x) => x + x;



Lambda with Extension methods


Writing predicate functions for the extension methods becomes real easy with  lambda expressions. The System.Query namespace comes with nifty extension methods which use predicates. The following using the Where extension method prints out all the integers in the array which is less than 3

int[] a = new int[] { 1, 2, 2, 3, 3, 5, 6 };
var lessThan3 = a.Where(x => x < 3);
foreach(var val in
lessThan3)
    Console.WriteLine(val);



Type Inference and Lambda Expression


When a generic method is called without explicitly giving its type then the compiler can infer the type. In the following case both calls to GenericFunc is equivalent and will print System.Int32

static void GenericFunc<T>(T t)
{
    Console
.WriteLine(t.GetType().ToString());
}


GenericFunc(5); // Type is inferred
GenericFunc<
int>(5);



Just like any other expression when a lambda expression is passed as a parameter to a generic function it is used to infer the type. Lets take the following example which is a modified version of the one used in the C# 3.0 spec

delegate R Func<A, R>(A a);

// the generic function
static
Z FuncInfer<X, Y, Z>(X value, Func<X, Y> f1, Func<Y, Z> f2)
{
    return
f2(f1(value));
}


var size = FuncInfer(@”c:\vcvars32.bat”, s => new FileInfo(s), t => t.Length);



Lets see how the type inference happens here.



  • Since the first parameter is a string, compiler looks at it and infers X to be a string.
  • For the first lambda expression the input type is X so s becomes a string. Since it returns FileInfo the return type of it and hence Y becomes FileInfo.
  • For the second lambda expression Y is the input type and so t is FileInfo.
  • The second lambda returns FileInfo.Length so Z becomes long and hence size is a long and contains the size of the file passed as the first argument.

Why I don’t like lambda expression in C#


C# has originally developed from C++ /Java and is (was :^) ) a strongly typed object-oriented language. The new features being introduced like closure, continuation (yes, yes very limited continuation) in C#2.0 and now type inference, lambda expressions are de-generating the language. Even though there are people go gaga about continuation and lexical closures these are fundamentally functional language features and should be left to that. Introduction of bits and pieces of functional language features are not going to add value to C# and at the same time the surface area of C# is growing beyond what most developer can grasp.


Every language has a domain of application and an audience. Most people who work in C# developing web-services and web-based applications today are not necessary computer science grads. For them these concepts are a huge variation from the way C# used to behave. Functional programming is for the academia and not from the industry and should be left as such.


If I am asked, whether I’ll use these language features, my answer will be maybe, and that is because the code written by me will be reviewed and maintained by people in MS who are fairly conversant with these. However, I think these features add burden to the learning curve of people who are not super interested in C# and should be avoided in favor of easier language constructs’ that might take couple of lines of code more, but would be more readable and maintainable.


These are just my opinions and I’m sure the designers of C# had given a lot of thought before adding them, but I strongly feel that these features are just adding more surface area to the language and will mostly go unused by the masses.

Comments (59)

  1. Wesner Moise says:

    That’s why VB is target for Morts, programmers who didn’t study computer science. It hides the theoretical underpinnings of the language behind friendly syntax.

    C# and Java caters to Elvis-types, computer science folks, so the language emphasis I believe is correct.

    There’s an artificial separation between functional and object-oriented programming, as there was with relational and traditional programming languages.

    C# and most other langauges are multiparadigmatic. I would argue the expressions are traits of declarative, functional languages. I could also argue that relational algebra joins as a natural next step after elementary and boolean algebra.

    You have to go straight down to assembly to find a purely imperative language.

  2. Dan Glick says:

    I agree with you that the concepts behind lambda functions are probably beyond the grasp of most non-CS developers. But you don’t have to grasp all those subtleties to use them to simplify LINQ queries. It’s a lot easier–especially for the less-advanced developers you’re concerned about–to write .Where(x => x < 5) thqn to create delegates (anonymous or not) to pass to the query functions.

    The new language feature that concerns me more is type inference. I understand why it’s needed; but especially for coders who have a background in scripting, it may be tempting to use it when it’s not necessary.

  3. Patrick says:

    I completely agree, thanks for speaking out about this!

    I have been coding professionally in C# since the very beginning, and this syntax is confusing to me. I had to read over it multiple times before I can see what is really going on, which is never the case today when working with any C# code.

    The fact that it is no longer "strongly-typed", but the compiler is inferring the type, should be avoided. This just feels wrong.

  4. Gabe says:

    I think that you are looking at terms like ‘lambda expressions’ and ‘closures’, and thinking that the uninitiated will be confused by it. You have to realize, though, that there is no way to eliminate complexity in a program. You can move it around between the language and the program, but you cannot remove it entirely.

    Not only do we use things like lambda functions all the time without thinking about it, but look at how we live without lambdas. Consider this HTML:

    <input type=button name=Close OnClick="window.Close()">

    In C# 3.0 this could be:

    Close.OnClick += (s, e) => window.Close();

    In C# 2.0 this could be:

    Close.OnClick += delegate(object s, EventHandlerArgs e) { window.Close() };

    In C# 1.0 this could be:

    void Close_OnClick(object s, EventHandlerArgs e)

    { window.Close(); }



    // Ick! this trivial event handler is implemented nowhere near where it is being used

    Close.OnClick += new EventHandler(Close_OnClick);

    Now, you tell me which one of the C# examples is the easiest to read and understand? I think anybody would automatically try to write something like the first one, without knowing what a lambda function is.

    Consider this next example in C# 3.0 (assume myList.Sort takes a function that returns the sort order of two passed-in strings):

    void SortMyList(bool ignoreCase, bool ascending)

    { mylist.Sort(a, b => (ascending ? 1 : -1) * string.Compare(a, b, ignoreCase)); }

    or in C# 2.0:

    void SortMyList(bool ignoreCase, bool ascending)

    { mylist.Sort(delegate(string a, string b)

    { return (ascending ? 1 : -1) * string.Compare(a, b, ignoreCase)); }); }

    That’s quite an uncomplicated function, and its meaning should be obvious. Does understanding that function require understanding closures? No — and if it didn’t use closures, you would end up with 4 different sort delegates which would have to be selected at runtime by SortMyList, and you’d be thinking to yourself "Gee, I wish there was some way to pass a couple parameters to my sort function"!

    A closure is simply a function pointer and a local variable context. C# 1.0 delegates are closures because they include an object reference, so it’s too late to start complaining about them now. C# 2.0 anonymous delegates are lexical closures because they "capture" the local variables of the function where they’re declared. C# 3.0 is just the same as 2.0, only with a different spelling (you don’t need the ‘delegate’ and ‘return’ keywords).

    To summarize:

    * Closures have always been in the language, they’ve just been enhanced.

    * Lambda functions are just anonymous delegates that require less typing, which yields a higher signal/noise ratio, which makes code easier to understand.

    * Continuations have been around since C’s beginnings, with setjmp/longjmp, and are in a more limited form as exception handlers. There is no magic that makes them hard to understand.

    * Coroutines (functions returning with ‘yield’) are simply a much easier way to write iterators. They may be a bit confusing to comprehend at first, but that’s nothing compared to how complicated it is to write an iterator without them.

    Any language feature can be abused, but in my opinion, these features not only make code more readable and easier to write, most people will probably use them without even realizing it!

  5. tzagotta says:

    One way to evaluate these new proposed language features is how quickly one can pick up on them, and how intuitive they are.

    I’ve been programming professionally in C++ for 15 years, and C# for about 6 months. My first read about lambda expressions etc. leaves me kind of confused.

    Maybe I’m just dumb, or maybe you’re right – these types of constructs come from a different world.

  6. Nick Parker says:

    Based on what you said, it appears that you feel C# supporting more features typically found in functional languages will harm the overall appeal of C#, in particular to those who aren’t familiar with some of the more advanced concepts it supports.

    In my opinion, developers tend to use functionality that they understand. An example unrelated to C# could be:

    While there are many amazing things you can do with WTL, there are many C++ developers that don’t use it. Is it because it employs advanced concepts or possibly because developers might not feel they have a firm understanding of how it can help them? Just my two cents worth.

  7. Merit says:

    I’m not particularly crazy about lambda functions and I agree with you that "Introduction of bits and pieces of functional language features are not going to add value to C#", but I think your comments about keeping C# "easy" so the web monkeys can understand it are off base. That’s why we have VB.NET.

    Keep VB simple and leave C# to the real developers.

  8. abhinaba says:

    Some of the comments specially like the one from Gabe has made me think again whether I really like Lambda expressions in C# πŸ™‚

    One thing is sure lambda expressions is going to help erradicate carpal tunnel syndrome as coders will be required to type much-much less.

  9. James Arendt says:

    "C# has originally developed from C++ /Java and is (was :^) ) a strongly typed object-oriented language."

    I think you mean "statically typed". Languages like Ruby or Smalltalk are strongly typed, but not statically typed.

    Of course, this point is really not important since it has no bearing on whether or not closures and continuations are/should be included in the language.

    "Even though there are people go gaga about continuation and lexical closures these are fundamentally functional language features and should be left to that."

    No one considers Smalltalk a functional programming language. Yet, these features are fundamental to the language. They just call them by a different name – blocks.

    "Introduction of bits and pieces of functional language features are not going to add value to C# and at the same time the surface area of C# is growing beyond what most developer can grasp."

    I agree with you that the surface area of C# is rapidly growing and that’s going to make it more difficult for developers to grasp what’s going. But, I’m seeing it from a different angle. The fact that Anders and company did not add them to the language in version 1.0 has led to this rapid growth in the language syntax.

    Languages like Smalltalk, Ruby, Scheme, Python, and many others are very easy languages to pick up. They have very small surface areas. Yet they all have included these features from the beginning. This has allowed developers (including the morts) in those languages to expand or create APIs far richer and intuitive than what’s been found on the .NET/Java/C++ side.

    People are gagaing over the new relational capabilities of C# 3.0. Funny thing is that Smalltalk is capable of doing that without needing to add new language syntax thus not increasing the surface area of the language.

    "Functional programming is for the academia and not from the industry and should be left as such."

    As I’ve already stated, these features are not inherently functional. I also disagree that they serve no place in the industry. If anything, the industry’s software development efforts would be running smoother if they were included from the get-go. But, it’s taken pressure from popular growing languages like Python and Ruby to kick Microsoft into attempting to make C# a better language.

    It may be too late. The problem now, as we agree on, the surface area has grown too large. Developers may prefer to go the path of least resistance — languages that are simpler, but just as powerful.

    I’ll wrap up by saying that I do see myself using these features regularly. Whether it’s in C# or taking refuge in IronPython or Ruby.NET, I know I’ll be using them in some form.

    I would like to also state that morts will use them if the following takes place:

    * Learn the features from people other than the Don Box’s of the world. If someone could write a section on anonymous delegates/lamba expressions that follows closely to the sections on blocks in "Why’s (Poignant) Guide to Ruby" or Dave Thomas’s "Programming Ruby", I think morts will realize that these features are not only cool, but easy to use.

    * The APIs promote the usage of these features. It looks like this will be the case from what I’ve used thus far in C#/.NET 2.0. The new generic collection classes provide methods that take advantage of passing blocks thus aiding in showcasing the benefits. And more to the point, morts will have a good reason to use the features. It’s just a short step from there to using them more often.

  10. Thong Nguyen says:

    You know, I couldn’t disagree with you more.

    Continuations and closures have made my life so much easier now that they’ve been added to C#. I spent a couple of years tutoring functional and logical programming languages at university so I always try to design things in a more declarative rather than imperative way.

    I believe that people who think that continuations or closures or lambda expressions are useless and needless are really in the same boat as people who thought classes where pointless (we have structs and pointers!).

    Things "appear" to look more complicated only because you are not used to them but after time, things actually become a lot more clearer.

    Many people may never see a use for lambda expressions because they have never learnt to think to program in the more generic fashion that functional programming allows. Take for example the String.Trim method. Currently, it trims only spaces or characters you provide it. It is no where near as flexible as a high-order version of String.Trim whose prototype would look something like:

    String.Trim(Predicate<char> acceptChar);

    Now, a developer can simply do something like:

    "ABCDEF".Trim(x => x < ‘C’);

    To trim the characters less than ‘C’. The Trim method now has a lot more flexibility and the developer no longer needs to sit down and write their own special trim method.

    All these new C# features greatly increase code reuse which will reduce errors and make code so much easier to understand.

    Passing bits of code (functions) around rather than variables is a very powerful and relatively easy to learn concept. People just gotta give it a chance.

  11. Thong Nguyen says:

    I really disagree with people who say adding functional programming features to C# adds no value.

    The idea of delegates is a bastardisation of OOP and yet most people using C# love them. It’s only natural, if you have delegates, to add anonymous delegates and closures and from there, to lambda expressions :-).

    Continuations are one of those features which drastically reduce the amount of code you have to write and with good practise, will reduce the amount of temporary arrays that get created and returned (think about Directory.GetFiles() and how much nicer and faster it would be if it was rewritten using continuations).

    Ruby, Python etc prove that functional programming is not "just for academia".

    Anyway, I salute Microsoft’s new found commitment to functional programming. They’ve won me back from Java.

  12. Siddharth says:

    Lambda expressions, a pain?? are you kidding… its going to be a darling feature of C# 3.0. Imagin the pains of writing loops to do stuffs on collections…

    var a = AllNames.Select(x=>x.Age > 10)

    alone is worth its existance. πŸ™‚

    My opinion is, lambda expressions will come as a shock to the community, yes. but they’ll soon get over it and start to love it.

  13. Chuck says:

    "My opinion is, lambda expressions will come as a shock to the community, yes. but they’ll soon get over it and start to love it."

    I think you are overestimating 87.9% of .Net developers.  Don’t forget, many of these guys are the same ones that started out with VBScript+ASP only 5-6 years ago with no background in mathematics, computer science, or engineering and no desire to "learn" a programming language.  And now you are expecting them to learn about relatively high level and abstract (again, relative) language constructs??  

    Not going to happen.  As snazzy as the feature is, I think it’ll go unused by the majority of existing .Net developers.

  14. Subbu... says:

    Hey Chuck…

    I agree with what you have mentioned here ===> "Not going to happen.  As snazzy as the feature is, I think it’ll go unused by the majority of existing .Net developers."

    Your reasoning is logical and justified…It becomes pretty high level when u take into account the developer community who are actually doing the coding…

    All said and done, this is not going to everyone’s cuppa tea…

    Ciao,

    Subbu

  15. Wiebe says:

    Don’t agree. I don’t have a university degree but am fairly able to grasp what’s going on here πŸ™‚

    I don’t think the problem will be that developers are not going to use the new 3.0 features, because then it would just be like 2.0 code.

    There will be problems with developers trying to use the features that they don’t understand and produce a loads of DailyWTF-worthy italian pasta code.

  16. The posters above who argued that this is the reason for having both VB and C#.

    VB is a rapid prototyping language for people without a firm grasp of CS concepts. If complication == bad, use VB.

    C# is, first and foremost, a software engineering language for professional programmers. Personally, I would be pissed if I had to look at porting my huge codebase to F# because Microsoft decided C# coders were too stupid to learn new programming techniques.

    Back in 1.x, a lot of people wondered why they bothered having both languages — you could do all of the same things in both places. They’ve answered that question pretty convincingly starting with 2.0. Now, 3.0 is adding some slick new capabilities.

    There are a lot of Rails programmers who don’t understand the tiniest fraction of Ruby’s capabilities, and are just using the language as a way to crank out fast websites. Likewise, there are plenty of working programmers who speak pidgin C#, and don’t really understand the details of the language. But while those programmers are the target audience of VB, they are merely tolerated in C#. If you can’t understand the new language features, you probably just need to suck it up and learn the new details.

  17. stevenR2 says:

    This is an interesting post.

    I’ve been reading the spec, trying a few things out in LINQ and although Lamba expressions are tricky at first, i am finding their power to save me from writing reams of code and the associated management that comes with that.

    I agree with Siddharth. This alone will sell me the concept:

    var a = AllNames.Select(x=>x.Age > 10)

  18. In my last post&amp;nbsp;I had discussed about anonymous methods.

    I had used the following code snippet…

  19. Lee Jensen says:

    I don’t have a problem with anonymous functions (lambda has always be a poor name), it is the syntax that is being used to represent it. An equal followed by a greater then (=>) makes for really ugly code.

    I suppose smashing everything onto one line (ala (l(i s (p))) makes some people happy, but there are MANY studies out there showing that this produces buggy, unmaintainable code.

  20. Paul says:

    My view is that all c#3 features should have individual compiler flags to invalidate their use. These features are, in my oppinion, subversive to business interests and individual companies should have options to protect their software interests from this kind of code being introduced by contractors.  Bill Gates being a knight of Malta and Microsoft being a Vatican corporation, one has to wonder whether these aren’t subtle and deliberate efforts to subvert business. While the features are in some ways cool and fun they still add a level of obscurity and confusion that business needs to consider when deciding how their software is developed. Those who think these features are so cleaver appear to be the some types who loved to write spagetti code with the "goto" statement and thought themselves so cleaver and superior at the expense of the companies interests.

  21. Joe Chung says:

    I think it’s funny how all these C# programmers like to look down on VB.NET programmers because they’re Morts, but give them something that isn’t absolutely trivial to understand, then all of the sudden they’re becoming incredibly uncomfortable with the notion that they’re just Morts that like curly braces.

    Suck it up and learn how to use it.  It’s going to become part of C#.  Or admit that you’re just a Mort that likes curly braces.

  22. LP says:

    Smalltalk was one of the first mainstream OOP languages. It was imperative, but contained blocks, which were lambda expressions. They were a primary feature of the language with all loops as well as numerous other features implemented in terms of the blocks.

    I do not have a degree in CS so I learned many of the concepts at work. Sometime intellectual curiosity can go a long way. I am not a big fan of making languages "feature rich", but strongly typed languages can often be difficult to read, so any syntactic simplification is an improvement as it clarifies intent, which can often get syntactically obscured.

    Too often  while interviewing people I run into those that do not have a CS degree and lack any curiosity. These people do not understand collections, threading and other important aspects of programming, so I really do not think we should dumb down the technology to keep them employed.

  23. Gaëtan Voyer-Perrault says:

    OK, your basic conclusion is nicely summed up as:

    "Functional programming is for the academia and not from the industry and should be left as such."

    And your explanation is basically that you don’t trust developers to understand this stuff and you don’t like the use of functional programming concepts in a declarative language.

    Well, the second "reason" is basically an unsupported personal opinion with no historical backing or even argument. Fact is, functional programming does some things very well and other things poorly. FP handles loops very well (the J language can perform a matrix multiplication in like 5 characters), but doesn’t necessarily do UIs or Data Access very well.

    And now we’re basically adding functional concepts for our looping structures (which functional does well!) and using C# for everything else. Sounds like a pretty eloquent solution to me.

    Worrying thtat other programmers won’t understand code is pretty disrespectful of your fellow programmers. You don’t need a 4-year degree to understand and use functional programming concepts.

    Your post is just emitting negative energy and reeks of hubris (supported by multiple links to Wikipedia). If you know all of this stuff and you’re worried that others won’t, why not be positive and build something instead. You’re halfway there, you build this post that’s actually somewhat informational and then you slam the technology.

    Why not write a real "here’s what you need to know" post and then point your co-workers to it. Just go out and use the FP concepts and point your co-workers to your blog if they have questions. Sounds more productive to me.

  24. GF says:

    This seems like a natural progression of the language to me. I don’t have a computer science degree neither am I highly interested in mathematics.

    I do however earn a living by writing code. Now does this make me a professional programmer or not?

    In my opinion the nail was hit right on the head in an earlier comment by LP "Sometime intellectual curiosity can go a long way."

    I remember first looking at Visual InterDev a fair few years ago and any tutorials etc that I could get my hands on were all describing drag and drop controls, when .NET came about the basic tutorials were dragging a DataConnection, DataAdapter etc on to the pane at the bottom of the form. Curiosity made me not use these techniques – although I would have got paid exactly the same regardless of whether I did or not.

    Training in a lot of jobs is not always a high priority and I don’t think many companys would push the developer to incorporate Lambda expressions – (Maybe this is different in top end softward shops – I dont know) – it then falls down to the reason why most developers chose this career path – an interest in programming and a curiosity strong enough to do something about it.

    A programmer should take pride in their work, if they don’t understand a concept that they may benefit from then they should learn it and not prevent other developers in the same project from using it.

    This probably is the main reason for me reading this thread, a curiosity of LINQ brought me here – seeing where the C# language is heading.

  25. oldgeek says:

    First, thanks for an excellent discussion of lambda expressions.  For someone who chooses not to like them so much, you have certainly explained them in a most enjoyable and readable form.  I found this site while looking for information on linq -> lambda expessions.

    For my two cents, I will probably use lambda expressions a great deal.  I am looking forward to using linq in my website development.  I started programming in ones and zeros literally and have programmed in almost every reasonably mainstream language that has been developed (NOTE: someone always comes up with a new scripting language or special purpose language that I have never heard of, but that is the WAY).

    As a practical matter, my opinion is that whatever facilitates quick, accurate AND maintainable solutions will be rapidly adopted by the development community.  Happy customers are the goal (at least for me).  I have been exceedingly happy with the progress in programming languages and paradigms from a purely commercial point of view.  I can create solutions in an hour with C#, ASP.NET, etc that used to take days, if not weeks to do (and I ain’t no genius by a long shot).  I believe that C# 3.0 is a major step forward.  And once again, thanks for your great and thought provoking discussion.

    BobH

  26. billie says:

    In my experiences with c++ the more ways to do something the more complexity there is.  When you are working on a huge enterprise application spread across many different teams each team doing things slightly different . . . you end up with a codebase that is really hard to follow.  One of the things I liked so much about c# was that it helped limit the ways to get something coded, and this helped code bases a lot.  I fear c# may be going the way of c++ . . .  it will get harder to maintain.

  27. Pete says:

    The driver in this thread is not whether lambda/linq/lisp et al are ‘good’, but rather how they play with the consumers of the language. The mort/elvis divide is seen by business clients as computer nerd posturing that proves IT should just get out of their cubicles more. Pick your ditch and get on with it. ‘readable code’ equates to ‘cost effective maintainable code’. The driving logic has to be self-evident; it has to jump off the page. Anything else means some poor geek scratching his head in his cubicle, and that is just a way to burn money. So ‘less typing, more head scratching’ is not always as clever as it sounds. vb programmers, take your profession seriously. C# programmers, please, spare us all the ‘I am smarter than you’ stuff, because your solutions are still buggy, over budget and over schedule. To business ears, ‘if its hard to understand then it must be good’ means pointless extra cost through the life of their app. If c# is a tool for platform developers and vb is a tool for business applications, then decide which task you are performing and use the right tool. But if you are using c#3.0 to write code that will be maintained by non-academics because thats the business model – cheap support – then you aren’t really as smart as you seem to think, and thats the concern. Its a concern because we see it all the time, right? The ‘brilliant programmer’ who leaves a tangle of unsupportable stuff behind. This is not something to lay at the feet of lambda/linq/lisp – so the extensions in c# are just fine – rather the real problem is mort/elvis, or more correctly, elvis impersonators.  

  28. Interesting discussion happening here!

    As I read in one of the comments that any language feature could be abused, I couldn’t agree with it more. But given this fact, I personally think C# 3.0 features are really cool. I don’t see any harm in increasing the surface area of C# to keep pace with complicated business needs. But devs shouldn’t be using these features unless they really need it. And to know if they really need it, it’s very important for them to have a deep understanding on these features.

  29. Gaurav says:

    "C# is, first and foremost, a software engineering language for professional programmers" that was good πŸ™‚

    Two points which I gathered from this discussion –

    1. Increase in C# surface area – very true, the more it expands more it will be difficult to *manage*. Because people working for one project may be writing one statement in different ways so keep the code clean we have to force syntax ethics to them πŸ˜€

    2. Complexity of new features – that is not true. Because complexity of a syntax is inversely proportional to amount of its use.

    I have a weird idea I do not know how much it is going to help and what will be its impact but it will surely keep the C# surface area under control at least for new projects.

    Why don’t the copiler discards pervious features and use the new ones (at least which can be) or if not discard at least throws an Warning that this is an old way of programming.

    I am not talking of everything but in case of anonymous delegates this can be done and new lambda expressions can be forced.

    Just an Idea πŸ™‚

  30. I think that the => operator should be pronounced as "induces", as it does in fommal logics. An equal followed by a greater then (=>) makes for really ugly code

  31. Gordon Freeman says:

    I think a lambda is good for identifying the following:

    items[] help = new items[]{ammo,healthpack,allies};

    var PainReliever = help.Get(x => x != allies);

    foreach (var owie in PainReliever)

      {

        if (owie = healthpack)

          {

             Me.Nurse[owie];

          }

      }

    (I was first introduced to lambda’s in Half Life^2)

  32. Today I was spreading the goodness of Ruby and why I love it so much (and you can expect multiple posts

  33. In my last post I had discussed about anonymous methods. I had used the following code snippet to show

  34. Alexandre Grenier says:

    Wow, this post is so old, yet still going!

    My take is you can’t just take one of the C# (1.0, 2.0, 3.0, etc) language feature and dice them up like this.

    If you go beyond the vertical examination of the language as a computer scientist, and you apply those concepts horizontally as an architect or developer, you will see how the lattice is interwoven.

    Pete, please don’t give us the non academic and business semantics crap. Non academics are usually the ones writing the business efficient pragmatic code that makes it to production.

    As for wasting business dollars on IT, blame the business men hiring the cheapest IT staff, not staffing an architect, and pushing through without a plan. The choice of language is hardly ever the cause of software project failures.

    It’s usually the business nerds coming up with arbitrary Gantt charts that screw things up before the first line of code is ever written. If you have a time and cost schedule before you have a team and a platform, your project is failed already.

    Back to Lambda expression, they solve a very real need in both the business and development worlds, to express problems with the least possible syntactic pollution.

    If the developer can’t figure out the problem expressed in Lambda, then the only part they can figure out in an alternative syntax is that very syntax. The problem expressed will be obscured and even less understood by the developer. This goes back to the business nerds hiring idiots that code for cheaper.

  35. James says:

    I was intrigued by this post, the orrigional body was a well worded and understandable introduction to these topics, and a decent comparison between language syntax that we already use, and the "new" syntax.

    Disturbingly enough, I found the last bit of criticism very out of place in this article.

    I started learning to program about 6 years ago, with VB6.  I’m not a genious, but  progressed from VB to C++ then to C# 1.1 fairly quickly, and understand some of the, initial, limitations and benefits of all of them.  If there is one thing I’ve learned, though, it’s that you can do almost anything in almost any language if you delve deep enough into the pits of the syntax.  I’ve yet to see anything in VB that couldn’t be done in C++, or vice versa.

    C# is a language I always viewed as a combination of the ease of VB and the power of C++.  

    It seems that the argument that adding these features is "bad" is just a prejudgement of every developer that isn’t yourself.  If I don’t understand the concept, I don’t use it in production code.  I experiment, and try to gain understanding enough to simplify my program, but I think the idea that having these options could be bad for the language as a whole is just ludicrus.

    I think worrying about language features instead of worrying about the fact that people are taught these instead of programming concepts should be more the primary issue.  If one understands the basic concepts of programming, language becomes less and less a defining factor.  Learning C++ tought me that conceptually, VB and C++ were the same, though VB provides a more rapid dev cycle in most common situations.  taking that conceptual ideal to C# has allowed me to combine my VB and C++ into one, while utilizing new C# objects, syntax, and functionalities.

    I don’t know if I’m alone in how I feel about it, but it would appear from some of these responses that many people have chosen to use alternative languages, like Python (which I’ve also done some studying and playing with) specifically in order to explore some of these "functional" features that until now C# has been unable to provide comparable alternatives to.  I would think that this will enrich the C# language by bringing some of the developers in these other languages into the playing field, so to speak.  Thereby bringing a more comprehensive understanding of the concepts behind these new functionalities and syntax, and who is ever going to say that a better understanding is bad?

    Just my $.02 on the subject…

    I don’t claim any advanced knowledge, I don’t even really use all of the features of C# 2.0, so I think it will be awhile before I make the jump to 3.0, but I just feel that the whole good/bad discussion is frivolous.  If you don’t want to use these features, don’t.  When you run into code that uses them, learn them so you can maintain it.  that’s what how I feel, and how I’ve made my living as a software developer.  

    "It’s not what you know, it’s what you know how to find;  Nobody knows it all." -Josh Bee, my C# instructor, while speaking about what coding really is about.

  36. IMO you stressed my point. Try asking Ford to build a car that kinda SUV but has space at the back like a truck and can win a F1 πŸ™‚

    Would you try to add C# type safety to Python? Just as you won’t use Python for device drivers hopefully you won’t use C for a large website. Every language has a style and a philosophy and its about sticking to it.

    "see anything in VB that couldn’t be done in C++, or vice versa"

    Have you tried a device driver in VB or to script in C++?

    "If I don’t understand the concept, I don’t use it in production code"

    But most folks do not write fresh code, they maintain code written by others and add to it. For them there’s no choice. The whole philosophy of C# has been to let writing of bad code harder. Exactly for this we don’t see macros and typedef in C# which is pretty easy to add….

  37. lubos says:

    Lambda expressions are extremely useful and I’m so glad that C# supports them. But I understand what you mean. 97% of .NET programmers don’t work in a domain which could utilize these new features to full extend and if there’s one-time opportunity to use them somewhere in the code, it’s just better to stick to "simple" language constructs and tolerate a few extra lines of code for the sake of consistency.

  38. mc says:

    corrupting the language for such a small gimmick doesn’t make sense, "experts" using lambdas for complex operations will become big problem in maintaining and understanding code!

  39. GeriatricSod says:

    So just to throw a little fuel on the fire…

    Commenting on "If there is one thing I’ve learned, though, it’s that you can do almost anything in almost any language if you delve deep enough into the pits of the syntax.  I’ve yet to see anything in VB that couldn’t be done in C++, or vice versa"

    The reality of it is that this is completely untrue. There is definitely a spectrum of language complexity, and all of us developers pretty much use the language we are most comfortable with – something that is adequate for the job…

    However, when you look "down" the spectrum of complexity, you wonder how the poor saps down there can manage without (some language feature of your choice). For example, I certainly had a hard time without the ability to do true polymorphism in VB6 (remember creating an interface, "implement"ing it, and delegating method calls to achieve some semblance of polymorphism?).

    The curious thing about looking "up" the spectrum is that one wonders WHY you would EVER need (some esoteric language feature that has someone else all excited). The reality is that they are looking down at you wondering how you can manage πŸ™‚

    Heck – now that I do a lot of programming in Javascript, it seems bizarre that you shouldn’t be able to extend a class at runtime with your own classes – how else do you properly extend an object you’ve just met. If you think this need is esoteric, move up here – we need it ALL the time πŸ™‚

    I think pure functional languages are at the very top of the chain – primarily because they can consume code that they generate on the fly without sacrificing cleanliness. On the other hand, there is validity to the view that with much power comes sluggishness πŸ™‚

    The debate above is typical – it takes place every time someone tries to bridge the gap between two points on the spectrum. (As someone pointed out, it happened when we gave the compiler the ability to create a vtable for us instead of storing function pointers), and it’ll happen again…

    The only pungent observation I’ll make (which should, with any luck, ruffle a few feathers πŸ™‚ ), is that anything these guys dream up will have been in Lisp since its inception in the 1960’s πŸ™‚ Which simply goes to show that we should all learn lisp and balance parentheses…

    By the way, for those who need me to be explicit, please read this message keeping a somewhat lighthearted view on life πŸ™‚ I intend to provoke thought and discussion, and certainly am not trolling aimlessly. I do actually believe what I just said, and quite repeatedly put my money where my mouth is!

    Gracias!

  40. GeriatricSod says:

    Heck – now that I do a lot of programming in Javascript, it seems bizarre that you shouldn’t be able to extend a class at runtime with your own classes – how else do you properly extend an object you’ve just met. If you think this need is esoteric, move up here – we need it ALL the time πŸ™‚

    should read

    Heck – now that I do a lot of programming in Javascript, it seems bizarre that you shouldn’t be able to extend a class at runtime with your own METHODS – how else do you properly extend an object you’ve just met. If you think this need is esoteric, move up here – we need it ALL the time πŸ™‚

    sorry πŸ™‚

  41. Scoper says:

    I am a professional software developer and have been developing applications in C# for about 8 years now and so have seen the evolution of the language in great detail. In my opinion (and thats all it is!), the additions brought to the language in version 2 *did* seem to enhance it. Features such as generics and iterators allowed developers to write much more flexible code but was still very maintainable.

    It seems to me that most of the new features in C# 3.0 are simply there to make the language simpler to use (By which i mean lambda expressions, anonymous types, variant data type, and extension methods). I don’t feel that they have added anything to the language other than to incite bad programming practices and unmaintainable code.

    I agree that there are times when features such as inference are appropriate and can make life a little simpler, however my fear is that it promotes lazy programming practices and in turn buggy code.

    But like i said, thats just my opinion :o)

  42. Paul says:

    Without question, lambda expressions and anonymous methods end up cleaning up my code and make them much easier to maintain and understand. It cuts way down on how much code I have to write, no need for all sorts of different helper functions or gigantic ultra-specific (non-reusable) functions… so I have fewer places bugs could be hiding and fewer unit tests that need to be coded.

    Consider the following:

    (hopefully this will format ok)

    var procs = ( from proc in Process.GetProcesses()

       where proc.PriorityClass == ProcessPriorityClass.Normal &&

       proc.StartTime < DateTime.Now.AddHours( -6 ) &&

       proc.TotalProcessorTime.TotalMinutes > 30 &&

       proc.Responding &&

       proc.MainModule.FileVersionInfo.IsDebug

       select proc ).ToList();

    ==

    The looping itself goes away and you’re left with a succinct way to describe what the point of all those foreach’s were trying to get at. If you can’t read the above code and figure out what will be left in your list, then I have no hope for you.

    For a different issue, I had 4 pages of imperative code, that had to be heavily commented to understand what it was doing… it was reduced to **1 statement** of highly-readable LINQ code that I showed to people WHO DON’T WRITE CODE AT ALL and they could tell me what it was doing, but looking at the 4 pages of imperative code, they gave up or were way off.

    Then, take into consideration the direction computing is going. We’re going to many-core processors. PLINQ will be able to parallelize for you and offload the burdens of that to the framework, thus making your code significantly faster especially once we start seeing 32, 64, 128 cores. You have a highly readable lambda expression with "AsParallel" tacked onto it, and kazam! Your code now obliterates the competition with speed.

    I use LINQ as a litmus test for my future employers, if they aren’t into it, then I know they don’t understand the power, simplicity and elegance it brings to applications… A unified query language that works on EVERYTHING: databases, generic lists, arrays, xml and you can do joins across those seemlessly.

    It enables shorter dev cycles & easier maintenance… IMO, companie unwilling to adapt aren’t worth working for and employees who don’t get it aren’t worth hiring. At least if you want the top-paying jobs with the best dev managers.

  43. Jack ( Denmark ) says:

    I’ve never used to do any functional programming before

    – and as such didn’t know anything about the constructs of functional programming…

    My educational level is far away from the University – but learn this stuff myself and various sources like the internet…

    I find Lambda expressions to be extremely powerful – and i love using them in different areas.

    They’ve presented me to some ideas of use -and certainly i would say that anyone that learns to use them has a powerful tool.

    I’m not the academic – but i know a bad programming language when i see one…

    VB anyone ?

    My days of development started with and old Turbo C++ compiler and moved on to C++ — GOOD times

    Also C / C++ learns you some fundamental basics to pointers and memory – i can’t see how anyone can compare C++ to VB

    I choose a language based on the solution required.. C# is not for everything

    blrb

  44. RealWorldExamples says:

    Thats a lot of code to accomplish what could simply be done in 1.0 in onoe line by:

    long size = new FileInfo(@"c:vcvars32.bat").Length;

  45. nirdesh says:

    I just happened to use lambda expressions in some of my code to make my code cleaner and easier to read.

    Well I thought to read more on it and it seems I came on it too late.

    I am surprised to see the orgin of this thread dates back to 2006.

    Anyways thanks to all for the good discussion

  46. yelinna says:

    I love C# new features and the fact that I can learn functional programming with a language I already know. I didn’t study CS but now I can act if I did it πŸ˜€

  47. Tom says:

    Good discussion. My complements go out to abhinaba, the author, for his willingness to criticize a major language feature and spark such an interesting interchange.

    My gut reaction is to side with him. Like many other folks have said, different languages have different ‘essences.’ The essence of C# I think was to make the Microsoft version of Java (which was stealing so many developers) and throw in some C++ syntax to make that crowd happy. If that is true, then I would argue that abhinaba is correct, as the driving purpose of Java was to create a language which was an elegant interpretation of OO that fit business needs. The addition of features that allow C# to be a one size fits all language detracts from this paradigm.

    In the words of the President of the Federation of planets circa Star Trek VI, (approximately) "let us redefine progress such that just because we can do such a thing does not mean that we must do such a thing."

  48. James says:

    Now here we are in 2010.  I transferred from a Java project to a .NET project last year, and I have to admit that lambda expressions have been one of the best things for us.  It’s true that the people where I work are all smart folks, so I guess maybe lesser engineers might get confused, but I really don’t think it’s that confusing.  It took me all of maybe several seconds the first time I saw lambda notation to figure out what ".ToDictionary(x => x.Key)" does, and it only took a few seconds more to realize that it saves me about four lines of repetitive code to maintain.

    Of course nowadays it’s clear that lambda expressions, besides being a good idea in and of themselves, were also a necessary building block in order to introduce LINQ.  In the months since our .NET project began, we have been able to leverage lambda expressions, LINQ, and expression trees generally to create an architecture that is far more flexible and easier to maintain than it would have otherwise had to be.

    Performance-wise, any hit we take due to the necessity of building expression trees and such is more than compensated for by our ability, using LINQ to Entities, to dynamically generate queries that produce all the data (and only the data) we want, in a single database round trip.

    Could the same functionality have been implemented in Java?  Yes, technically, but not practically.  Because we live in a practical world, time saved on writing and maintaining code takes something that was always "technically" possible and actually makes it available to you in real life.

    Maybe I just have the advantage of retrospection. I don’t know what I would have felt if I’d been programming in C# for years and lambda functions were just getting introduced.  But looking back, I’m sure glad they were!

    And, by the way, I would argue that C# is still STRONGLY typed: It just doesn’t always have to be EXPLICITLY typed.  The var keyword gives us the advantage of compile-time sanity checks without requiring us to be overly repetitive ("Dog dog = new Dog()") or unnecessarily verbose ("Expression<Func<Dog, bool>> dogCriterion = …").

  49. Valko says:

    Now we are in 2010. I have 20 years programming experience and I do use lamda expression but in 90% of the cases those projects are nightmare to support. The problem is you simply cannot find qualified programmers that do understand code complexity. Anybody can develop complex code. The problem is when you need to maintain that code later. So from business point of view all this "improvements" are pointless. The fact we have this long thread is the proof. Making something anonymous and closure automated is not help at ALL from maintainability point of view. And from business point of view I’ve seen this types of programming:

    1. Simple code complexity with many lines of code – that is the most usual case, you still can maintain it.

    2. Complex code meaning (like lamda, can be understand by 10% of the folks on the field) with less lines of code – that is the worst case.

    3. Simple code meaning (can be undertsand by ANYBODY) with less lines of code – that is the best case scenario, I can write this one πŸ˜‰

    Good software programming is reducing the complexity on ALL levels. Introducing language features that increase complexity (language surface) is a pure nonsense and the sooner Microsoft realize it the better. The whole idea of having .NET framework is about making the basis of the future programming more simple by shielding the language from the implementation, which contradicts this idea with making the language overly complex.

    That is my 2 pence form the real life projects.

    cheers

    Valko

  50. Wolfie665 says:

    Now we are 2020. After 30 years of programming (wolfie665 => Valko){My previous post}, I am retired lying on the beach, Microsft has introduced Alpha-conversion in C# 6.66 – poor folks that should maintain my code and re-write the new release…vaiables names are not what they have been on old days when X was always X.

    Analyze this…and let me know how exited you are about the new features.

  51. John says:

    I 100% agree with everything you wrote in this blog entry.

  52. Norman says:

    Its nice to have shorter (and in my view more readable) syntax for Delegates.

    However, there were already several ways to do this in C#.

    It would be better if Microsoft added more features to the language, rather than just adding more syntax options.