The commutes too long for that.
I'm going to resort to using snide commenting in my code, instead.
Printable View
The commutes too long for that.
I'm going to resort to using snide commenting in my code, instead.
lol....;)
Well on the bright side looks like I've created a good topic to discuss. I've learned a little here and I hope everyone else has picked up something as well. I really joy these discussions. So nice to debate and learn new stuff through debate. I will try to limit my commenting in the future.
It's not so much about limiting it, it's abut targetting it. I think JM hit the nail pretty much on the head for me when he said commenting is about explaining "why" rather than "what". The next developer, if he is even half way decent, can see the "what" at a glance. The "why" is much harder to spot.Quote:
I will try to limit my commenting in the future.
I think the debate, really, is about how you should explain the why. Us minimalists believe our primary method of doing that should be the code itself. Maximalists (if there is such a thing) believe that explicit commenting is better and/or adds an extra level of clarity above and beyond what the code itself can. Ultimately, it doesn't really matter which of us is right because it's not about the comments or the code, it's about the clarity. As long as clarity is achieved than it doesn't really matter how.
I must admit that I found the .Any jarring as well and would probably have gone with .Count > 0. I guess that's only because it's a property that was new to me though. I thought the really good stuff EG demonstrated was breaking out the helper methods. Because that gives you a chance to explicitely name the helper method it also gives you a chance to encapsulate a great deal of information in that name. It's really the High-Cohesion principle applied at a method rather than class level and is, IMO, a much better way of writing your code.Quote:
I found that it did not capture the intent very well at all
Like I said, though, I personally still struggle with it. My ingrained tendancy is to have the problem mapped out in my head and just want to dump it down onto the screen. That tends to lead me to writing one big long method. Decomposing it into tiny parts is very much a concious, and not very comfortable, step for me. Still, I think it's one worth taking.
On the performance vs readability issue, I think you're being a little unfair when you say "one day you have to rewrite the whole thing" (I'm paraphrasing because I'm on the next page of the thread) because that's not what happens. What does sometime happen is that a particular part of the program becomes a bottleneck. So then you just refactor that particular part to optimise it and then, yes, you will sacrifice readability for speed.
I think this discussion has pretty much run its course. We've basically got to the point where we're just restating our positions now, but a couple of final points worth addressing:
No, I wouldn't code with implicit conversions, because it's not about "easier to read" it's about "easier to maintain". It's about the process of going from the code displayed on screen to a sufficiently accurate mental model of the intent of the code in the programmer's head. Implicit conversions may transfer the textual representation into your brain more easily, but then you need to figure out where all the converting occurs, which makes it harder to understand.
If it comes down to a choice between fast or clear then I would definitely choose clear on the first pass. The reason is that it's very easier to sacrifice the clarity for speed if you need to, but it is much harder to understand that fast code later. Since it is much more likely that you need to modify code for bugs or changing requirements than you are to need to improve its performance, it is always worth striving for the clarity over speed.
Also, the question on performance isn't "which is faster", it should be "which is fast enough?". If you have two approaches, and only one meets your performance budget (whether that be speed (with all its sub categories [time-to-first-byte, time-to-last-byte, throughput]), memory, power consumption, etc), then you clearly need to use that approach. If neither meets your performance budget, well then you've got a problem. If both meet your performance budget then you choose the clearest code - even if it isn't the fastest. Note that all this assumes you have a performance requirement you need to meet. If you don't have a performance requirement (and, no, "must be fast" isn't a performance requirement) then you don't have a performance problem - and prematurely optimising before you have any performance data has the potential to make your performance worse. Also, optimising in one area could cause a bigger slowdown somewhere else.
So as another saying you may have heard goes: "Measure twice, cut once". Except that in performance considerations your two measures need to be one before and one afterwards.
I can't remember who said earlier in the thread that they tend to write pseudo-code comments to define the top level idea of the method. I do something similar in that I don't think through the details when I first approach a method. I know that to do X, i will need to do A, B and C, but I don't particularly worry about how I'll do A, B or C straight off. However, instead of writing comments like this:
I'll instead write something like this:vbnet Code:
Public Sub doX() ' do A ' do B ' do C End Sub
I can use the IDE to insert method stubs for those three methods. Now when I'm thinking about how to implement A, I write that code in the doA method, rather than under the doA comment in the doX method.vbnet Code:
Public Sub doX() doA() doB() doC() End Sub
Well, that's actually highly simplified to the point where I don't actually recognise that as my approach, but it's kinda how I work.
Heck, I thought it had run its course before it got moved to General Developer. I'm surprised at how much, and how well, it has taken off since then. Rather nice, really.
That all sounds good to me. I recognize that part of my views comes from working on a series of projects that have real potential for running into slowdowns due to the likelihood of having LOTS of iterations, but often unknown numbers of iterations. That situation argues for watching the time taken in any one particular iteration. A type of program that I tend to work on a fair amount where this applies would be Genetic Algorithms, where each individual generation is trivial...but there are so MANY of them. Still, in a general business app, I think I would do it the way you suggest.Quote:
No, I wouldn't code with implicit conversions, because it's not about "easier to read" it's about "easier to maintain". It's about the process of going from the code displayed on screen to a sufficiently accurate mental model of the intent of the code in the programmer's head. Implicit conversions may transfer the textual representation into your brain more easily, but then you need to figure out where all the converting occurs, which makes it harder to understand.
If it comes down to a choice between fast or clear then I would definitely choose clear on the first pass. The reason is that it's very easier to sacrifice the clarity for speed if you need to, but it is much harder to understand that fast code later. Since it is much more likely that you need to modify code for bugs or changing requirements than you are to need to improve its performance, it is always worth striving for the clarity over speed.
Also, the question on performance isn't "which is faster", it should be "which is fast enough?". If you have two approaches, and only one meets your performance budget (whether that be speed (with all its sub categories [time-to-first-byte, time-to-last-byte, throughput]), memory, power consumption, etc), then you clearly need to use that approach. If neither meets your performance budget, well then you've got a problem. If both meet your performance budget then you choose the clearest code - even if it isn't the fastest. Note that all this assumes you have a performance requirement you need to meet. If you don't have a performance requirement (and, no, "must be fast" isn't a performance requirement) then you don't have a performance problem - and prematurely optimising before you have any performance data has the potential to make your performance worse. Also, optimising in one area could cause a bigger slowdown somewhere else.
That's a fine statement for a tailor, but pointless for software development. The cost of the measurement in software development can easily be higher than the cost of cutting incorrectly.Quote:
So as another saying you may have heard goes: "Measure twice, cut once". Except that in performance considerations your two measures need to be one before and one afterwards.
This is true if you expect the analogy to hold. The measurements are of course completely different for the tailor and the software developer. It's more like expecting the tailor to measure how much cloth he has, and if he doesn't have enough then try cutting up a certain piece of cloth, and then measure all the cloth again. If he now has less cloththan before then he needs to stitch the piece he cut back together and try a different cut, if he now has more cloth but still not enough then he should keep that cut and try cutting a different piece and if he has now has enough cloth then he should stop cutting.
Ye-e-e-eah, I think that saying doesn't really apply in the performance optimisation scenario.
It should be: measure 1 - Requirements; measure 2 - design ... but rather often if falls into a cycle more like this:
Attachment 99411
-tg
That's a painfully accurate diagram. xkcd is pretty awesome.
Yep, that pretty much describes every project I've ever worked on.
I would not say I comment my code heavily, only where it is needed and/or when I am coding something as an example for someone else. Most of my code is written in such a way that you should not need a comment to understand what it does and why it would do it that way.