- 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
If the biggest WTF in your code is #regions, you've got some pretty good code.
Admin
Wait a minute.... a prime is a number that's divisible by itself and one? If it's [evenly] divisible by itself, then it MUST equal itself. So, for any X, where X=X, then x is prime! No need to multiply by one, all numbers are prime.
captcha: causa - Causa I said so.
Admin
Admin
... and ONLY divisible by itself or one ...
Admin
Admin
Hasn't that happened already?
Admin
This must be an optimization to avoid the expensive equals check.
Admin
Were you objecting to my comment or Foo AKA Fooo? Just trying to simplify his math. Are you Canadian? That could explain it. You use "bud" and "bagel" but use the commonwealth "Humour".
Admin
Admin
Helps fold code in some IDE's and ignore bits that aren't interesting in others. Mind you, good consistent indenting (no mixing editors that means somethings are tab indented, some are space indented and some are all over the shop).
having had to work in support in an environment where people frequently move files from the Unix build environment to Windoze just because they loke notepad for editing (ok, I'm jokling a little - I think they use VS for its syntac highlightind (which is perhaps even more laughable), I appreciate any attempt to make code easier to follow - even if it does bloat the source
Admin
Perhaps in future we need references and explanation every time anyone refers to something that not everyone in the world has read.
Apparently not anyone understood the reference to Hitchikers Guide - although I'll admit I've never read it and still picked the reference....but I'm just awesome!
Admin
Reference: The Bible
Admin
Admin
Zing! you win 1 whole internets for today.
Admin
Admin
I really want to understand the full depth of this crime against Java.
Is this a Remy-style snark that somehow escaped into the article, or is this valid syntax? (Perhaps like importing from the future in Python.)Also, is something deliciously bad going to happen to this code once they start using the only secure of java that exists? Correction -- I should say "most secure from the set of versions formally recognized by Oracle".
This seems to mean that ZipCodeInfo is a sub-class of ImmortalZipCode. Can you really subclass something to remove its inherent property of immutability? I would have thought the other way around.Also, and perhaps this is the point of the article's name, is nothing really jumps out about either of these things as being immutable.
Well, it implements these methods, which is perhaps enough to make it possible to create a HashMap, but given the WTF-ery in the equals method, how can this code even be close to working?I guess I'm interested in what bit of accidental tomfoolery causes this code to somehow work as hoped even 60% of the time (i.e. the functional level necessary to obtain approvals to offshore the code and make it Someone Else's Problem).
Admin
Admin
The naming convention would normally be something like:
but perhaps the developer didn't like the double letter at the beginning of the interface name.Admin
Admin
Well, yeah, C++ lets you do all kinds of dumb shit with operator overloading. You can even overload the bit shift operator to send strings to a stream, though I don't know why anybody would think THAT was a good idea.
Admin
Why? Suppose you had ImmutableThing as a subclass of Thing. Thing will have methods like setFoo. The subclass relationship says that ImmutableThing needs to obey the same contract as Thing, e.g. "calling setFoo(new_foo) will update foo." But ImmutableThing can't implement that interface, because then it wouldn't be immutable. So from a strict OO design perspective, ImmutableThing cannot be a subclass of Thing.
Now, some times for one reason or another it's more expedient to ignore this problem and just have ImmutableThing implement setFoo as throw new UnsupportedOperationException(). This isn't necessarily a WTF, but at the same time pretty much any time you see something like UnsupportedOperationException that's an indication that you don't really have a subclass relationship.
Well, what about the other way? Is Thing a subclass of ImmutableThing? Well, yes and no. From a 'local' perspective, it is. ImmutableThing will have accessors like getFoo(). But a (mutable) Thing can implement those functions just fine. So from that perspective, the subclass relationship in this direction is correct! It becomes incorrect if you look across calls, to properties such as "getFoo returns the same object on different calls". That will hold for ImmutableThing (because how would it change?) but not for Thing (because someone could setFoo in the interim). Is that property part of the interface? Depends how you look at it. I'd probably argue "yes" and that the Thing implements ImmutableThing relationship is technically not valid, but I'd also say the other position could be reasonably argued (especially in a language like Java where you don't have some super-ultra-fancy type system).
Admin
IMO, that one benefit makes up for and then far surpasses the drawbacks in terms of compactness of iostreams-style IO vs printf-style IO.
Admin
Think the original coder was trying to give a nod to the hitchhikers guide to the universe with that magic number of 42? Can't explain the *1 part but perhaps the 42 was written 'for the lolz'
Admin
Well, you have some problems with that.
The first is that operator precedence doesn't change. The compiler will still treat the bitshift operator as a bitshift operator, regardless of the abominations that you're forcing it to perform. I need to toss in a quick debug statement to see if "status" is less than zero. No problem:
std::cerr << status < 0;
Oops.
And, since cout << "Hello World" is the first line of C++ a new coder sees, they're encouraged to do stupid operator overloads from day one by the standard library itself. From there it's a matter of time before you see them try and overload the bitwise xor operator to do exponentiation. Then they get introduced to the "friend" keyword to implement that extensible stream feature on their new class.
But hey, we have extensible type-checked IO, so forget these small problems, this is for production use! Except, of course, that iostreams-style IO is impossible to localize, so the entire facility is worthless outside of trivial example code using strings literal. Whoops! Guess somebody has to go back and change all of those calls to sprintf after all, so they can reference the correct language file.
Admin
The cache code is flat wrong.
Most obviously, the ref will never get cleared because there is a hard reference to the zipcode object - it is being used as a key.
To fix this, you use a WeakHashMap. But there's an error there too - there's nothing to stop the ref being cleared between the call to containsKey() and the call to get().
What you have to do is get() the ref, if it is not null then get() the ZipInfo, and if the result of that is not null then return it. Otherwise, re-fetch.
And it's still not threadsafe, if that's a thing. Which it probably is.
Admin
Admin
Admin
Oh, other problem is that weak references are aggressively cleared by the gc. This means that his "cached" values will be discarded as soon as his code has finished with them (unless there's threading going on). He should be holding soft references as the values in his weak hash map.
Admin
Almost; he's only adding the zipcode as a key if it was not found before (by hash/equals). So in fact, he only adds it the first time it's encountered.
In fact he built his own interning system for zipcodes. I've seen it before.
The real issue is he should've used weakhashmap as well, to have weak references to the keys.
And of course the shared instance makes for a lot of threading fun :)
Admin
Use printf for printing non-primitive types, then make a different function call for printing your type, then go back to printf. ('printf(...); print_my_object(o); printf(...);')
Use printf, use a %s operator, and have your class return a string, then convert that string to a C string. ('printf("%s", myobj.to_string().c_str());')
Similar to 2, but have your class maintain a C string representation that it can return directly. ('printf("%s", myobj.c_str());')
Overload a binary function 'f(str, obj)'. This is like the expansion of the overloaded << and >> operators. ('output(output(cout, obj1), obj2);')
The addition of templates added a new option:
The addition of variadic templates added a new option:
My evaluation is that the syntactic obnoxiousness of #1 and #4 are way worse than the precedence issues and verbosity with ostream. #3 is actually decent all around if you can do it, but there are issues including potential race conditions (if the object has to update its string) and the fact that most of the time there's no reason to keep that string representation around. #2 is the most general and only mildly annoying syntactically, but it requires building the entire object's string representation in memory before outputting, which can occasionally be an issue. It also begs the question of how you construct that string in the first place... the best way of which in the standard library (at least pre-C++11, not sure if there's something now) is stringstream! (Though a version of sprintf that returns a std::string would be easily possible to write even in early C++.) Still, I'd take iostreams over #2 most of the time, and would definitely take it if compilers didn't have format-string-mismatch warnings (which I think was probably common at the time, considering that one of the other big benefits touted for iostreams was type safety). Maybe my statement that the << >> operators was 'by far' the best of the mechanisms available in ARM C++ was a bit strong.
It's only where you get to #5, where you can write a print function that you can call like, say, the Python format function -- 'format("{} + {} = {}", a, b, a + b)', including if 'a' and 'b' are of class type -- where you get to something that I think presents a really strong case for being better than iostreams. And even it has the limitation that it has some edge-case restrictions, most obviously the maximum number of output parameters, which must be fixed.
"friend" is not a bad feature, and using it for the stream functions is, IMO, almost 100% fine. Or maybe you don't like it. Then just add a public print(ostream &) function to your class and forward to it. Do you really work in some crazy world where everything needs to be localized? Even if you think that every program should be internationalized from the start because you never know when you'll need it (perhaps a dubious claim, but I'll allow it), IMO there is still plenty of output that has little, no, or negative need to be localized. Log messages meant for the developer don't need to be localized. I/O to and from data files that aren't even meant much for human consumption in the first place definitely don't need to be localized.Admin
Admin
You normally see "I" at the beginning of interface names in Java? I don't recall ever seeing that. Certainly the Java API itself doesn't do that. Do you preface class names with "C"?
Does anyone else find the idea of an interface defining something as immutable to be stupid?
Admin
Admin
That would be a synatx error, so it'd be:
Admin
Actually a prime is a number that's ONLY divisible by itself and 1.
Admin
I always thought something was fundamentally wrong with the universe.