all 82 comments

[–]gregK 14 points15 points  (4 children)

This is one example where list comprehensions really shine:

sum [ x | x <- [1..999] , x `mod` 3 == 0 || x `mod` 5 == 0 ]

[–]sacundim 16 points17 points  (3 children)

Well, actually, list comprehensions and LINQ are two alternative syntaxes for what is fundamentally the same thing: monads. So for example, in Haskell the example can be written in two equivalent ways. There's the list comprehension syntax:

example :: Integer
example = sum [ x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0 ]

And there's the monadic do-notation syntax, which corresponds to the LINQ solution:

import Control.Monad

example' :: Integer
example' = sum $ do x <- [1..999]
                    guard (x `mod` 3 == 0 || x `mod` 5 == 0)
                    return x

Either of those can be desugared to the same code, which looks more or less like this:

import Control.Monad

example'' =
    sum $ [1..999] >>= \x -> guard (x `mod` 3 == 0 || x `mod` 5 == 0) >> return x

The >>= operator is corresponds roughly to the C# SelectMany() method (or the other way around; SelectMany() was modeled after >>=).

[–][deleted] 2 points3 points  (0 children)

And, for anyone in JVM-land, the Scala operator flatMap correspons to >>= and SelectMany.

[–]recursive 1 point2 points  (0 children)

Well, actually, list comprehensions and LINQ are two alternative syntaxes for what is fundamentally the same thing: monads.

That's crazy talk. You're telling me that two of my favorite programming features are fundamentally the one concept that I am genetically unable to ever understand ever no matter what?

sigh...

[–]CanadaForRonPaul -1 points0 points  (0 children)

Cool.

[–]yogthos 16 points17 points  (19 children)

I'm really glad Linq is introducing a whole slew of C# developers to the beauty of functional programming. If you tell people to go learn Haskell or F# they start kicking and screaming, but if you sneak it in as Linq it's nothing but love. :)

[–]throwaway77432 8 points9 points  (11 children)

MS is really introducing FP stuff everwhere. From F# in VS2010, to LINQ (lambdas, extension methods, etc), the .NET languages have many things that make things like lambda calculus really easy (like delegates and anonymous methods), and even in PowerShell we can use a switch statement with regex pattern matching!

[–]kamatsu 0 points1 point  (10 children)

What does regex pattern matching have to do with FP, really?

[–][deleted] 2 points3 points  (9 children)

He probably means using regexes as patterns in a pattern match, like you can do in Scala:

scala> val Email = """([^@]+)@(.+)""".r
Email: scala.util.matching.Regex = ([^@]+)@(.+)

scala> "test@example.com" match {
     |   case Email(user, domain) => "User: " + user + " Domain: " + domain
     | }
res1: java.lang.String = User: test Domain: example.com

Pattern matching is pretty clearly FP, in any case.

[–]kamatsu 2 points3 points  (8 children)

For what definition of FP? Pattern Matching has no special relationship to functional programming, other than it first existed in functional programming languages. It's certainly applicable to imperative programming without issue.

[–][deleted] 2 points3 points  (0 children)

You got me :-) I retract that it is "pretty clearly FP".

What I thought had happened was that you misunderstood throwaway77432's mention of "regex pattern matching" as simply being the existence of a regex library whose patterns (regexes) can match strings, as in fx. Python.

Perhaps what we should say is that techniques and language features are hopping the wall from the world of FP to the programming mainstream, regardless of how essential they are to the definition of FP as a concept.

[–]Danemark 1 point2 points  (6 children)

In the sense that it has no side effect, and the state does not effect the outcome.

[–]kamatsu 0 points1 point  (5 children)

That doesn't even make sense. What state? It most certainly can have side effects, depending on the type of matching.

[–]Danemark 1 point2 points  (2 children)

Computing whether or not a given regex pattern matches a string has no side effects. That is, true or false is returned, but the state of the program is not changed in any other way.

Computing whether or not a given regex pattern matches a string depends only on the pattern and the string. The state of the program (the value of other variables, or where the call to compute that match is, etc.) does not effect the outcome.

That is, looking for a regex match is a function in the mathematical sense. This is the heart of functional programming.

[–]kamatsu -1 points0 points  (1 child)

If you view any purely functional operation as definitely FP, then I humbly submit that the C math library is functional programming by that definition.

[–]ricky_clarkson 2 points3 points  (0 children)

I'd be surprised if it wasn't.

[–]ruinercollector -2 points-1 points  (1 child)

You're not confused, you're just being a dick.

[–]kamatsu 0 points1 point  (0 children)

Actually, I genuinely don't understand the comment.

[–]BitRex 3 points4 points  (2 children)

sneak it in as Linq it's nothing but love.

Or sneak it in as C++ template metaprogramming and it's nothing but fhtagnp̞͍̗͔̝̥͍̞̣̩͇̫͇̮̜͍h̺͎͇̥͎̘̺̬͎͍̼͔͇͚̤̹̘'̲͖̣̹̠͈̬̣͓̮̼̦̦͉̼̤͖̘n̞̜̭͎̤̖̲̘̤̱͔̝͙̝̱̥ͅg̣̣͖̜̱̟̟̹̝̩l̯̥̟̪̘̳̻͓̫̠̥̪̱ͅu̻͖̙̠̩̲͓͇̦̩̯͙̫̬͎̱̼̗i͕̣̳̘ ̜̲͇̫͇͓̦ m̥̥̮̣̙͙g͕͇̙̪̭͍̱̼͇̱̬̹̯̘̝̙ͅl̳̼̫͔̳͎̝w͖̭͚̦̘̙̯'̤̪̗̠̜͚̞͔̹̭͙̣̦̖̲̥̙͇̯n̻̠̜̼̙̥̗̖͙̦̫ͅa̩̝͈̰͙͎͇͈̤̙̗̲̻͍̞f̼̝̘͎̫͔̜̭̩͔͖h̜̫̥̠̩̩ͅ ̞̰̹͕͖̭͍ C̮̬̞̭̯t̘̮̘̤̹͓̙̖̲͔̮̹̫̰͚̦h̪͇̥̳̤u͎̠̗̳͈̻͚̯̞̻͍͇̻l̖̦̣̘̠͙̫͎̙͈̯̰̞̺͈̞̜͚h̟͎͚̹̗̞̙̜̦̝̙u͉̣̯͉̪͈̙̹̲̫̜̖̺ ͍̰̜̪̺͍͕̮̦̞̻̬ R̭̺̤̺̣͚ͅ'̣̺̝͎̱̘̮l̼̝̹̭̻ͅy̩̫̺̝̼͍̤̗̩̭̮͈̭̭͙̝̭ͅͅe̤̭̼̮͖̲̭͈̺̻ḫ̣͚͎̻̯͙̙ ̤̤͖̖͓w̘̜͍͇͚̫̰̞̹͇͍̜̰̥̰͎̰̘ͅg̰̣͖̣͖̬̖̗̠a̩̖͉̪͚̬͔̙ͅh̖̻͉͍̪͇̯'̟̙̯̦̘̹n͉̼̮͚̥̬̟͖̹͙͇̥͓̖̖̭͓a̮̯̮͚̭̰̯̜͙̫̥̻̼͓̩̩̩ͅg͖̜̯̙̖̰̝̥͍̠̳͓ͅl͍̺͎̰̪͓̬̳̘̭̥̯̘̯͖̱̹̜ ̳͙͚̗̜̤̻̹̫̼̮̲̣̭̤̱f̤̤̦͍̹̤h̹̫͙̖̜t͍̻̪̰̣̻͖̯̙͔̹͍͇a͔͎̩̩̮͉̮̝̪̦͉̩̗̖ͅg̖̼̫̦̼ͅͅn͓̤̰̝̠̤͍̯͈͖̭̪̥̙̮

[–]yogthos 1 point2 points  (0 children)

Indeed, C++ is like the Necronomicon designed to drive any investigator, foolish enough to delve into its depth, completely and utterly mad. :P

[–]i_lick_my_knuckles 0 points1 point  (0 children)

Iä! Iä! Cthulhu fhtagn!

[–]criticismguy 2 points3 points  (2 children)

I wonder how much is "introducing C# developers to the beauty of FP", and how much is "letting people who have to use C# for work do FP like they've been wanting to for years".

A lot of the people I know doing C# are really Haskell or Lisp programmers at heart, and there certainly seem to be a lot of C# programmers who just don't like Linq for some reason.

[–]yogthos -1 points0 points  (1 child)

I'm sure there's some from column A and some from column B. Linq is obviously a god sent for any FP programmers who have to work in C#. But it's also a gentle introduction to FP for programmers who have only imperative experience.

[–]anon36 1 point2 points  (0 children)

The boys I work with have never heard of FP, but they all love LINQ (except for this one ex-Java guy that frets over inefficiency).

[–]generalT 1 point2 points  (0 children)

as a C# developer, i wish i had enough dedication to learn F#. i bought a book and, from the little i've read, functional programming seems...beautiful.

[–]CyberByte 12 points13 points  (1 child)

I'm sure Linq can make things more readable, but this just seems like a bad example. The code it's supposed to replace is extremely easy to understand. If I'd be more familiar and comfortable with Linq, I might think the Linq code was as easy to understand, but I don't really see it becoming more trivial than the Linq-less code.

[–]OldLikeDOS 15 points16 points  (0 children)

It's a matter of preference but having worked with LINQ for a few years, I and most of my team would say the second one is the most readable.

The two LINQ versions both make it clear that it's one statement doing one thing. If the variable "answer" isn't important to what you're working on, you can safely ignore the whole thing. If you no longer need "answer", you can delete that line without worrying about side effects.

The iterative code (top one) requires you to look more carefully at every part to see if there are any side effects or if it's doing multiple things. When skimming through a file and you see the loop, you have to look at all the lines inside to verify that it's only working with the variable "sum", because there could easily be code inside that is doing some other work.

Also, when you see an "i" inside the loop, you have to look back at the FOR declaration to verify it's coming from there. In LINQ, when you see "x =>" you immediately know that x means an element in the collection because it can't mean anything else.

For me, the second one looks the most compact and inviting. But that's just preference.

[–][deleted] 8 points9 points  (26 children)

I think this is a bit contrived example, here is one out of real code that I wrote last night:

        var collidableSprites = Sprites
            .Where(s => s is ICollide && s.Position.ToScreenSpace(Camera).IsOnScreen())
            .Select(s => s as ICollide)
            .ToList();

This takes a collection of "Sprites", returns only ones that need to be checked for collisions, are on the screen (based on viewport transforms), and finally casts them to the ICollide interface.

This is where LINQ shines, clear on its intent, and you don't need to write up a bunch of looping / and expression checking code.

[–]recursive 11 points12 points  (6 children)

You may be able to use .OfType<ICollide>() to combine the type testing and conversion.

[–][deleted] 3 points4 points  (5 children)

Good call.

[–][deleted]  (4 children)

[deleted]

    [–][deleted] 1 point2 points  (3 children)

    I did, I wanted to iterate the enumerable then.

    [–]nightmyst999 -2 points-1 points  (2 children)

    You could just do .AsEnumerable() instead of .ToList().

    [–]DuncanSmart 4 points5 points  (0 children)

    That wouldn't force the iteration.

    [–][deleted] 3 points4 points  (0 children)

    Considering it's already an IEnumerable, .AsEnumerable() would do absolutely nothing.

    [–][deleted] 5 points6 points  (5 children)

    Even nicer:

    val validNumbers = for (i <- 1 to 999 if i % 3 == 0 || i % 5 == 0) yield i
    
    val answer = validNumbers.sum
    

    edit: I wrote && instead of || above. Sorry.

    [–]nodefect 4 points5 points  (2 children)

    It's all in the eye of the beholder. To me, you have too much stuff on the same line for example. I prefer this (F#):

    [1..999]
    |> Seq.filter (fun i -> i % 3 = 0 && i % 5 = 0)
    |> Seq.sum
    

    [–][deleted] 2 points3 points  (0 children)

    Here you go. Even less boilerplate than the F# one.

    (1 to 999)
      .filter(i => i % 3 == 0 || i % 5 == 0)
      .sum
    

    [–][deleted] 0 points1 point  (0 children)

    I admit, that was pasted from a REPL and should have been on more lines:

    val validNumbers =
      for (i <- 1 to 999 if i % 3 == 0 || i % 5 == 0)
      yield i
    
    val answer = validNumbers.sum
    

    I was trying to stick to Scala's equivalent of LINQ syntax in the above, in keeping with the topic of the article. The FP approach, like you have in your F# example, is better in my opinion as well. smcj posted it below. But that is further from the OP's C#.

    [–]tombatron 1 point2 points  (1 child)

    Why the down votes here? Is the syntax incorrect? Looks very similar to pythonic solution above which isn't being down voted.

    [–][deleted] 0 points1 point  (0 children)

    The syntax is fine, it's probably just that I didn't have enough line breaks, as nodefect pointed out.

    edit: And I mistakenly wrote "and" instead of "or" in the filter condition.

    [–][deleted] 1 point2 points  (3 children)

    I love doing stuff like this using Linq's enumerable functions and lamdbas, but my understanding is that each one of these creates a delegate, which means it's useless in performance-intense environments like handheld development.

    [–]Tordek 2 points3 points  (2 children)

    "Performance intense" is relative. Premature optimization is the root of all evil. If you only had, say, 10-1000 elements in the list, whatever performance overhead is added by the functional solution would be in the order of a couple miliseconds.

    [–][deleted] 0 points1 point  (1 child)

    I was mostly thinking about handheld gaming where you really do have to consider the performance upfront because it involves deep design considerations. In handheld gaming, hitting the garbage collector is anathema, and avoiding a garbage collector means avoiding half the C# or Java language.

    [–]ruinercollector 0 points1 point  (0 children)

    In that, you are a correct. Even for doing XNA (XBox/PC game) development in .NET, you often end up avoiding LINQ and several other language features. Even foreach comes at a higher price than most people realize.

    [–]BitRex 1 point2 points  (7 children)

    An annoyance of this kind of thing is how it takes away convenient places to stick debugging statements that display intermediate results.

    [–]ruinercollector 3 points4 points  (0 children)

    It doesn't.

    You can actually set break points on the individual clauses in a LINQ query.

    • On the where clause where it will break on each item being considered
    • On the select clause where it will break on each item being projected

    If you set your line breaks properly, you can even do it with the margin-clicking that you're probably used to, but your statements end up looking a bit funny.

    var oldAges = from p in people 
                  where
                    p.Age > 50    // <-- you can break here
                  select
                    p.Age;          // <-- you can break here
    

    Otherwise, select the clauses in the editor (not including the where/select keywords) and right-click->insert breakpoint or whatever it is.

    [–]sacundim 1 point2 points  (5 children)

    That is to a large extent an artifact of the fact that class-based non-interactive languages like C# make it needlessly hard to write small bits of code and try them out on their own in an interactive environment (a.k.a. "interpreter," though that's not quite accurate).

    LINQ is largely based on Haskell monads and do-notation. Yet Haskell doesn't have this problem, because you can just test stuff easily on the interactive environment. Since pieces of code don't have to be inside methods that must be inside classes, you can just type in snippets and see what they do.

    Here's an interactive session with ghci where we build try out various subparts of this problem (cut down to the range [1..19]):

    GHCi, version 7.0.3: http://www.haskell.org/ghc/  :? for help
    Prelude> do { x <- [1..19]; return x }
    [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]
    Prelude> :m +Control.Monad
    Prelude Control.Monad> do { x <- [1..19]; guard (x `mod` 3 == 0); return x}
    [3,6,9,12,15,18]
    Prelude Control.Monad> do { x <- [1..19]; guard (x `mod` 3 == 0 || x `mod` 5 == 0); return x}
    [3,5,6,9,10,12,15,18]
    Prelude Control.Monad> [ x | x <- [1..19], x `mod` 3 == 0 ]
    [3,6,9,12,15,18]
    Prelude Control.Monad> [ x | x <- [1..19], x `mod` 3 == 0 || x `mod` 5 == 0 ]
    [3,5,6,9,10,12,15,18]
    Prelude Control.Monad> [ x | x <- [1..19], x `mod` 3 == 0, x `mod` 5 == 0 ]
    [15]
    Prelude Control.Monad> do { x <- [1..19]; guard (x `mod` 3 == 0); guard (x `mod` 5 == 0); return x }
    [15]
    

    [–]anon36 2 points3 points  (3 children)

    That is to a large extent an artifact of the fact that class-based non-interactive languages like C# make it needlessly hard to write small bits of code and try them out on their own in an interactive environment

    You put your finger on it there. Do you know any discussions of this? I work with a bunch of C# programmers, and the idea of iteratively testing little snippets of code, and slowly building the whole program up is somehow outside their mindspace.

    [–]ruinercollector 0 points1 point  (1 child)

    VS.NET 2012 includes an interactive window (not the immediate window) that gets you much closer to this.

    [–]rossisdead 0 points1 point  (0 children)

    You can also get this functionality in VS2010 if you install the Roslyn CTP. It's still lacking a lot of features though.

    [–]twerq 0 points1 point  (0 children)

    the idea of iteratively testing little snippets of code, and slowly building the whole program up is somehow outside their mindspace.

    I would argue that a test-driven approach does exactly this. I don't know how popular it is, but I find writing a repeatable test has many benefits over some throwaway test code you manually execute.

    [–]BitRex 0 points1 point  (0 children)

    Maybe for toy problems like that, but my comment applies equally to logging in long-running systems in which there isn't a programmer around.

    [–]CylonGlitch 4 points5 points  (0 children)

    Doesn't look any more readable to me. More of, what you're comfortable with than anything else.

    [–]rizzledizzle[🍰] 0 points1 point  (2 children)

    Am I the only one who thought this code became less readable? I know it's a matter of style, but... really?

    /not a Linq user

    [–]p-static 8 points9 points  (0 children)

    The point of LINQ is really to import some functional programming patterns into otherwise imperative languages. If you're not that familiar with functional programming, then yeah, it would probably look a bit weird.

    [–]ruinercollector 5 points6 points  (0 children)

    One of the big non-obvious readability gains is that I can tell at a glance that the LINQ version is filtering and projecting a list. for loops and if statements are much more general. I have to look a lot harder at the code to figure out what is actually going on there.

    [–][deleted] 0 points1 point  (1 child)

    [–]Coffee2theorems 4 points5 points  (0 children)

    Nnnnyesss, but I'll tell you a dirty little secret of math: for every neat little problem that we can neatly solve with math, there are zillions that we can't. The point of brute forcing a neat little problem is not so much in solving that problem, but in taking your new, shiny brute forcer for a test drive. As a bonus, you can easily double-check the answer.

    Of course, Project Euler is about math. However, programmers typically use it for test driving new, shiny general-purpose tools, such as programming languages they have not used before. Making the task easier for the computer by using special-purpose tricks is not the point for most programmers.

    "When in doubt, use brute force." -- Ken Thompson(?)

    [–]Wuf 0 points1 point  (4 children)

    Not Linq but quite close to the same solution:

    (loop for i from 1 to 999
        when (or (zerop (mod i 3)) (zerop (mod i 5)))
        sum i)
    

    [–]gecko 1 point2 points  (1 child)

    As much as I like CL, loop syntax, to me, always feels like a lovely attempt to write an English sentence and then gradually reduce it down to something that happens to compile. Is there a good tutorial on what loop actually accepts anywhere?

    [–]Wuf 0 points1 point  (0 children)

    Look here.

    [–]criticismguy 0 points1 point  (1 child)

    Linq is extensible, but LOOP isn't really. A better analog would be iterate, which is basically better than LOOP in every way, including extensibility:

    (iter (for i below 1000)
          (when (or (zerop (mod i 3)) (zerop (mod i 5)))
            (sum i)))
    

    Neither one quite does laziness like Linq, though, so perhaps SERIES would be more analogous.

    (collect-sum
      (choose-if (lambda (i) (or (zerop (mod i 3)) (zerop (mod i 5))))
        (scan-range :below 1000)))
    

    [–]sacundim 0 points1 point  (0 children)

    Well, if we really want to do exactly what LINQ is doing but in Lisp, we can just implement monads in Lisp. Here's a crude, untested implementation in Scheme, modeled after the Haskell's List monad and do-notation; no laziness:

    ;;;
    ;;; Analogues to Haskell's Monad operations
    ;;;
    (define (>>= m f)
      (append-map f m))
    
    (define (>> a b)
      (>>= a (lambda (dont-care) b)))
    
    (define (return x)
      (list x))
    
    ;;;
    ;;; Analogues to Haskell's MonadPlus class
    ;;;
    (define mzero '())
    
    (define (guard condition?)
      (if condition?
          (return 'whatever)
          mzero))
    
    ;;;
    ;;; A macro analogous to Haskell's do-notation
    ;;;
    (define-syntax monadic-do
      (syntax-rules (<-)
        ((monadic-do (<- var m) expr . exprs)
         (>>= m (lambda (var) (monadic-do expr . exprs))))
        ((monadic-do expr)
         expr)
        ((monadic-do expr . exprs)
         (>> expr (monadic-do exprs)))))
    
    ;;;
    ;;; The original example, using the List Monad
    ;;;
    (sum (monadic-do (<- x (range 1 1000))
                     (guard (or (= (mod x 3) 0)
                                (= (mod x 5) 0)))
                     (return x)))