Using IEnumerable nonsense for everything
-
Why? A for loop tends to be far clearer and easier to read, not to mention faster and more efficient.
obermd wrote:
A for loop tends to be far clearer and easier to read
Because that's your opinion and when I code I don't take your opinions into account :)
GeoGame for Windows Phone | The Lounge Explained In 5 Minutes
-
You've probably seen this style if you're done anything with C# after 2007 or so. someStuff.Where(c => c != What).Select(d => d + The).Foreach(e => Hell(e)); Instead of, you know, a plain old `for` loop with an `if` in it and so on. Or maybe `foreach` if you want to be fancy. So, now we have nearly a decade of experience with this, can we finally settle this question: Is this style cancer? I still think it is, and the retort "you just have to get used to it" isn't going to work any more. I file this firmly under "stupid one-liner 'clever' code with no benefits to compensate". Yes, I've argued in the past that "clever code" isn't necessarily bad, and I'll keep saying that - there's a time and a place for it. But not if you're just trying to be cute. "Oh look at me, I put everything on one line, +1 nerd points for me" And this is even worse. It's not just cute with no benefits to compensate, it's cute and harder to read. Side question, why is this style popular?
I agree with Harry here, but I think a lot of developers, including maybe even Harry, are missing the point. Programming code is not there to suit the computer, or the compiler, or the run-time engine. If it was, we would do everything in machine code, or p-code, or whatever. Code is there to be read by PEOPLE. Anything that obscures that intent is, basically, just pretentious BS. Why should I have to stop and ponder your code for even 3 seconds? Every time I see that line?
-
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.
-
F-ES Sitecore wrote:
That line throws a null exception...can you look at the line that threw the exception and know what the issue is?
Assuming I'm using LINQ, the most likely culprit would be
GetAList
returningnull
. Failing that, I'd have a stack-trace to tell me where the exception occurred. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
But you agree it wouldn't be immediately obvious like it would if you weren't using linq?
-
I would be a bit surprised if your first point was true. Please give me a couple examples of optimizations that depend on function size.
Mike Marynowski wrote:
I would be a bit surprised if your first point was true. Please give me a couple examples of optimizations that depend on function size.
Small functions can be in-lined by the optimiser, so this code
foreach(string x in y)
{
x = x.Trim().ToLower();
DoSomething (x);
}function DoSomething(string s)
{
if (s.StartsWith("hello"))
{
s = "test";
}
}might be optimised to this
foreach(string x in y)
{
x = x.Trim().ToLower();
if (x.StartsWith("hello"))
{
x = "test";
}
}thus avoiding a code jump\stack update etc.
-
Mike Marynowski wrote:
I would be a bit surprised if your first point was true. Please give me a couple examples of optimizations that depend on function size.
Small functions can be in-lined by the optimiser, so this code
foreach(string x in y)
{
x = x.Trim().ToLower();
DoSomething (x);
}function DoSomething(string s)
{
if (s.StartsWith("hello"))
{
s = "test";
}
}might be optimised to this
foreach(string x in y)
{
x = x.Trim().ToLower();
if (x.StartsWith("hello"))
{
x = "test";
}
}thus avoiding a code jump\stack update etc.
Yes, but that optimization doesn't have to be made if you are putting everything into a big block of code lol. I'm not advocating for that approach, just saying that splitting into functions is unlikely to boost performance...in the best case it will match performance after optimizations, which is basically what is happening in this example.
-
But you agree it wouldn't be immediately obvious like it would if you weren't using linq?
If I wasn't using LINQ, then I'd be able to identify which line in the massive complicated method the exception was thrown from. Whether it would be obvious why the exception was thrown is a different matter. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
If I wasn't using LINQ, then I'd be able to identify which line in the massive complicated method the exception was thrown from. Whether it would be obvious why the exception was thrown is a different matter. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
So it's easier to debug without linq? :)
-
So it's easier to debug without linq? :)
No, because you've still got a massive overly-complicated method to dig through to find the cause of the problem. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Richard Deeming wrote:
Writing all of your code in one big
Main
function is faster than any of this "object-oriented" nonsense.That is, almost certainly, not true. With one big function, the optimizer will have to practically shut-down. Many smaller functions can be highly optimized.
Richard Deeming wrote:
And using C or assembly will be much faster than this JIT-compiled C# nonsense.
Again, real world examples have shown that letting the computer do things like managing your resources, is much faster than trying to do it yourself manually.
Truth, James
I think I need to buy one of those "sarcasm" flags. :-D
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
No, because you've still got a massive overly-complicated method to dig through to find the cause of the problem. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
You instantly know the code that threw the error though so that's a big starting point. Let me give you a better example
string mytext = mydata.Where(a => a.Name != "Admin" && a.ID < 1000).OrderBy(b => b.Surname).SelectMany(c => c.Role).FisrOrDefault(d => d.Updated.Year == DateTime.Now.Year);
We've all seen code like this, right? Let's say it throws a null exception, good luck finding out what is null. If you split your code into functions\loops you don't have that issue.
-
You instantly know the code that threw the error though so that's a big starting point. Let me give you a better example
string mytext = mydata.Where(a => a.Name != "Admin" && a.ID < 1000).OrderBy(b => b.Surname).SelectMany(c => c.Role).FisrOrDefault(d => d.Updated.Year == DateTime.Now.Year);
We've all seen code like this, right? Let's say it throws a null exception, good luck finding out what is null. If you split your code into functions\loops you don't have that issue.
Start by changing the code to:
string mytext = mydata
.Where(a => a.Name != "Admin" && a.ID < 1000)
.OrderBy(b => b.Surname)
.SelectMany(c => c.Role)
.FirstOrDefault(d => d.Updated.Year == DateTime.Now.Year);Your stack trace will include a line number, which will tell you exactly which line you need to look at. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Start by changing the code to:
string mytext = mydata
.Where(a => a.Name != "Admin" && a.ID < 1000)
.OrderBy(b => b.Surname)
.SelectMany(c => c.Role)
.FirstOrDefault(d => d.Updated.Year == DateTime.Now.Year);Your stack trace will include a line number, which will tell you exactly which line you need to look at. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Guess null exceptions aren't a particularly great example of debugging, despite what you might read on CP they're not the hardest issues to track down. When it comes to logic issues with streams of chained linq statements if you want to debug them to find out better why you're getting\not getting the results you want you often have to isolate the steps and loop at them in-turn which is an additional faff you wouldn't have otherwise.
-
Guess null exceptions aren't a particularly great example of debugging, despite what you might read on CP they're not the hardest issues to track down. When it comes to logic issues with streams of chained linq statements if you want to debug them to find out better why you're getting\not getting the results you want you often have to isolate the steps and loop at them in-turn which is an additional faff you wouldn't have otherwise.
I still think that's easier to do if you're reusing small methods that do one clearly-defined thing, and which have been thoroughly tested, than if you've lumped all of the implementation into one giant method. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
I still think that's easier to do if you're reusing small methods that do one clearly-defined thing, and which have been thoroughly tested, than if you've lumped all of the implementation into one giant method. :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Regardless, debugging is still harder with chains of linq statements, that's the only point I was making.
-
That might be true but it comes at the cost of jumps and stack management for function calls. I think you will be hard-pressed to find an example of one block of code that runs slower than similar code split into more functions.
But then, what about library functions? Are you going to inline every call to ToUpper() or Trim()? If you do, you have a unmanageable mess. If you don't, then you're back to the costs of jumps and stack management, so what's a few more?
Truth, James
-
Linq => Backward SQL
We're philosophical about power outages here. A.C. come, A.C. go.
Actually, I think of it as SQL the right way round. A good clue comes from intellisense. It cannot get the field names unless you write the FROM before the SELECT.
"If you don't fail at least 90 percent of the time, you're not aiming high enough." Alan Kay.
-
But then, what about library functions? Are you going to inline every call to ToUpper() or Trim()? If you do, you have a unmanageable mess. If you don't, then you're back to the costs of jumps and stack management, so what's a few more?
Truth, James
"What's a few more" is often significant overhead. I don't know what argument you think I'm making. The comment that is the topic of my comments simply said that writing your code in a big main function is faster that all this object oriented stuff but probably a bad idea. I'm agreeing with that.
-
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
Imperative to Functional Programming Succinctly Contributors Wanted for Higher Order Programming Project! Learning to code with python is like learning to swim with those little arm floaties. It gives you undeserved confidence and will eventually drown you. - DangerBunny
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.
-
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.
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
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.