The Lounge is rated PG. If you're about to post something you wouldn't want your
kid sister to read then don't post it. No flame wars, no abusive conduct, no programming
questions and please don't post ads.
So what you'd have is (a bit cleaned up and assumptions made):
foreach(var stuff in someStuff)
if (stuff.c != "What")
Hell(stuff.d + "The");
harold aptroot wrote:
Side question, why is this style popular?
I think, given the above example, the answer to that is obvious. But if you want it enumerated (hardeeharhar):
1) Easier to understand the logic
2) Simpler code
harold aptroot wrote:
I file this firmly under "stupid one-liner 'clever' code with no benefits to compensate".
Sure, it can be abused, but for me, the Linq statement is so much more readable and understandable, in a very short order of time, than the longer format.
Consider also some order advantages:
someStuff.Where(c => c != What).Select(d => d + The).OrderByDescending(q => q.CreateDate).Foreach(e => Hell(e));
What a PITA to have to create yet another list to reverse the order, and if you're abstaining from Linq altogether, you'd probably have to call a method to re-order the list on the desired field. More kruft, more complexity, more things to go wrong, more hard to understand imperative code.
Furthermore, if you need to change the order, the above "long" code example breaks, because now you have to create a separate list of the filtered items so you can then sort that -- I assume you wouldn't want to sort the unfiltered list!
So, add another item to the reason the "style cancer" is better:
3) more maintainable
The style cancer, as you call it, is very much like functional programming, where each function results in an output that you pipe to the next function as its input. It's a much much cleaner style.
Strange thing there, Harold; last Sunday's crossword puzzle had, as its long-tail-quote, something former US Prez Gerald Ford supposedly said:
"I am not getting better playing golf because I hit fewer spectators"
Have you ever looked at the XML the WCF serializer generates: object-name prefixes and suffixes can total twenty characters and more. It has become my habit to write long descriptive names in code, even though I am a solo act; part of that is because I want any students who may see the code to encounter such long mnemonic names ... and, partly because I am a speed touch typist, so the perceived "cost" of typing longer names is minimal ... and, of course, ReSharper and the VS editor make name completion a snaparoo.
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
Having scored technical interview questions/tests before, I can tell you now, that developers that don't know-and-use linq, are the bottom of the barrel...
In one of the threads of this discussion performance is talked about, and while true that raw performance of a for/foreach for basic enumeration is marginally better, and has less overhead, you'll find that linq performs scores faster for more complex enumerations.
It basically comes down to devs not really understanding how they are putting code together, and linq is a great way to build up an enumerator before actually executing it. It is simply plain wrong to say linq doesn't perform as well, because not only did the succinct linq answers perform better than the code of the senior devs that were taking those tests, but we ran benchmarks, and the memory footprint was minimal in comparison, and every time a linq expression was used, the unit test covering the question passed, whereas it was closer to 20% for devs not writing linq (there was time pressure on the tests - I am sure the number would have crept up had there been more time, but it also shows that linq was faster to write a solution with).
Whether you think it is less readable, less simple or less maintainable is truly your opinion, but it sounds as though you, and others posting in this discussion, actually need to do some research on linq, because it shows a lack of understanding of the other benefits too.
Yes, it can be abused, but in the right hands it can produce some fantastic results.
I have to admit that I hate the more sql form of LINQ and find it extremely unreadable even though I am pretty comfortable with SQL. As far as debugging, I have to agree that it is much harder to debug, but it is also true that a long equation is harder to debug than breaking it up into pieces. I have had times in the past when I was having difficulty with a LINQ statement and did break it up, just like on an equation that was giving me problems. However, generally, I find that my LINQ statements are a lot more reliable than when I try to do the same thing without LINQ. I am of course talking about the simple case that you have. Personally I find the LINQ statement clearer then the foreach statement and the if statements. Also, I like to be able to see as much flow of the class and method as I can when looking at them on the screen, so I prefer much more compact code, but that is probably because I am more the type that wants to see the forest, and not focus on the trees. I can understand the complexity concern on more complex LINQ statements, but in order to reproduce the same thing, like the capability of joins, I would need a lot of code, and much easier to introduce errors.
In other words I like LINQ, and to me it is where programming languages are going. It provides an awful lot of power, and saves a lot of programming. If we took your approach to the extreme we would still be using assembly language. After all is in not easier to debug
b = 6
a = b / 2
c = b * a + 4
Would you also advocate getting rid of SQL. SQL is horrible to debug, and I think worse than using extension methods, but you are basically advocating the elimination of SQL. It is also extremely difficult to understand. I have worked with some SQL that goes on for pages, it was miserable.
Nope, I love that style of programming.
It's SO much more readable than a foreach/for/while loop.
It becomes immediately clear what the code does.
There's some collection than we need to filter, transform and process whereas a loop is just a loop and might do all those things, but you won't know until you read through the loop, probably with a lot more code to keep the new lists and counters. I've found a lot more unreadable loops than LINQ queries. I have no idea why you'd find it unreadable, it reads almost like natural language...
Anyway, that style is necessary for LINQ to SQL/Entities (because loops can't build expression trees, convert that to SQL and be lazy evaluated). And if I had to choose between LINQ or plain old SQL I'd choose LINQ wherever possible.
Only the .ForEach() is an odd one. It's defined on List<t> and not as a LINQ extension method because ForEach, by definition, has side-effects and LINQ was designed keeping the functional paradigm in mind. I never use it.
When I started programming, "some" years ago, people where complaining about the performance of Object Oriented Programming (I won't speak of assembly vs. "high-level" language).
A "few" years later, when .NET arrived, the same was said regarding the use of the Framework compared to native code.
The "idea" isn't bad per say ... just that it tends to be taken too far.
Personally I try to keep such Linq chains down ... at most two dots in such a call (at least that being a quick-n-dirty rule-of-thumb). Especially as a normal for/foreach tends to be more efficient too, your sample is quite litterally performing 3 loops where one for loop would have sufficed.
The only time I feel such long chain of Linq extension methods make sense is if using the Linq SQL syntax instead. Though it's still not very efficient, actually less so than the pseudo FP style.
The chain of Linq statements clearly perform 3 loops (one of which is unnecessary). Yield doesn't "magically" fix that. And to show by how much such Linq chains (and even the Linq-to-SQL version) adds extra overhead - look at the performance of that yield function.
And just to make doubly sure no JIT optimizations skew the benchmark - I added an extra loop before starting the stopwatch, and rearranged the orders: BenchLinqLoops[^]
Now you actually see the SQL variant's "extra" overhead - i.e. being translated into (effectively) the LinqAddXToEven2Loops function before it runs.
Linq has both it's Pro's and Con's. However, there is a clear benefit: Easy to write and easy to read (keep in mind that, if using Visual Studio, you have full intellisense support. And you can use your favourite code template, too.)
someStuff.Where(c => c != What).Select(d => d + The).Foreach(e => Hell(e));
looks better to me than
List<SomeStuff> tmpStuffList = new List<SomeStuff>();
for (int i = 0; i < someStuff.Count - 1; i++)
if (someStuff[i] != What)
for (int n = 0; n < tmpStuffList.Count - 1; n++)
We should be using that syntax because it's cleaner and more readable than lots of indented loops.
Our problems (at this point) are
There's not enough good guidance on not doing dumb things (ToArray etc being case in point).
EF does a helluva job converting LINQ to SQL so what would be interesting is if there was a preprocesser that went through the whole LINQ chain, worked out what was really happening, then optimised (ie not did a bunch of stuff, parallelised other stuff, vectorised some stuff etc) and made it more efficient than foreach loops (which themselves are not efficient).
We shouldn't have a million devs optimising the same code. We should be able to express the code in elegant syntax and have the tools do the optimisation.
Here it's still obvious. It's the chaining where things start to get confusing.
Besides, I can't agree with your statement that you must create a list, after all you need those checkboxes in order to do something with them, you can most of the time just do that in the very same loop that checks them.
You said "for vs LINQ", I show you obvious case where you're not right. If you wanna just discuss how long LINQ can be - it's different question.
You don't understand word "materialized". If you use "for", you have to create physical list, where you keep your objects. In case of LINQ you have Enumerator, which will not take any object until you ask! It's important difference when you have billion objects, where half of 'em match your query. Enumerator just pass 'em one-by-one (keeping memory consumption low exactly for ONE ELEMENT), while your "for" takes all necessary memory at once.
I did not, I showed an example of what I deem unreasonable. Using a single clause is still clear, if often unnecessary, though I like Max for example - there's a case where it really is simpler than an equivalent explicit loop.
You don't understand word "materialized". If you use "for", you have to create physical list, where you keep your objects.
Oh you mean the source, sure. foreach it is then, problem solved.
You shown long LINQ query and start talking about "foreach". But even being that long, FORMATTING RULES.
someStuff.Where(c => c != What) // comment why you do it
.Select(d => d + The) // comment why you do it
.Foreach(e => Hell(e));// comment why you do it
Oh you mean the source, sure. foreach it is then, problem solved.
Nope. You do not solve problem if you prepare list of objects thru foreach - you have to put 'em in a List<> (because hell knows how it will be used later). In case of LINQ you prepare just REQUEST (which takes zero memory), which later will enumerate any amount of objects. And BTW same request can be enumerated many times.
Agreed, this is cancer. IEnumerable and Linq will cause far more instructions to be processed by the processor than a simple "for" loop with an "if". Will the average user notice this? No, not on todays computers. But as more people do these trick things, it does build up.
I remember when trick things were done to save processor clock ticks, and it was just as bad for reading code. The smart ones would document the clever code with comments with a reasoning why it had to be done.
if you've seen that in production code before, people are trying to be clever for clever sake, I just don't see the benefit.
I now have my son back. Last Christmas we finally gave in and bought our son an iPad. Since then we have become iPad widows. Nothing else interests him...until now that is. Pokemon go has got him off the iPad and onto the...iPhone. I know it doesn't sound like much...but it is. Leaving the house is so easy now, no arguments. Sometimes the signal goes and he is forced to talk about the interesting surroundings. And what's more, someone had the bright idea to make pubs pokestops a place where you get random gifts. Thanks Nintendo -bringing families back together again since 2016.
Just another experiment by the elite pushing towards a paradigm where all reality is augmented through technology, whether it is this or "google glass" or self driving cars, and government has the capacity to alter any information past present or future.
Does it also happen with other games? The graphics processor can draw a lot of power, just like the CPU. It could be that both together draw too much power and the power supply is too weak. Then the voltage would drop and it would react as if the cable had been disconnected. Try running some other more demanding game to find out.
"I don't know, extraterrestrial?"
"You mean like from space?"
"No, from Canada."
If software development were a circus, we would all be the clowns.