|
I use whatever is appropriate, and refuse to use new language features just because they're new. I still resist using Entity Framework because generalization on that scale usually means bloated and inefficient code.
".45 ACP - because shooting twice is just silly" - JSOP, 2010
- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Well, no, Harold, I haven't seen that style because I haven't read any buggy code that was written by someone who did not know that the 'ForEach sequence iterator only works on a List<T>, and will fail on an IEnumerable<WhatEver> ... until ... now
Eric Lippert would agree with you, however, that the 'ForEach iterator is 'gang aft agley': [^]. As Eric (famously) said: "Remember, the purpose of code is not just to communicate to the compiler it is to communicate to the future reader of the code; make it as clear as possible."
While I do think there's something that many programmers innately find "satisfying" psychologically about method chaining a la functional programming, perhaps there is also an attraction to writing the most recent syntax as a way to ... "be cool" ?
But, wait a minute, what about when the purpose of the 'ForEach iterator is to operate on a "projected" IEnumerable to modify elements of a collection where attempting to modify those elements in standard 'for, 'foreach, loops would result in an error. In that case, perhaps the creation of an "extra" List in order to use 'ForEach is ... useful ?
cheers, Bill
«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
|
|
|
|
|
BillWoodruff wrote: Well, no, Harold, I haven't seen that style because I haven't read any buggy code that was written by someone who did not know that the 'ForEach sequence iterator only works on a List<T>, and will fail on an IEnumerable<WhatEver> ... until ... now Damn
Can I get away with this if I pretend it's my own extension method?
|
|
|
|
|
Hi, Harold, I am sending you via mental telepathy one of my rationalization-rations; I don't know why the gods give me so many ... is it because it's so clear I need them ?
cheers, Bill
«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
|
|
|
|
|
BillWoodruff wrote: and will fail on an IEnumerable<WhatEver>
Which is why I have an extension method to overcome that shortcoming.
Marc
|
|
|
|
|
Marc Clifton wrote: Which is why I have an extension method to overcome that shortcoming You and Eric:
Eric Lippert, 2009, op. cit. "A number of people have asked me why there is no Microsoft-provided “ForEach” sequence operator extension method. The List<t> class has such a method already of course, but there’s no reason why such a method could not be created as an extension method for all sequences. It’s practically a one-liner:"
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
foreach(T item in sequence) action(item);
} For me, seems like something happened this year where suddenly I felt more comfortable (secure ?) using Linq goodness, and Yield Return, and IEnumerables of whatever, and writing extension methods that have a "socket" for an Action, or Func. I have seen some students bounce off those semantics/facilities, and some take to it like the proverbial "ducks to water."
And (I hope you can still blush), you were an influence on me to "get more into" the method-chaining style, which I really like, now.
Not that I am "catching up" with you (technically) in any way, though: occasionally I get a glimpse of your shadow going around a corner
thanks for the mentories, Bill
«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
|
|
|
|
|
BillWoodruff wrote: I get a glimpse of your shadow going around a corner
You are generous as always!
There are some corners I probably should not be followed:
public static bool If(this bool b, Action action)
public static void IfElse(this bool b, Action ifTrue, Action ifFalse)
etc.
Let's just call those "experiments."
Marc
|
|
|
|
|
Ha! But then there is value in experiments:
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T, int> action)
{
var index = 0;
foreach(T item in sequence) {
action(item, index);
index++;
}
}
For example, I am curious if I could find value in (probably with a different body implementation):
public static async Task ForEachAsync<T>(this IEnumerable<T> sequence, Func<T, Task> actionAsync)
{
foreach(T item in sequence) await actionAsync(item);
}
|
|
|
|
|
Is that a Smalltalk influence I detect?
In Smalltalk, there are no control flow statements beyond sending messages. However, the boolean object responds to the messages ifTrue: and ifTrue:Else:
(x < 3) ifTrue: [ x <- 3 ].
(x < 3) ifTrue: [ x <- 3 ] Else: [ x <- x + 1 ].
And of course similar constructs such as:
(x > 0) whileTrue: [ x <- x - 1 ].
Here [] denotes a block of code (similar to a closure) and <- denotes assignment.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
Definitely, cancer in my world. My goal is to build quality software that any level of developer can easily understand and change, if needed. Hey, I might die tomorrow. I don't run after the newest thing and don't try to be fancy or cute.
It is probably popular because organizations, such as MSFT, bring out new features to get more people on board using their products. Young people just starting out have a difficult time getting established, plus they like to be fashionable; so they try to code fancy with all the new stuff, to make the big money.
|
|
|
|
|
The newest thing? It has been around for almost 10 years...
The paradigm itself, readable, no side-effects code making heavy use of lambda's (or anonymous function) has been around almost as long as programming. It's called functional programming.
|
|
|
|
|
Sander Rossel wrote: The newest thing? It has been around for almost 10 years...
Exactly. I'm baffled by the people in the thread calling this style a new thing
|
|
|
|
|
As LISP came out in 1958, it makes it a pretty old thing for programming. Venerable even.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
Alan Kay.
|
|
|
|
|
It seems I may be in the minority, but I don't find that (or predicates in general) unreadable.
/ravi
|
|
|
|
|
As others have said, it might give you "nerd points", but IMO it is the C# equivalent of APL one-liners - easy to write, impossible to debug or understand 6 months down the line.
Under some circumstances, this coding style may produce faster code, but that remains to be measured.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
Daniel Pfeffer wrote: impossible to debug or understand 6 months down the line.
I'd have to disagree with that - I've got LINQ code going back eight years which is still perfectly understandable. It tends to be easier to read than the equivalent imperative code, especially if you try to squeeze all of the filtering, grouping, sorting and projecting code into one method to try to make it go faster.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
harold aptroot wrote: Is this style cancer?
Not in my opinion.
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.
Marc
|
|
|
|
|
Exactly, well put
|
|
|
|
|
/ravi
|
|
|
|
|
Ok OrderByDescending is convenient and having to retroactively put in sorting into normal code is annoying. That doesn't sell it for me. It's still "codegolfing but with longer method names" to me.
|
|
|
|
|
harold aptroot wrote: "codegolfing" 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.
cheers, Bill
«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
modified 17-Jul-16 12:47pm.
|
|
|
|
|
harold aptroot wrote: t's still "codegolfing but with longer method names" to me.
Well, if readability, simplicity, maintainability, and a more functional programming syntax style don't sell you, then I don't know what will.
And an FP style is often times better because those "long method names" are descriptive of what is happening, rather than having to look at code to figure out what is happened.
Marc
|
|
|
|
|
Marc Clifton wrote: readability, simplicity, maintainability, These might have sold it to me if they were true. They're true for you, but not for me.
The functional syntax I see as detrimental.
|
|
|
|
|
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.
|
|
|
|
|