6 ms·
Learning Haskell/Python makes you a worse C# programmer
- stcredzero 14y ago> The fact is that functional idioms work badly in languages that don't have syntactic support for them. You can even remove functional from the sentence. Powerful features of languages like Python and Lisp don't get you more power than languages like Java. They give you more power per unit of effort.
- wging 14y agoThe definition of power is energy per unit of time. Similarly, the common usage of the word power as applied to programming languages means pretty much that: you get more out of your work. In this analogy energy would correspond roughly to computability, which is not quite so useful a concept to measure. (Of course the analogy breaks down--energy can be indirectly measured, but computability is a yes-or-no question.) http://www.paulgraham.com/power.html http://www.paulgraham.com/power.html
- hippich 14y agoOr in perl: join "\n", map { $_->{description} } grep { $_->{description} ne "" } @mylist; sorry, every time i see something like this, i just can't resist to post code in Perl. =)
- deleted 14y ago[deleted]
- cygx 14y agoI'll see your Perl5 and raise you some Perl6: @list.map(*.description).grep(?*).join("\n")
- gecko 14y agoThat is starting to look more like J or K than Perl. Is the Perl 6 team still considering syntax changes? If so, any thought on making map/grep/join operators?
- cygx 14y agomap, grep and join are subs as well as methods. Perl6 is a multi-paradigm language and of course there's more than one way to do it - even when using the same operations. Instead of chaining methods, one could also use # p5 style join "\n", grep ?*, map *.description, @list; # dataflow style @list ==> map *.description ==> grep ?* ==> join "\n"; join "\n" <== grep ?* <== map *.description <== @list;
- draegtun 14y agoPerl6 allows you to define your own operators: $ perl6 > sub infix:<J> ($sep, @list) { @list.join($sep) } > sub prefix:<J,> (@list) { @list.join(',') } > ':' J <one two three four>; one:two:three:four > J,<five six seven eight>; five,six,seven,eight
- yen223 14y agoThat can't be Perl, I actually understood it.
- omgtehlion 14y agoTLDR: C# 2.0 had ugly syntax. article from 2006 in c#3.0 we write string.Join("\n", mylist.Select(x=>x.Description()).Where(x=>x != "").ToArray()); and now string.Join("\n", mylist.Select(x=>x.Description()).Where(x=>x != ""));
- njbooher 14y agoA method named 'where' seems really odd.
- mwg66 14y agoWhy? It's a fluent interface.
- njbooher 14y agoIt's not a verb.
- kooshball 14y agoUsing Select and Where makes perfect sense.
- njbooher 14y agoHere it's a misuse of notation.
- markokocic 14y agoIn SQL it does.
- kooshball 14y agoThe whole point of LINQ is to add query-like functionalities to C#. LINQ stands for "Language-Integrated Query" from http://msdn.microsoft.com/en-us/library/bb397926.aspx http://msdn.microsoft.com/en-us/library/bb397926.aspx "Language-Integrated Query (LINQ) is a set of features introduced in Visual Studio 2008 that extends powerful query capabilities to the language syntax of C# and Visual Basic. LINQ introduces standard, easily-learned patterns for querying and updating data, and the technology can be extended to support potentially any kind of data store. Visual Studio includes LINQ provider assemblies that enable the use of LINQ with .NET Framework collections, SQL Server databases, ADO.NET Datasets, and XML documents."
- binarymax 14y agoIt is unfortunate, that the type of positions that employ .NET developers, enforce C# (or sometimes VB.NET) as their language that targets the CLI. While I understand the need for consistency, it would be nice if IronPython or F# were accepted. But dont just feel defeated, make a case to your architect or manager, they might be open to it. However its worth noting that in my experience, C# is a fine language - especially if you can move past .NET 2.0 and use lambdas and LINQ.
- gecko 14y agoI think part of the problem is that, while the CLR is vastly better than the JVM at supporting languages other than its flagship, I also think that the cost of using languages other than C# or VB.NET is higher than a lot of developers are willing to admit. We just allowed some F# code into Kiln. On the one hand, it was vastly simpler than the C# code it replaced. On the other hand, we had to rearchitect our solution layout to handle changing the build order, which we in turn had to do so that the F# code could be sanely usable from the C# code and vice-versa, which in turn required writing a lot of call-site boilerplate and type converters (from C# to F# types). Add in that the CLR is simply not as optimized for F# as for C# (or vice-versa, depending on how you want to view things), and it's not exactly a situation where you can simply say, "Well, F# is better than C# at expressing this problem, so let's use it here." I want to be really clear on this: I don't think these problems are any worse on the CLR than they'd be on the JVM or with native tools (e.g., OCaml calling C or vice-versa). In fact, they're better in many ways: you have the BCL for your primitives, rather than the native C ABI (for native), and you have a VM that is legitimately much less tied to an individual language than the JVM, which makes things like tail-recursive languages a lot simpler. But I think the right way to regard Foo# languages is more-or-less the same as any other language: unless you can write the entire project in Foo#, think hard about whether the cost of interfacing between Foo# and C# is worth it to your project. Most of the time, it isn't.
- danek 14y agoAlso consider that it is hard to hire people to work on your project if you use F#, whereas c# has enough similarities to other languages that it is easy for people to get up to speed. It's too bad, F# is a really great language.
- gecko 14y agoI think the author is simply inexperienced in C#. Here's the right way to express his code: string.Join("\n", from elem in myList where elem.Description != "" select elem.Description); Note how mind-numbingly close this is to the Python: "\n".join(foo.description() for foo in mylist if foo.description() != "") I also think it's considerably easier to read than the foreach loop.
- deleted 14y ago[deleted]
- resurge 14y agoNote that this article is from 2006. Hence his using of C# 2.0 instead of a later version which includes Linq.
- kenko 14y agoLinq, which was inspired by ... Haskell! Would it be irresponsible to speculate that this article is directly responsible for the inclusion of Linq in C#? It would be irresponsible not to speculate!
- pjmlp 14y agoLINQ was introduced by Erik Meijer, an Haskell researcher working on .NET team. http://research.microsoft.com/en-us/um/people/emeijer/papers/es012-meijer.pdf http://research.microsoft.com/en-us/um/people/emeijer/papers...
- rjzzleep 14y agowell i completely disagree. he's got a point in his first paragraph, maybe a little different though. If all you saw is C# code from C# people you won't care one bit about the disgusting mess they create. But if you've learned a whole range of languages you'll try to come up with more elegant solution. He tried that, but as gecko pointed out the errors were not in trying, but rather in his results. I work in a C# dev house now, and boy what is considered a good solution there (and in their contractors works) is so sad I don't even know what to call it. But then, you look at the latest c# version and it has quite a few interesting features, people just don't use it. My guess is that they've just been doing it since c# 2.0. And the fact that c# is not really made for web development, which is what it seems to be most taught doesn't really help either.
- pcote 14y agoI'm a Python guy with a Java day job so I'm guessing my situation isn't that different from what he dealt with in 2006. Heck, most of us Java guys are dealing with it in 2012! Python didn't drag my day job down. Instead, it gives me the understanding of what Java's shortcomings are and why IDEs and frameworks exist to cope with them. It also changed the way I looked at design patterns. Before I knew Python, they were pretty intimidating. Now, I look at a strategy pattern implementation and find it more a cute attempt to compensate for something than anything else.
- tinco 14y agoPeople should not be so eager to jump to the new functional constructs in C# to proof it can be cool too. There is no shame in imperative programming, it has its own advantages and can be pretty too. In this case, just using C# a bit more idiomatically can go a long way: var descriptions = new ArrayList(mylist.Length); foreach (var foo in myList) { if (foo.Description == "") { continue; } descriptions.Add(foo.Description); } return String.Join("\n", descriptions); The names the author gives to his variables are the first indicator that he just isn't really in a C# mindset.
- noblethrasher 14y agoThe spirit of your code is correct but I think you'll get a runtime error since the inferred type of your iteration variable, foo, will be System.Object. Here's a slightly more idiomatic C# 2.0 (i.e. sans var goodness) ArrayList descriptions = new ArrayList(mylist.Length); foreach (Foo foo in myList) if (foo.Description != "") descriptions.Add(foo.Description); return String.Join("\n", descriptions);
- tinco 14y agoHey, you're right, it would be a compile time error but indeed. I'd rather supply a generic constraint <Foo> to ArrayList than have it be cast to Foo that way (does it even do that automatically?). Also, do you think leaving out the braces is idiomatic? I think it looks really pretty but I don't like it at all, it is too brittle.
- noblethrasher 14y agoEliding the braces does make it a bit less idiomatic I suppose; but in ten years of programming I don't think I've ever been bitten by a bug caused by that style... not even in JavaScript. On the other hand, I think the risk of making the code slightly more brittle is worth it if it makes it much more pleasant to read. Whenever I see a for/foreach followed by a single statement then I know that the code is doing a simple projection (i.e. Select in Linq or SQL parlance). If it’s a for/foreach followed by an if statement followed by some other statement (as in the above code) then I know it’s a simple filter and projection (i.e. Where and Select). But I wanted to illustrate your larger point, which is that C# programmers shouldn’t be so quick to use functional idioms since imperative code can not only look just a pretty, but it’s almost always slightly more performant since it doesn’t imply as many allocations and indirections.
- PaulHoule 14y agoC# has gotten much better since that article was written, but I've still got a 'bag of tricks' that I feel guilty about such as properties that return delegates and such. I like using functional methods in Java to implement DSLs but the guava docs are right when they say you shouldn't be ashamed to use a for loop from time to time in Java.
- klibertp 14y agoAnybody knows if the author moved to programming in Python or Haskell since then? He should...
- tkellogg 14y agoWow, this is the worst article I've seen on hacker news front page in a very long time. C# has a tremendous potential for functional programming. There's some features that make a pure functional style easier and prettier in haskell, but C# has plenty of potential. The title is total link bait. I clicked because I know there are things to write about - like pervasive nulls and mutable-by-default variables to begin with. There really are things to complain about! But the actual contents of the article are infuriatingly obtuse. The fact that 39 people found this interesting in 2012 just demonstrates how ineffective the entire hacker news concept really is.
- olmobrutall 14y agoI totally agree with you. Sometimes the anti-MS feeling here is absourd. C# is an amazingly designed multiparadigm language with excellent tooling that works in plenty of OS and devices. If it will come by google the open source world will be wet already. Having an ideology is ok but shouldnt be confused with technical merits. Some examples: IQueryabe<T> and expression tress let you write expressive queries that run on the database but have compile-type checking. Amazing for mantaining big datacentric apps. Async/await let you write complex asynchronous code as if it where usual imperative one. With for, try catch, etc... The compiler changes it for you. And all this on a real language that runs fast and you can use in your work to build phone apps, web apps, win apps and also, but not just, compilers and authomatic theorem proving applications.
- mhaymo 14y agoC# has improved greatly since this article was written, but replace it with Java and this piece is still sadly relevant today. The point is not that C# is bad, it's that using outdated tools can make it impossible or impractical to apply the kind of knowledge that many programmers today consider nigh-essential.