- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Look at the output running nm on a library or executable on a linux system. You'll see all your classes, methods, enums and so much more!
Admin
What do you mean by right? Fantom only generates the basic setters and getters for you if you don't write them yourself, so it still follows the same idea. They do this "So if you add one later you won't have to recomoile everything" whuich is why a lot of us provide the setter and getter even though it isn't really doing much.
I will still stand on my previous words though, if all you have is that in a business object where are your rules for proper values? A phone number setter should at least check for proper formatting, a quantity should at least check for proper range limits, etc.
Admin
No, this is an artifact of the languages you use, and you're so used to it that you can't imagine it any other way. Look at the way Python, for instance, implements "properties". You have a public variable, and then later, if you need access to that public variable to go through a method, you can change it to do that transparently to the code that uses that class doesn't need to change. Only in C++ and the languages derived from it (e.g. Java) do you see everyone "defensively" creating getters and setters for everything right off the bat.
Admin
C# disappointed me with their attempt at auto-implemented properties which often still require you to declare a separate, private field.
Admin
Oh, my $_DEITY, they're Greenspunning COBOL (the language in which a short novel about the program is the program)!
Admin
True, but it's not clear how that is an argument in favor of code like the example here. It is true that a programmer may change what a function does and forget or not bother to change the comment. But it is surely even more true that a programmer would be unlikely to change function or variable names. That would require finding all the references and updating them.
I have fond memories of a function I once wrote that I called "validateStockNumber". It accepted a stock number as a parameter, looked it up on the database, and returned true if it was found and active, false otherwise. Than another programmer came along and changed this function to also do a bunch of additional work and update the database. I really disliked the fact that a function whose name implied it just did a validation in fact also did database updates. Later someone made another change that removed the validation. But he left the function name unchanged. It was now totally misleading. Some time later another programmer had to build a VB interface to the Java code, mostly consisting of pass-thru functions. He called the pass thru on this one, "ValidateStockNumberButReallyUpdateShippingManifest".
Admin
Correct me if I'm wrong, but (in the case of .NET) doesn't compiling to CLR make it so this doesn't make it take extra memory?
Admin
You can easily write a unit test against this Controller Action. After calling an Action, you can test if the ActionResult is typeof(View) with the ViewName ("Index") and ViewModel ('form') you were expecting
Admin
This embodies the highly questionable idea that longer names are always better. Who says?
I agree that extremely short names, like "x" or "i1", are likely to be uninformative.
But extremely long names mean that figuring out whether two names are the same is now a chore. If I have a variable called "AmountBilledToTheCustomerForShippingChargesOnPackagesSentOverseas" and another called "AmountBilledToTheClientForShippingChargesOnPackagesSentOverseas" and another called "AmountBilledToTheCustomerForShippingChargesOnMailersSentOverseas", etc, it is very easy to get confused when trying to make sense of the program.
No name you give is going to tell the reader exactly what the function does unless the name repeats all of the code contained in that function. At which point, why bother to write a function at all? Just write the code in-line. At best, a name gives the reader a clue what the function is for. At a minimum, it should be meaningful enough that once the reader has figured out what it does, when he sees the name again he can recognize it.
Sure, suppose I create a function to calculate sales tax and I call it "f32". Then I have a function to calculate shipping charges that I call "f33", a function to apply discounts that I call "f34", etc. When I come back to this program in a few months it's unlikely I'll remember which was which. Even after I figure it out again, it will be easy to get confused working my way through the code.
At the other extreme, if I call them "FunctionToCalculateTheSalesOnASaleMadeToACustomerFromOneOfOurStoresOrOverTheInternet", "FunctionToCalculateTheShippingCharesOnASaleMadeToACustomerFromOneOfOurStoresOrOverTheinternet", etc, that will be almost as painful to read and comprehend.
But if I call them "calcSaleTax", "calcShipping", and "applyDiscount", the names are reasonably descriptive, easy to remember, and easy to read.
Let me add that if two functions are similar, the name should tell me how they are similar and how they are different. Like "calcDomesticShipping" and "calcInternationalShipping". Then I can clearly see that both have to do with shipping but one is about domestic and the other is about international. It drives me nuts when programmers give two functions similar names with no clue about how they are different. Like just adding a digit, so we have calcShipping and calcShipping1. Or deliberately mis-spelling a word, like calcShipping and calcShppng. Then I have to guess how they're different.
Okay, I'm off on a tangent of at least somewhat serious discussion rather than the simple ridicule and meme-repetition. Sorry.
Admin
It's written for the .NET framework so it will have terrible performance anyway compared to an unmanaged natively compiled executable. Any further performance penalty caused by terrible coding practices will probably come out in the wash.
Admin
Frist! Irish Girl! Bring back MFD! Oh....sorry.
Admin
Or better yet, have a DomesticOrder class and a InternationalOrder class that both inherit from an abstract base Order class and implement their own CalcShipping functions.
That way the code becomes self-documenting without adding blot to function names. One is DomesticOrder.CalcShipping and the other is InternationalOrder.CalcShipping. If you're looking at CalcShipping inside the InternationOrder class, it should be obvious that it's calculating international shipping! And you don't have to mess around with lots of:
if (isDomesticOrder) order.CalcDomesticShipping(); else order.CalcInternationShipping();
Now it's just
Admin
Obvious troll is obvious.
Admin
Not been here long have you. NEVER assume someone might actually do the sane thing.
Admin
Say what you will about long object names. I'm working with a database designed by a guy who grew up in an era when every fucking byte was precious. If he could still pack his number fields, he would. I've spent (not spended) a week trying to follow his cryptic mess, and I'm ready to kill someone.
Admin
Admin
My eyes hurt.
Admin
Not a WTF at all.
Actually, the code IS self-documenting. A "manager" can read it, and determine the business cases that the code implements. A modern COBOL!
About the only thing I would change (in a code review) would be "ThereIsAtLeastOneSharedActivityTypeBetweenTheEventAndCurrentUser"
That function is not a declaration, but a predicate, and should be named
"IsThereAtLeastOneSharedActivityTypeBetweenTheEventAndCurrentUser"
Now, personally, I would prefer underscore separators for readability, but that is secondary. (I would also like the ability to use ? in names if this sort of thing is being done).
("Is_there_at_least_one_shared_activity_type_between_the_event_and_current_user?" would be better, because it wouldn't slow down reading as much)
The wrapping of "true" and "false" is pure syntactic sugar. The compiler should be capable of optimizing these completely away, anyway.
The logic is approachable by a reader who is not capable of abstract thought. It embodies the business cases. It is maintainable (by use of IDE tools). There are no comments to get out of date. The path of least resistance is to properly update the code, and the "manager" will be able to tell if it hasn't been done correctly.
Really, for most business logic, this is almost perfect. If this style could have been conceived when COBOL was designed, it would have been.
Admin
Admin
Truly, such long method names are not necessary iff* the path and class are named properly as well. Architecting properly encapsulated features will lead to extremely easy to read, modify, and maintain code bases.
Example: CustomerOperations.Sales.ShippingCalculator() If I am already within the Sales package/namespace, then it is obvious I what the ShippingCalculator refers to. If I am in the MerchandiseOperations.Inventory.Warehouse package/namespace, then a call to such a distant package/namespace should raise a code smell.
* as in if and only if, not merely a typo
Admin
Admin
Anyone else read:
as: the first time they saw it? Because obviously that's much more semantically clear and "documenting" than a negative boolean test: But now I'm just regurgitating the original article.Only two reasons exist to move logic into a separate method/function:
Otherwise all you're doing is wasting your time and, more importantly, the time of any poor soul having to look at your code abortion after you've moved on.
If you're not capable of processing more than one logical operation per line of code, then you should really go back to creating refrigerator art with your crayons.
Admin
I remember when software guys were not good enough for the engineer title and double E's would rant when ever someone used software and engineer in the same sentence. LOL
Admin
Admin
Admin
Admin
So, in your opinion, could the principles of engineering be applied to the construction of software if they were taught and practiced?
Admin
FTFY.
Admin
You got to write your code? LUXURY! LUXURY! Back in MY day we had to chisel our code into stone tablets! Without our bare hands!
Admin
You got to chisel your code? Paradise! Back in MY day, we had to erode our code out of the stone with precisely-placed water - when we had even that! I kilt many a developer to get the necessary blood when water was scarce.
Admin
There are people out there doing precisely that. They're the decent end of our industry, and should be encouraged.
There is discussion in the more professional end of our industry about certification/chartership, and there's a common feeling that it's more "when" than "if".
Admin
It's not an argument in favour of code like in the article - there's a huge difference between that insanity and naming functions/variables to make it clear what's going on while using a minimum of comments.
Yes, when you change what a function does, you have to rename it. Refactoring is normal - that's what you've got your test suite for, to allow you to do it safely.
If you can't rename your function when you change what it does, you've got serious problems with your codebase or processes anyway.
Admin
A bit like Coco !
Admin
Admin
Of course not. One becomes a chief by proving oneself brave and victorious in battle, repeatedly. Also by poisoning one's predecessor's bear claw soup.
Admin
where each of the three functions is, say, about 50 lines long.
Admin
Admin
I am really surprised some of the commenters think that this is not a WTF. However, it explains where the WTFs like this come from.
Admin
It's not a skirt, ye bloody Sasunnach!
Admin
I think of it kind of like plumbing. One one hand you have physicists designing piping in a liquid fuel rocket, on the other someone is gluing PVC pipe fittings together. In traditional engineering there is also a lot of beating on things until they work.
It really depends. In aircraft design, every excess ounce comes out of the payload. So you pay to carry it around. Which means management is motivated to pay to get rid of it. Other fields extra weight is a one time cost that may not justify the NRE to get rid of it.
Admin
That's one problem with comments, but often they still give you an idea of what was going on. Even better is if you check the file history to see the comment & code at the time it was inserted.
However I see a greater issue with this particular alternative. If one of the Self Documenting functions changes, so that the name is no longer accurate, the developer would have to rename the function and all calls to it (sometimes that's easy, but other times it can be a nightmare). Or more likely they'll just leave it with the same name and you'll get a similar issue to obsolete comments, only with it being an obsolete function name (which personally I'd find far more misleading).
Admin
private static bool NoActivityTypesAreAttachedToThisEvent(IEnumerable<ActivityType> activityTypes) { return activityTypes.Any() == false; }
or
private static bool NoActivityTypesAreAttachedToThisEvent(IEnumerable<ActivityType> activityTypes) { return !activityTypes.Any(); }
Admin
Exactly my point - I'm so happy not to be the only one with this experience.
Picking up ten year old code with no change history or source repository means that you benefit from every bit of information you can glean whether code or comment.
Where is my deer stalker hat, Watson?
Admin
When reading existing code, I tend to completely ignore any comments. Mainly because comments are mostly wrong because they have been correct only at the exact moment when they were written (maybe not even then), and they almost never get updated, so much of the time, they are incorrect if not misleading.
I prefer well-named identifiers (at all levels, be they function names, variable names, class names or whatever) at any time. But the identifiers shown in this daily-WTF take the cake. These names are less than helpful.
Admin
The identifier names in this code are a little wordy, but worse things happen in code... much worse!
I would take issue however with the TrueBecause... and FalseBecause... methods, whose names appear to expose their implementation. What if I wanted to subclass, and change the return value from true to false? That would generate a real WTF.
Good program design is about preventing future WTFs, and therefore saving the cost of refactoring them away (refactoring works, but it is expensive).
In review, one might suggest toning down the wordiness a little, but one should not let that distract attention from more substantial isses.
Admin
Seems to me this would be an occasion to take a step back, and ask "why are we breaking this function?" If it no longer does what it says, perhaps the structure of the program has changed enough to warrant refactoring.
It may also be possible to divide the new functionality between 1) a new function with a helpful name and 2) a subfunction called by the now "incorrectly" named function.
Admin
Shouldn't self documenting code be about what it does rather than why?
Knowing what a method does by the method name is a great but the "TrueBecauseThisEventDoesNotRegistrictBasedUponActivityType()" being a a ramble over why you return a true value.
Maybe AddCommentToArticleBecauseItIsMyLunchTimeAndAContributionMayBeHelpful() is the new Article.Comments.Add()?
Admin
Admin
If Marie Antoinette were a programmer, she would say "Let them code COBOL". If one want's to read code as if proper English, then I suggest COBOL which has the concepts of "paragraphs" and sentences"; and COBOL-68 in particular where operators had to be spelled out: "COMPUTE X EQUALS Y MULTIPLY X PLUS A." (Don't forget the period!! There. That will make those morons happy. I understand 'zactly what that calculation is about!!
Admin
Isn't this just how most average programmers write their code? When I look at other people's code, it usually looks about like this to me: abusively camel-cased, with everything wrapped in stupid little functions.
I feel quite certain that this code conforms to the misguided standards of the group tbat produced it.