As Languages Evolve...
naph writes "It seems that as programming languages have developed there has been a steady increase in the level of abstraction they use. Early languages were all very low-level, but successive generations have become higher and higher. Is this trend going to continue, or do you think we've reached a kind of happy medium between power and abstraction? Would developers prefer higher level languages, or is the direct control of things good? I was just wondering what other developers out there thought of this."
One thing that has happened in PL design is that they constrain the programmer more. This tends to increase the expressiveness, unlike what one qould expect at first.
The dangers of excessive individualism are nothing compared to the oppressiveness of excessive collectivism
As long as the compiler is efficient and very good at optimizing, more abstraction is OK. But if abstraction comes at the price of too much speed (Or executable bulk), then the compiler should not exist.
Even though i am just starting programming, I would prefer a language that is more abstract. I think it allows for faster programming. Just tell me if I am wrong.
"What we have here is a failure to communicate"
The Warden, Cool Hand Luke
I like being able to mess with the hardware like I can in C/C++. Don't get me wrong, you need abstractions, but I think that C/C++ have it just about right. I can program without learning anything about hardware, or I can cast null pointers and crash it.
Comment forecast: Bits of genius surrounded by a sea of mediocrity.
The entire point of computers is to do things much faster than we can do them manually (or even make things possible that weren't before).
By making programming easier and faster with higher-level languages, this contributes to that goal.
There IS a trade-off in speed by doing things at such a high level versus, say, machine language, but considering the scope of most apps these days, it wouldn't be economically viable to create everything that way. Optimising certain bottle necks in low level languages is probably about the only common use programmers will have for low level stuff in the future, except for certain special cases or very small applications.
If you have a project that needs super-duper optimization, it might be better to concentrate on improving the compiler's optimization rather than writing your app in a low-level language. Keep in mind you have to maintain your code!
It's not as much about high/low level as about code reusability. Nowadays it's almost impossible to start anything completely from scratch, so languages offering better code reusability win. And high level languages generally offer much better code reusability (combined with good separation -- I can use other's people code together with my code easily).
... Thus older languages have a great advantage of the amount of existing code -- look at Fortran, it's ugly as hell, but people still code in it ;-)
This doesn't necessarilly mean high level languages will win, at least not fast. There have to be enough code to reuse -- libraries, modules, or how it's called in the particular language
Life is the slowest way to death.
It seems to me that any language, be it Java, C++ or plain old C will become more abstract on their own as people begin to use libraries and reuse classes and methods. Once someone writes some basic classes, he will write classes which use those, and so on until the classes which he writes are many steps above the original class in abstraction.
I don't really think that its a trade off between power and abstraction. It's more a case of expressiveness vs efficency. All languages have the same power - as long they're universal and not some subset of a universal language.
Expressiveness is slightly different though, as you move up through the levels of languages; from machine code up to imperative languages like C++ and then up to functional or logic languages like Haskell or Prolog - you lose control over telling the machine how to do something and focus more on what it should do.
Potentially this gives the compiler more scope for optimisation and leaves the programmer able to reason about more complex systems. Yes you could write something like, say a datamining or visualisation app in assembly language. But how much more effort would it be than doing the same in Haskell?
These nicer abstractions actually make it easier and quicker to write more complex code (theres a hell of a lot less of it for a start). I would think that theres still a level higher that we could go that would give a useful impact in productivity. The holy grail of language research is an abstract specification of what a program should do, from which an actual program can be generated automatically. This would allow complex systems to be verified more easily (and correctly) which are the kind of qualities that you need to move software from a scientfic (artistic?) discipline into a mature school of engineering.
Hopefully that would lead to more realiable systems but comes back to my original point about efficiency. In the longterm it may be more efficient rather than less to use these levels of abstraction as the large complexity of the types of systems that we will be designing will stop anyone from 'coding them by hand'.
Slashdot: where don knuth is an idiot because he cant grasp the awesome power of php
When it comes to languages, the answer is use the right tool for the job. Low level languages will always coexist with high level ones.
As I recall from my software engineering class, programmers program at the same rate in lines of code regardless of the language (I believe IBM did the study in the 80's, but dont quote me on that). Therefore, programming languages SHOULD be more abstract to increase productivity. It also comes down to the "reinventing the wheel" factor. The more bug-free features/libraries we can stuff into a language, the more we can produce bug free code quicker. The only problem is of course that abstraction comes at the cost of speed. How much more enjoyable is it to program in java and not have to worry about cleaning up memory than say C or even assembly where everything is a battle. I dont know about you, but I would much rather type create_new_window() than worry about framebuffers and things of that nature. Hopefully this can be accomplished while keeping speed up and code bloat down
cpu ------> abstraction ------> problem
As a result, the more abstract language is often less efficient for the computer to execute, but allows the programmer to describe the problem to the computer faster. That is, it makes him more productive, in the sense of...
productivity = features developed / times spent
Now,
As a result, the "sweet spot" in the tradeoff between programmer time and cpu cycles now is with more abstract languages than it was 10 years ago.
This is also why in the past the abstraction level of "mainstream" languages has steadily increased (machine language -> assembler -> macro assembler -> COBOL/FORTRAN -> modular/structured languages -> object-oriented languages).
This is also why I firmly believe the abstraction level will keep going up, through stuff like:
I also expect more new languages to have dynamic instead of static typing, which is also a way to attain higher programmer productivity (especially for refactoring) at the cost of compiler/runtime efficiency.
One more note: Before you argue against higher abstraction, please check if your line of reasoning could have been used as an argument for assembler and against higher-level languages. If so, maybe something is wrong with it...
Stupidity is mis-underestimated.
Abstractness in PL's is always the simplification of powerful extant patterns of current programming, for example, Object-Oriented programming was already highly in use in systems such as windowing environments long before languages like Java and C++ incorporated it into their grammar. Polymorphism, templates, etc. also follow this paradigm.
So as long as there are powerful programming systems in use that are not already part of a language, PL's are bound to become more and more abstract. Of course the abstractions of these systems will tend to bloat programs and may inhibit low-level control; so, PL's capable of low-level optimization (akin to C) will always remain when performance is a requisite.
In keeping with the history of PL's, we will see the evolving languages charging ahead while their compilers try to keep pace: leaving their lower-level predecessors behind to tend to more obscure and specialized tasks.
It's all going according to
I think the hard tie to a single langauge for a project is slowly going away. I think you are going to see more and more projects done in 3+ langauges. You built your first revision in a scripting langauge (python), and have it calling your database (PL-SQL), then once most everything is working you will go in and check how it preforms. You profile the slow bits and port them over to a quicker langauge (C++) using a tool to help you tie it all together (SWIG).
I could have written this little made up example using (perl), (xslt+xml), (C), (h2xs) or one of a dozen other combos.
The power of using a scripting langauge as a major component of your project is you get rapid prototyping, and easy extendability. The advantage of using a lower level langauge is speed and "access" to APIs of hardware you might need. Why anyone would feel the need to limit themselves to one group is beyond me.
The progressive abstraction of computer languages slow to a creep a long time ago. OO has been around very a very long time, just not neccesarily in the form of C++. Essentially the CS world has settled on some mutual understanding the the range of abstraction around C++, Java, and Perl is a pretty good place to be depending on how OO and whatnot you want to be (and of course we will always have the ever-enduring C for simpler and systems programming), and we can't seem to come up with anything better that's got more useful abstraction than that.
There's been a dream of a useful and successful 4GL for many many years now, and from time to time someone claims they've done it, but it's a shoddy system that isn't flexible enough and too proprietary (comes with it's own crappy OS just for that programming language, etc). 4GL (4th generation language) is supposed to supremely abstract away the need for code altogether, or at least try to. In my idea of a proper 4GL, programming would consist of composing one well-structered XML document describing the objects your problem domain deals with, what they can do, and your business rules for dealing with them. It should be something a non-technical person who understands the business can write with a little help for a helper gui. From there 3GL (C++, Java) source code, GUI elements in whatever, middleware servers, database design and sql code, should all spring forth on it's own. But like I said, so far 4GL has been a pipe dream, we seemed to have reached a point where it's going to be very difficult to get much further without figuring out true-AI first, which is some ways off.
11*43+456^2
Programming languages are just going through the normal stage of evolution. Early oral cultures had little to no abstraction because the 'language' didn't support it. Then the invention of writing offered a quantum leap in understanding, letting people realize that both an oak and pine were 'trees' (a previously meaningless word).
Programming languages, while not following exactly the same paradigm, are definitely following the same thread. The more advanced they become, the more advanced people who use them become... allowing things to be done in multiple ways and bringing in a new wave of thinking about programming.
Computers double in complexity every 18 months. Programmer productivity doesn't. The only way to get programmer productivity to keep pace is by augmenting programmer intelligence with computer intelligence.
...and of course there's the often overlooked facet of this which is that often times, for a given load and/or userbase, the higher level abstraction is more than fast enough to do the job.
If your current implementation can potentially handle ten times your current requirements, there's no need to rush into the lower levels.
- I don't need to go outside, my CRT tan'll do me just fine.
And as long as your IT guys aren't coding too many O(n^2) algorithms...
Using more efficient algorithms will always be a better usage of coding time than choice of language.
- I don't need to go outside, my CRT tan'll do me just fine.
Only small and simple processing platforms are good candidates for an all-Assembly solution nowadays.
Show me someone who can effectively handle all of the ins and outs of modern Athlons, P4s, Xeons, and G4s, and I'll show you someone who's smart enough to spend their talents on writing compilers instead of individual applications.
I'm sorry, but normal humans cannot beat optimizing compilers on modern processors. Coding to the metal on the high end isn't a viable option anymore.
- I don't need to go outside, my CRT tan'll do me just fine.
If you're a customer and you're stuck with a particular tool chain for a given device, then you're stuck with whatever your vendor provides for optimization. For many embedded devices, there are only one or two compilers available.
Thus, your suggestion to improve the compiler isn't all that useful. The vendor needs to do that. Meanwhile, the customer either attempts compiler black-magic (eg. tweaking their C code in obscure ways to try to help the compiler) or reduces their code to assembly.
For the vendor, to accurately measure the performance of the tools relative to what can be achieved with a given device, it is extremely useful to have hand-optimized benchmarks that represent "optimal" and measure versus them. (This is especially true for 'heavy compute' functions.) That is an activity I actually get to participate in -- I get to write some of the highly optimized assembly code that we benchmark our compiler against. I get to do that, though, because I work for the vendor. Our customers are stuck optimizing their code with no chance to improve the optimizer.
--JoeProgram Intellivision!
I agree with you that it's possible to speed up programs written in higher-level languages immensely by finding the bottlenecks and rewriting them in a lower level language, (profiling your code, the old fashioned way) but I find much of the rest of your bashing to be quite excessive.
:)
:)
I find that in higher-level languages, I spend less time debugging my code and more time debugging the system libraries and the language. In any complicated and changing system, there will be bugs, and there's far more code behind your average higher-level programming language, especially when it's new, not extensively tested, and not well-understood. i.e., your average C compiler will behave much more predictably than your average Java compiler, and if you screw something up in Assembler, rest assured, it's probably your fault.
How are iostreams more portable than stdio.h? Do you mean portable in that it hides more implementation details, or portable in that it runs on more platforms? I'll agree with you on the former, although that isn't always a good thing, but never on the latter.
As for C's #ifdef facility, I like it a lot. In fact, I sincerely wish Java had some form of macro preprocessing, because occasionally, I need it. I'm sick of Java programmers whining about how "macros are confusing"--if they lack the intelligence to run the source through the preprocessor in the first place, then... it might explain a lot about their Java coding.
But this goes right back to using the right tool for the job, and not reinventing the wheel--if I needed to implement some sort of portable, network-aware program in C, I'd probably look for some sort of portable, network-aware LIBRARY that's already ported to the intended platforms.
There's nothing wrong with quickly testing out an implementation in a higher-level language, but depending on what you're doing, you still might want to re-code all or parts of it in C. And all languages have their warts, especially depending on what you're used to doing or having. I wish C compilers had a standard facility for hashes and did proper tail-recursion optimizations--but then I also wish Java wasn't so crippled, bloated, and slow (to say nothing about typecasting, scope problems, enforcing its own naming conventions, etc., etc.), OOP in C++ wasn't so whacky, and I wouldn't mind if Perl's type system were a bit cleaner, or if PHP implementations could be more consistent between versions, etc., etc., etc.
So, yes, use the right tool for the job. But don't kid yourself--you'll be banging your head against that higher-level language a lot anyhow, and likely for different reasons, sometimes completely unrelated to your program. After doing that for a while, I'd much rather know I'm shooting my own foot in C or Assembler instead of having my shot foot anonymously instantiated by some cryptic and unnecessary higher-level language 'feature'.
pb Reply or e-mail; don't vaguely moderate.
Even now, with highly abstract languages, we still have computer languages that only trained users can understand. In my company, we are always trying to make applications where the business logic can be changed by business users, so that, say, the finance guy can log into the system and change the process for paying bills. This is because as highly regulated/complex industries move more processes to computers, they need business-person control over their systems. It's very easy for a bank to have a business analyst change an online form because a regulation changed; it's harder to call up the program vendor and rewrite the program. The problem is that there needs to be an easy-to-use language for describing the new form. Currently many such languages are business domain only; expect them to grow and become more powerful; soon a business person will be able to put together an entire web application from "scratch" with a good framework.
there has been a steady increase in the level of abstraction they use
So, C is more abstract than LISP? And C# is more abstract than Haskell? Or is this "steady increase" just an artifact of how you choose your examples?
Imagine you are hosting a party. The first person to show up will either be taller than you, or shorter. And (if the people are showing up in a random order) there is a non-zero chance that the next person to show up will either be shorter than both of you, or taller than both of you. As new guests continue to arive, we should expect the height of the tallest person present to go up, and the height of the shortest person present to go down.
I would argue that the same thing is happening with programming languages. We are not just seeing higher and higher level languages, we are also seeing lower and lower level languages (e.g. so-called programable hardware, PLAs, etc.) at the low end. More than anything, we are seeing a steady increase in the number of FORTRANistic languages that dwell somewhere between BASIC and C.
But no grand trend in any particular direction.
-- MarkusQ
Abstract languages have been around for a long time. Kernighan calls them little languages, and he has described them several times in his books. The examples of abstract languages appears endless: snobol, awk, troff, tbl, pic, eqn, ampl, . . .. When it comes to problems in their domain, I would always rather use a little language.
A single language designed from the start to do things at a high level by default, but that let's you drill down to C-level where needed -- but not to actual C -- to a replacement for C. Something intended to be compiled down to highly optimized machine code, not to a higher-level bytecode. Something cleanly designed from the start to span the range of high-level to low, rather than evolved to be that way, like C++. Something that you really *can* develop device drivers and operating systems and embedded apps as well as big GUI client apps with.
.Net, but those platforms aren't suitable for low-level coding.
C was quite elegant for its time, but it is no longer even close to the best we could do at that level of abstraction.
And C++ was built by taking one good idea at a time and finding a way to shoehorn it into an existing framework that never anticipated the new stuff, resulting in the monstrosity of a design we have today, with more exceptions and gotchas than the US Federal Tax Code.
For example, the utter confusion of arrays of bytes and strings of text characters is a fundamental flaw (today).
C++ can't correct the flaw and remain a superset of C, so it just added a single-byte string class and then a wide char string class, which gives us byte arrays and char* and const char* and string and wstring, all with different APIs and rules and gotchas and no consistent conversion between any given pair...all in the same language.
But wait! there's more. Since C's approach to strings (modern text data) is so poor, and C++ did something about it so late, every OS, class library, home-grown "portability layer", etc. in the world also invented its own string class, string APIs, etc. Something so utterly fundamental to almost every program is an utter mass of confusion in C/C++.
Compare that to the purity of strings in Java or C#. Yet, unfortunately, you can't compile either of those down to the sort of nugget of machine code you can compile C++ into.
Or consider something as fundamental as numerical types. How many bugs are caused by C's (and therefore C++'s) use of different definitions of char, int, wchar_t, etc., on every platform? I know why it was done, but I think fixed data types is the right choice for a general purpose language for today. Again, you can do this in Java, and have an even better selection of types in
Something like ECMA-334 (that's ECMA and soon to be ISO C#), which the spec allows to be compiled straight to machine code, could get pretty close to this. A small runtime to provide GC (even C and C++ have runtimes these days) could still be used, but could be overridden to do full byte-by-byte manual memory handling where needed. Bounds-checked arrays by default that let you turn off the bounds checking where you're sure you ought to, etc.
If ISO C# can't be modified to allow this, then it could be forked into a language that could. You would have the high-level constructs combined with low-level byte manipulation of memory, files, and streams, capable of being compiled down to roughly what you would get if you wrote in C, but much more reliable and easy to maintain.
A language that was designed from the start to span a range from high-level to low-level with a single string type, fixed numeric types, byte array manipulation primitives, regular expressions, gc that could be overridden, a syntax that is already widely known (C#/Java-ish)etc., would be a great replacement for C & C++.
"Those who have never entered upon scientific pursuits know not a tithe of the poetry by which they are surrounded."
Early languages were all very low-level, but successive generations have become higher and higher.
The first language was FORTRAN. The second was LISP. Your premise is fundementally flawed -- languages have not been getting higher and higher level. And before I get any spelling flames, I should point out that back in 1959, the names of both languages were still capitalized like that.
What has been happening is that generic support for useful abstractions has been slowly creeping into our languages. It seems that about once every 10 or 15 years the limitations of the current languages to express those abstractions becomes severe enough that people are willing to make a jump to the next generation of languages.
During the 70's and early 80's, ALGOL-like languages, like Pascal, C, and FORTRAN 77 predominated. From the mid 80's through the late 90's, C++ apparently reigned supreme. Now, in the late 90's and early part of the 00's, we're seeing Java and C# move into the forefront of the developer's mind.
I am loath to call any of those languages high level. C++ added generic support for several OO ideas. Java and C# have added garbage collection and much better support for runtime linking.
But in the end, all of these languages are still fairly low level. The biggest thing that has changed is the overwhelming size of the languages standard libraries, and each Operating System's runtime libraries. We've learned a lot about what programmers need to do in the last 50 years, and we've encapsulated a lot of that knowledge into standard, reusable libraries. In return, those libraries have grown huge.
Think about the size of the libraries available to us -- the KDE libraries, the Win32 runtime library, the suite of standard ActiveX controls available on Windows, the huge Java standard library, CPAN, or the new DOT.NET framework. These are where the advances have been made in the last 50 years, but with a price.
In the 70's, one programmer working a few months could have implemented an entire robust optomized copy of the C library himself, down to the syscall level. A good programmer could intimately understand the entire library in a matter of weeks. Today, it would take dozens of programmers working years to implement the Java or DOT.NET libraries. There is probably no-one who can honestly claim an intimate understanding of any of them. We've reached a point where the standard library is bigger than any one person can understand. At that is probably the biggest thing that is going to impede the development of more complex, useful libraries in the near future...
Slashdot is jumping the shark. I'm just driving the boat.
Think of the consequences--someone might write an arbitrary precision number library that allows for code that looks like "2 * 3 + 4 / 5" -- no, that must never be, it would be too useful and obvious!
This explains so much--thank you. I have often wondered why Java programmers can't seem to indent their code properly. I've even had trouble finding a good program to (re-)indent Java code. The main reason why I'd like to see programmers stick to 80 columns (or 120 even? please??) is because sometimes I might want to PRINT SOMETHING OUT.
However I realize that when you have code that looks likeit might be difficult to indent without introducing awkward spaces or unnecessary temporary variables, and you wouldn't want to disrupt the straightforward purity of the Java code itself! Actually, if you write all of your classes correctly, and your iterator functions and whatnot, maybe you can get your main program to one big long line that does everything you need. Say, 10,000 characters long.
But while we're enforcing semantics on the programmers, let's enforce specific editors or IDEs too! Do you have any suggestions, or an approved list of allowable console text editors? Does the editor have to be written in Java?
pb Reply or e-mail; don't vaguely moderate.
OK, wild speculation follows...
I think we're going to see languages move in two directions: higher and wider.
The "higher" languages will be designed for bigger abstractions. A lot of these will compile down to today's high- and medium-level languages. Most will be domain-specific. We've always had examples of this (e.g. parser compilers such as yacc, ASN.1 compilers and so on; there are plenty of these for high-level languages like Haskell, such as happy and Strafunski too), but I think we'll see more as we go on.
The "wider" languages will be designed to support higher-level abstractions directly by providing the basic building blocks to the library writer. We see this in C++ template libraries, Haskell combinator libraries, Lisp macro libraries and so on. They will not be as good as "high" languages in their specific domains, but they will be generic enough for "normal" applications, plus they will have the benefit of not requiring a whole other compi.
sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
One of the benefits of C++ is that you can drill down from a level of objects sending messages to each other to void* shuffling bytes and operators that twiddle bits when necessary.
C++ is a great idea, but it's a monstrosity of an implementation for historical reasons.
Working in layers is the only sensible way to go, but I don't think you need to call out of one language and into another to do so.
Both C++ and Lisp are models of building in layers within the same language.
"Those who have never entered upon scientific pursuits know not a tithe of the poetry by which they are surrounded."
I remember the good old days when I coded small games for my Atari. It had a 68k CPU with 1MB of RAM (yes, I bought the top notch, I even had it upgraded to 4MB later on). :P )
I coded in asm and C, in order to save RAM I had to use several sprites and compose them into one character (for example, a gnome and an elf are holding a torch, a sword or a bag, simply put the hands of the characters in a fixed locations, use one torch, one sword and one bag to overlay on the character sprite and save loads of memory, i.e. a few kBs at most
A proper use of structs even provided a primitive OO interface (I had a C++ book, but no compiler)...
Early languages were all very low-level, but
:directory '(:absolute "etc" "monkey")
:name "settings"
:type "conf"))
:if-does-not-exist :create
:if-exists :rename
:direction :output)
// is static initialization order even guaranteed?
// get the old one out of the way
// file descriptors aren't garbage collected
// now put back the old file
successive generations have become higher and
higher.
I don't buy this. Explain why Common Lisp lets
me do this, for example:
(defparameter *settings-file-location*
(make-pathname
(defun save-settings ()
(with-open-file (settings-file *settings-file-location*
(prin1 *settings*))
Java, 18 years later, requires code like the
following to approach the functionality of the
previous snippet:
/* We have to shove EVERYTHING into a class.
A singly-inherited one, no less. */
class Settings {
static File settingsFile = new File("etc" + File.separator +
"monkey" + File.separator +
"settings.conf");
static File settingsFileBackup = new File(settingsFile.getName() +
".bak");
public void saveSettings() {
boolean backedUpSettings = false;
if (settingsFile.exists()) {
settingsFile.renameTo(settingsFileBackup);
backedUpSettings = true;
}
FileOutputStream fow;
BufferedOutputStream bow;
try {
fow = new FileOutputStream(settingsFile);
bow = new BufferedOutputStream(fow);
dumpSettings(bow);
close(bow);
} catch (Exception e) {
if (bow && fow.getFD().valid()) {
close(bow);
}
if (backedUpSettings) {
settingsFileBackup.renameTo(settingsFile);
}
}
}
}
Note that this Java code loses on systems like
Mac OS, which store the file type somewhere
besides the filename.
Or how about Common Lisp's condition system,
which allows execution to actually continue
where it left off once an error is corrected?
What about MAPCAR, or DO and DO*? Heck, what
about first-class function objects?
Of course, try getting a job using Common Lisp,
or any other decently abstracted general-purpose
programming language today...
BTW, Slashdot inserted the spurious semicolons
in this post, not me.
TO BUY A NEW CAR WOULD MAKE YOU SEXUALLY ATTRACTIVE.
I believe that the next generateion of languages will contain the following new(ish) abstratrions.
Data encapsulation:
All data on the system is encapsulated with some Meta-data describing it's type, origin, rights, source,destination etc.....
This will give a huge increase in security, and allow for radicly different programming models.
Profiling JIT compilers:
JIT compilers that profile your code, and use the profile data to occasionally peform a
re-optimized compile.
MPP:
Applications will be written to take advantage on MPP, as chip manufactures start adding things like hyperthreading to there CPU's and it becomes more efficient to build a PC with 8CPU's than with one fast one, coding practices will change to allow applicaitons to run more effiently in MPP environments.
thank God the internet isn't a human right.
Re: evolved vs. not.
You give code snippets. You talk about high level concepts. You show the world why you are right and risk cross examination of your claims through submitting your example to public review. You have dreams, aspirations, a job, desires. You largely function properly, you, and as you suggest, LISP, are thoroughly evolved. But your antithesis lurks here. People like Tevis Money, the retard. People like him are Slashbots. You don't get replies because the morons are silenced. People like him are fat, have no sex life or aspirations thereof, they masturbate to Sarah Michelle Gellar, or they Masturbate to Gay Porn. They do this day in and day out in a subsidized existence. They use their computer to propagate their mediocrity; they levy their sucktitude upon us. They lash out, like automatons and robots, vanguards of sucktitude.
You are too good for this place, man. All the intelligent people are gone for the most part. You comment lies dangling in the wind. People like Tevis are busy sniffing their armpits, masturbating and pretending to be techies and elite hackers.
This being said. I agree. Java is clearly not a progressive language in this regard. It is a horrible mix of being powerful and high maintaince like C, but it kludges in object oriented and garbage collection inferiorly. Death to Java in its current state - It sucks.
I tend to find the current movements too "code-centric". I find that one can factor (move) much of the complexity of an application into a relational database.
You can get virtual and ad-hoc views of your "noun model" without physically shuffling around code and code structures. Code is too physical, rigid, and one-dimensional for my tastes.
Note that I honed most of my database techniques on "nimble" desktop database systems of the 80's. The "big iron" DB's like Oracle can learn something from them to make their systems (optionally) more nimble IMO. Their formality has scared off a lot of people into the code-centric realm. I am not saying go back to those 80's systems, but simply look at what they did well and carry the lessons over to the big-iron DB's.
Table-ized A.I.