- 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
This is a very interesting case that demonstrates why I think java needs to evolve to have better type inferences. I don't know how exactly that can happen, though. In a more dynamic language (Ruby, Python, Javascript), the programmer doesn't have to write all the type decl since type check is only done during runtime. (And the validity of the type should be checked using unit test cases...) On the other hand, in a language with a stronger type system (Haskell etc.), the programmer still doesn't have to write all the type decl since it's inferred at compile time, I think. I wonder if it can be done only because variables are immutable. Either way, maybe it can't be done without changing the java language fundamentally. sigh...
Admin
Well, all the stuff should be split into a real data structure.Thus using a vector of HashMap is a bit strange...
Admin
You're probably right, though. After I get through sticking a knitting-needle through my frontal lobes, I'll read through the rest of this uninformed lunacy and check up.
Admin
I kinda like java generic declaration syntax
Class BinarySearchTree<E extends java.lang.Comparable<? super E>>
I'm sure you can build even more "interesting" generic classes using ? super and ? extends.
Admin
The only thing missing is a typedef.
Admin
Admin
That said, it's still (1) more code that (2) you have to remember every time you use File that (3) is easy omit.
Admin
Admin
Admin
Admin
All your typedef are belong to C++, too bad for you Java guys!
Admin
This is, indeed, the real wtf.
Admin
Admin
The real WTF is that it should be:
Map<Long, Map<Timestamp, List<Map<String, Object>>>> superHashMap = new HashMap<Long, Map<Timestamp, List<Map<String, Object>>>>();
I think this is really only an anti-pattern if your key is something that doesn't implement or inherit its own proper hash function, in that case every insertion/lookup is a collision, and the chaining or whatever goes into N deferments , and you might as well be in a linked list.
Admin
The real WTF here is the use of Vector, which should obviously be replaced with an ArrayList.
Admin
In this case C#'s "var" keyword comes in very handy.
Admin
Also,
)Works for anything that's IDisposeable.
Admin
Interesting idea. I've always approached it using editor macros to create the appropriate try/catch/finally structure.
However, I think you can get close to it in Java using a bit of setup and anonymous classes.
Step 1, put these in your library:
Step 2, use them as follows:
I'm designing this on-the-fly, so I may have some details wrong. The FileActor and FileAction classes do require a bit of planning and careful coding, but from then on, using them is pretty straightforward and achieves what I think is your goal.
/rob runs off to code a DatabaseTransactionActor and DatabaseTransactionAction ...
Admin
So, pretty much you're arguing that Java doesn't let you do opaque, tricky, unmaintainable stuff? Man, that's, uh, terrible.
Seriously, pretty much none of the stuff you talk about should ever be done in a system that anybody but yourself will ever look at. If you want to "temporarily" change a value, use a named temporary variable. If you want a file closed, close it. If you want to change your cursor after an operation, explicitly call "cursor.Style = Styles::Pointer" or whatever. That way, people know what the hell you were thinking instead of having to grok every line of every class before understanding dawns.
Admin
[quote user="prod"][quote user="Volmarias"]
"PhoneBook" is much easier to understand than "map< string, string>" (which could mean anything!).[/quote] And a PhoneBook class is what I would have.
Admin
-- Now on to your point. You can get all this with PhantomRefrences if you must. But yes, Java does not handle ever case in the cleanest way possible.
Admin
This is not actually a WTF…
It is a little unusual to have so many nested collections, but the generic part is totally fine.
Admin
[quote user="EvanED"][quote user="dkf"]In your hurry to That said, it's still (1) more code that (2) you have to remember every time you use File that (3) is easy omit.[/quote] Still wrong, Files are just pointers to files, you want a Stream.
As to forgetting, well in most cases the finalizer will close for you, you just have no idea when. And any Java developer worth shit would be running findbug. Prob Sol.
Admin
Maybe we should send him a book about Interfaces so he could refactor it to
Map<Long, Map<Timestamp, List<Map<String, Object>>>> superHashMap = new HashMap<Long, HashMap<Timestamp, Vector<HashMap<String, Object>>>>();
Admin
Opaque, no. Java, no. C++, yes (if you're lucky, and you actually have an adult C++ programmer instead of some wacko mutant transplant from the Bio-Chem lab).
There are ways to handle this in Java, no doubt. This just happens to be the way to do it in C++ -- thus, no need for 'finalize,' just as in Java there is no need for 'typedef.'
Honestly, this language nit-picking -- it isn't even a real flame war, for goodness' sake -- is plummeting rapidly down the tubes.
Admin
Like in Ruby?
Pass a block and you can use the file as much as you want in it, when the block ends, the file will be closed.
The fun part here is that the blocks are really fancy. They have the potential to blow your minds (LISP-like langs are more hardcore, I've heard)
This could be useful for file usage, too. Think of the possibilities! ;-P
Admin
Second, editor macros don't help you nearly as much when you're retrofitting code, and depending on how you have it set up, I would guess you still have to remember to use them, and it's still more code that will be sitting around.
But:
there is at least one program that uses this convention for all their resources; I think it's Lucine. This has some nice benefits over try/finally (i.e. better enforcement that people actually follow it), but it's still (1) more code than the C# or C++ technique and (2) you can't refer to non-final local variables in the containing function, which may or may not be a serious limitation. I think you'll find plenty of people who agree with me about the merits of RAII techniques. That works fine with C, but once you add exceptions it becomes way harder, because now you have to ensure that any temporary changes get undone even in the face of exceptions.IMO, if you're coding C++ and see the line
and don't realize that the lock is released when it goes out of scope, you're missing a huge benefit of C++. Automatic destructors are, I think, in the running for biggest single improvement over raw C. As I said, I'm not a Java programmer. You're concentrating on the specifics, not my actual point, which is that there is something you need to clean up. Which makes them far, far less useful. Have a lock on something? You can't rely on the finalizer to release that. You need determinism. The cases like this, where you need a resource to be released at a specific point, I would say are far more common than the cases where you just need them released at *some* point. (Even files can get in this situation if you are opening a ton of files.)(And it's not just when the finalizer runs, but if; if the garbage collector never runs, the finalizer won't be called. Granted, if this happens it's almost certainly because the program exited, in which case just about any resource I can come up with will be automatically released by the OS or won't matter.)
For a few of these problems. Will it tell me that I forgot to change the cursor back to a pointer?Admin
Not a WTF at all in my opinion. Here's a snippet from our code (which I don't consider a WTF either):
Admin
The real WTFs are:
Personally, I would refactor the code so that the Map of Map of List of Map is instead encapsulated into objects in an domain-specific manner.
Admin
You'd be better off doing either:
Admin
As you say, automatic -- and in context I think you mean "deterministic" -- destructors are a great advantage. People outside C++ don't seem to realise that this is pretty much nothing to do with memory management (I had no problems tracking down memory management issues in C, before I worked with C++), but with resource management.
I would, however, humbly take issue with your statement. The biggest single improvement is ... not classes, no no no, and not inheritance and arbitrary levels of protection borrowed, no doubt, from some unholy marriage of Simula and Smalltalk, but ... Templates.
Luckily, this brings us back to the OP. Stroustrup took a long time to get around to templates in C++, and the syntax is a godawful mess, and he's since apologised. But they work. Extremely well.
Java's "generics" are an excellent idea, but they're still only syntactic sugar. (Much like 'typedef', in fact. ahem)
At the end of the day, what you get with Java generics is an Object. What you get with C++ templates is an extremely rich (albeit statically typed) field of design choices and code re-use.
That is all ye know, and all ye need to know.
Admin
The real WTF here is the fact that he declared the variable using the concrete classes, plus he is using Vector. Seriously, who uses Vector? It is not 1995 anymore.
Map<Long, ap<Timestamp, List<Map<String, Object>>>> superHashMap = new HashMap<Long, HashMap<Timestamp, ArrayList<HashMap<String, Object>>>>();
See? I made it all better.
Admin
Admin
wish he would have thought about the Blue Pill too...
Admin
What's wrong is that after two lines of generics, it's still storing "Object"!
Admin
Admin
Still wrong, y'know... ArrayList is an implementation, like Vector. The generic Interface for both (!) is List - everything else used in declarations should in fact be treated as a (design) error.
In declarations all types (i.e. interfaces!) you ever need (and should use) are List, Map/SortedMap, Set/SortedSet, Queue and Collection. Period.
Admin
At least one who gets the concept of generic interfaces :o)
Vector does not have to be deprecated though, as long as it is treated as a List. It is still better to use Collections.synchronizedList(List l) to get a List which is synchronized per-method, but there is nothing wrong in using a Vector in such a case.
The real error is - as you stated - using Vector (and any other implementation class, at that!) in declarations instead of the generic interfaces.
Admin
As this is Java and Map is an interface, it'd be more along the lines of
but otherwise, 100% d'accord.
Admin
ad (1): "More code" is never really a reason to abandon a concept when this is the only "issue", especially with modern IDEs.
ad (2): There is a very good reason for this limitation in Java: Such so-called "(anonymous) local classes" have a very limited scope (i.e. the block of code where there are declared) and can also only see local variables in the same scope. The lifetime of their instances, OTOH, is potentially much longer (the references can be passed out of the enclosing code block, compare the Listener-concept in Swing), so the values of the local variables might not exist any more (on the stack) when such an instance is used. Therefore the compiler stores the value inside a synthetic field in the inner ("local") class.
As we - the developers - do not see, where the value is copied (it is passed in transparently when the constructor is called BTW) this can only be done unambiguously when the local variable does not change it's value somewhere in said enclosing block, especially after the local class was instantiated.
Thus it simply has to be final.
And this is moreover never a limitation: Method parameters can safely be declared final (and should not be "re-used" inside the method body by assigning different values anyway, so one could always declare them final!).
Most other local variables that change their values are not used inside a local class - and those local variables that have to change their value and be used in a local class (think e.g. loop variables...) can always be copied to a scoped final variable if necessary, e.g.:
Admin
I like the ignorance of not creating container classes. Even if it might make sense. Sometimes I happen to see code like this on my own. But that is usually an alert for me that some data is screaming to be wrapped in a nice and gentle class. The generics are definitely not the problem. Consider how the code would have worked without it..
Admin
Best Comment Ever!!! First thing that made me laugh on this site for a bout 6 months. Alex, feature it! Notwithstanding the comments to MFD, that thing was worth it just to see the creativity of those who parodied it.
CAPTCHA: secundum, wtf is a secundum?
Admin
Multiple inhertitance can be misused much more than the single inheritance/interface concept can (which is not to say that you cannot build crappy data models with that).
Operator overloading is mainly syntactic sugar and does not add to readability - you never know what a given operator behaves like by just looking at it being used - you have to look at it's implementation too.
And scope controlled deterministic destruction? Implicit memory management in Java is of course also deterministic - objects going out of scope and not being held on to are destroyed. The fact that many people still manage to create memory leaks in the presence of a GC most of the time can be blamed to a fundamental misunderstanding of OO concepts and bad design.
The common base class for everything is not in your way if you do not use it (many people do not even know that they derive from Object in Java implicitely when leaving out the "extends"-clause!) - otherwise it is one of the single most important concepts in any OO language: generic data structures and algorithms depend on it heavily (especially in the absence of templates) and with the addition of compile-time safety (the so-called "generics" in Java) this is a good and clean concept. The concrete implementation in Java has its flaws, e.g. the protected clone()-method with the empty Cloneable-interface, a clean mixin-interface would have been much better here. That is to say, you have to really know a language to criticize (not flame!) it.
Admin
Ah yes. Someone might sometimes think they needed it (but nothing you could not solve with a new class), it is evil most of the time when lowering readability, there are no legitimate uses that cannot be solved with single inheritance/interface (and additionally an association if you really want to share implementation), it is pointless for large distributed systems, point taken for const, a GC is scope controlled, a common base class is a good thing for generic algorithms and data structures and who is treating programmers like idiots?
You are missing the point here - Java is designed for large distributed systems where you do not care for some CPU cycles on a single machine or an explicitely allocated block of memory where you can perform some nifty pointer tricks.
If you want to program a 3D game, Java is perhaps not the right choice, you are welcome to use C(++) or whatever at any time.
For large systems with large teams (with a lot of people who are not on the kernel hacking level) we should be glad that all that stuff was left out, it makes life a lot easier.
Admin
Can someone explain to me why you would EVER stack hash maps?
Admin
Which is by far a bigger WTF for me. Having a separate linker? What on earth is the point, in this day and age?
I'm looking forward to C++08. None of the ideas are obviously insane, and I'll put up with yet more horrid syntax to be able to use lambda functions instead of my current lovingly hand-tooled functors. The "constraints" thing (or whatever it's called) on templates also looks like a useful design tool.
I suspect the proof of the pudding is when we look at Java 1.8 and discover how many parts of C++08 it "borrows."
Admin
Admin
Admin
I'd be interested to hear your arguments as to why Java is a "comparatively clean language." It's a fine language, but it is by no means comparatively clean. Unless, of course, you refer to the syntax -- which is largely irrelevant to anything other than a compiler.
Agreed. Stroustrup is wrong on this. I prefer Java's inheritance/interface mechanism by far. And if you want to do multiple dispatch ... well, then, multiple inheritance is not a hell of a lot of use. An interesting and common objection to operator overloading. But, I think, misguided.Operator overloading is clearly not needed in functional languages. In C-derived languages, though, it can be used as a useful design tool. Yes, it's syntactic sugar (and I personally do not like std::string operator+(...) used as 'concatenate'), but it can make things clear through design. As the Greeks say, μηδὲν ἄγαν. (The other classic Greek aphorism, γνῶθι σεαυτόν, is also relevant here.)
The point is, why deny this syntactic sugar in a language? Why not just castrate the silly bastards who misuse it willy-nilly?
"Of course?" I suspect not. You're talking about an inequality here, not an equality.This would be the same definition of "deterministic" that allows some loonies (not you, obviously -- they're normally recruiters) to claim that "Visual Basic can produce a Real Time system."
Well, no, it can't.
Well, no, Java memory management is not "deterministic."
Leaving aside the minor point that Resource Management Is Not Simply Memory Management, it is simply not true to suggest that the Java (or any other) GC will "deterministically" delete free resources. Of course it won't. In a large-scale system, this is potentially a problem. In a large-scale system under stress, this is almost certainly a problem.
Whilst in no way wishing to suggest that Java is a useless and pointless language that should never have been invented, or should have been strangled at birth before its reinvention from Oak or Green or whatever it was at Sun into "the Language of the Web" (which it subsequently failed to become), I would humbly suggest that other languages do it better, and often without the huge backwash of 'plz send me teh codez' morons.
Python, Ruby, or some idealised version of Lisp/Scheme spring to mind. Or, going backwards and actually hiring "gurus" (ie sentient human beings, such as you and possibly me) to do your programming for you, C++.
Java is a very weak half-way house, with a ridiculous and unsustainable amount of superstructure above it.
I should point out that my current peeve is Python's GIL ... but that's neither here nor there.
Admin