Some people seem to have a disposition to modeling problems with objects, but I fear I'm too young to have ever met any Java zealots. To me they seem more like straw men invented to help set up posts like this one.
Later in life, listening to the Berkeley SICP lectures made me realize what a joke the whole thing was.
I don't think Java OO zealots are a straw man. I think they're very common, and many of us are living in a happy Hacker News and startup bubble, where people we meet are surprisingly competent.
Example: U of Washington CSE 142 (the entry level course for one of America's better programs) starts with Java and continues that through 143.
As you said a lot of universities use Java or C straight away.
At anyrate, I don't see how this assertion is even useful, even if it was true.
MIT - Introduction Course - when it wasn't python.
Can you give any examples, of where it was an advanced course?
I thought that way then, too. I remember complaining with my friends to teacher that he teaches us algorithms and data structures in procedural Turbo Pascal, when everybody knows it's obsolete, and we should be doing everything in C++ or Java. Yeah, I was clueless, and that particular prof. was right.
But most teachers were OO fundamentalists, and it was assumed everything should be OO. One stupid exercise - design system to keep data about students and teachers on university, using OO.
And the answer was obviously - Student and Teacher class extending Person class. No matter that sometimes people are studying on 2 facoulties, sometimes Student is also a Teacher, or becomes Teacher after he graduates. And when we could use relational DB, it was always with ORM, because objects are needed in any modern system.
"No matter that sometimes people are studying on 2 facoulties" -- Why doesn't this work? Just use a collection, several students inside a collection object...
"And when we could use relational DB, it was always with ORM, because objects are needed in any modern system." - Because you manually want to populate objects with tons of boilerplate?
Just sounds like results of bad design in general, not OO...
Historically, OO's acceptance of composition over inheritance only came after a decade of experience that showed inheritance doesn't work as promised. (Or two decades, depending on your accounting.) Composition as an answer came later.
"Just use a collection, several students inside a collection object..."
So, embed an ad-hoc, informally-specified, bug-ridden, slow implementation of half of a relational database in OO and its problems go away?
I've found some places where OO works (the traditional UI widgets still tend to work pretty well), but it isn't even close to a panacea and if you compare the initial promises to what it can actually deliver, history has not treated it that well.
And that's where OO initially gained traction. At the time, UI was a major pain. OO was a good fit. UI elements have state, and can do things. Bundling them together made a lot of sense. Inheritance also worked well, as all the objects were purely artificial creations. They were precisely how one chose to define them in code.
Problem was, the rest of the world is not like UI widgets. The main difference being, it has a reality external to the code. State and behavior are not so obviously bundled into types and instances. Verbs are sometimes more important the nouns.
But OO had been sooo successful w/ UI widgets, that many people hoped to repeat that success more widely. OO also provided an easy way to dumb things down--"everything is an object" obscures all the hard questions--just start with objects, and keep writing code until the thing works.
That's a silly argument. It could be applied to almost any programming language. Just start with functions...
The hard choices are what data structures, and algorithms to use and OO does not get rid of that.
When did I ever say that?
If you wanted to search the database, say people with a certain name, belonging to certain faculty, you'd have a separate method that indirectly runs SQL statement or ORM statement for you.... Perhaps belonging to the faculty object, the method taking the name as the param.
You could even have a single generic search method belonging to the faculty object, that allows a whole range of relational features(SETs etc) to be used in the search.
If you wanted to search all students, you'd have a generic search method, on the student object?
That's the most obvious design ever? Unless you wanted to make it difficult?
You answered the question as if that really was the only many-to-many relationship in the system. I observe that it is only an exemplar, and that in practice any real system is shot through with similar relationships, and the answer isn't to implement each one of them in OO.
If you're using an ORM, btw, you're using a relational system under the hood, which is my point. You seemed to be implying pure OO had answers to that problem, and it really doesn't unless it imports a foreign paradigm like a relational database. If that wasn't your intent, then we're in agreement.
ORMS allow you to use those relational features(HQL, LINQ), except without the boilerplate of manually populating objects, connecting to the database or whatever...
Nearly every search you perform via orm, uses relational operations...
Y = X.where(p => p.name == "Bob");
PS: You can also use the select syntax if you want.
Student <-> Facoulty is many to many relation. I can make
Faculties keeping arrays of pointers to Students, and Students keeping arrays of pointers to facoulties, and update both arrays accordingly when something changes.
Then I want to save the information, that Student X finished Facoulty Y, but still studies at Facoulty Z.
So pointers from student to facoulties won't suffice. I need to have a place to keep this data. So I introduce Relation object, like I should have from the start. And I end the Student/Teacher maddness, and make Person<-Relation->Facoulty. Much better.
Then I want to be able to filter students according to different conditions. And I end up writing nested loops for every possible condition and join I need. I refactor. I generalize. After a few months or years I've implemented nonstandard relational database.
> Because you manually want to populate objects with tons of boilerplate?
Because I don't want to have objects at all, when relational db is the right tool.
"Then I want to be able to filter students according to different conditions. And I end up writing nested loops for every possible condition and join I need. I refactor. I generalize. After a few months or years I've implemented nonstandard relational database."
Only a moron would write loops to search using an ORM. You implement a generic search method on the object, which executes the relevant SQL statement(Via HQL or LINQ) and returns the result.
ORMS do this stuff automatically, no need to write loops to search...
I mean how badly have you been abusing ORMS?
You've been using ORMS wrong. ORMS provide the whole range relational features. They just map the results of the SQL statement into objects.
Relational Databases are good keeping data integrity correct, not so good at modelling computations. So you use the best tool for the job, relational database for storing data. Then extract that data from the database, and then use whatever (functional, OO, logic languages) to perform operations on that data.
Relational is not a way to perform computations on data, other than searching and using the various relational search features. Try implementing a machine learning algo on data using solely SQL...
I described how I've been taught OO. First without using databases, and with wrong abstractions (nouns instead of relations, when the system was all about relations). I think it's the default experience, because I've seen many such examples of bad OO design.
Then we've been taught databases, but using ORMs, like it was the only possible way, because objects are required for the system to be modern. And I don't like that too, because IMHO (OO + ORM + relational DB) doesn't add any value over (procedural programming with relational DB), but adds complexity, and is less transparent.
If you prefer procedural code, then obviously ORMs are no use to you...
I mean love various programming paradigms, I like Haskell, but it can make things difficult. For example programming a basic game in haskell, is far from simple. You normally have to introduce reactive programming to make it sane.
I find OO makes large systems easier.
In my opinion the amount of boilerplate required for JDBC makes ORM a must in java...
Just yesterday a colleague of mine looked at me with chock and awe when I told him I enjoy coding in C. "But... it's not OO!" he mumbled, puzzled.
Pushing the caricature a little further, Python and Ruby are toy languages that only hipsters use, Perl is only to be used by the sysadmin down the hall, and Lisp is the biggest failed experiment programmers ever came up with.
Pointy-haired bosses encourage this kind of thinking: They would never get in trouble for chosing a language amongst the big 3 (C++/C#/Java).
I once heard someone say: "I don't understand why there are still new languages coming out every day. Shouldn't everyone just use Java?"
As opposed to an endless "Ruby vs Python vs PHP" flamewar?
Pushing the caricature a little futher, C++ and Java are enterprise languages that only old out-of-touch programmers use.
Hipster Apple-using kids encourage this kind of thinking: They would never be un-cool for choosing a language among Ruby, Python, or Lisp.
It's far too easy to become that type of programmer. Choice of language has little to do with it. No doubt you understand this, just making the point clear.
F# is interesting, Scala is interesting, and we both wondered what it would be like to really try ocaml for real. But Java's just pretty solid. It's not exciting, but it's quality engineering. It makes some questionable trade-offs, but it seems to provoke more hate than it deserves.
Of course, we then rolled our eyes about all the crazy Java stuff we've seen, with XML-everywhere, FactoryFactories, and gratuitous IoC.
That started me wondering: what is it about Java that encourages the craziness? My theory is that it's a combination of garbage collection and lack of easy blocks/anonymous functions. Garbage collection lets you get away with things that you'd never try in C++, and lack of blocks means you're stuck with a pretty limited API, so you end up inventing extra-language channels for information.
Note: I intentionally didn't demand closures. I think the original blocks in Smalltalk weren't closures, but they were still useful for things like "monkeys select: [:m | m throwsPoop]". I'm not sure if this is really enough; closures make some things a lot easier.
It doesn't hurt when you're trying to rack up a lot of billable errors and keep clients dependent on you.
These resulting structures then end up being factories (You could pass the object creation function), command objects (you could have a function to call instead of a command to pass back) and so on.
The problem is called lack of skills, not the language.
I don't know what it is about Java that seems to encourage the mess, but there is something.
I have seen lots of awful code, when you combine software design done by out of touch architects, with lousy enterprise coders, regardless of the chosen language.
I remember being told that my way would work but wasn't OO enough, and because of that it was wrong i.e. I hadn't done well on that portion of the interview.
So, before my first contact with OO, I learned BASIC, 6502 assembly, FORTRAN, GraFORTH, C (on QNX!), some Pascal (Turbo on CP/M), a little bit of Lisp (and I ran away from it). Dijkstra would consider me hopeless.
The worst part about it is that it actually made sense. You don't want your Order class to worry about localizing dates and you don't want to clutter your glue code with Java's cruel date/time system either. You also don't want to make yet another subclass of a date/time and glue it to your ORM.
What was the first API for amazon aws in? Java. Nearly everything has Java API because it is so well supported.
Java developers don't get off on, programming language one upmanship. Some people like being boring...
SAP? Jave API.
Oracle? Java APIs.
Google Stuff? Java APIs.
Android? Java APIs
nearly every piece of commercial software has java apis.
I remember having to use a 3rd party django paypal plugin and it was half broken(IPN callbacks), that would be unlikely with Java. Ended up faffing about in its source code to get it working.
Maven obviously isn't as nice as the way Ruby handles Gems, but to me it feels more structured.
Especially since most programmers out there are not polyglots, work in a big company, and may not even by "programmers" but just "engineer/accountant/business person who programs a bit".
What is the business value for rewriting the code in the flavor of the month language?
In what sense does it improve profit?
Sometimes it's hard to convince them that even particular OO-flavor is not the end of the road.
C++ - guys thinking that OO in C++ is the best, java-guys thinking that extensions methods ruins OO in C#, all of them looking with horror in python. (Where's my private and protected??)
Totally reformed now - I hope.
Usually it's someone responding to some personal issue with a public post. Perhaps they argued with a peer.
I also found it to be a serious mental bender to see OO and Java called "new", relative to "old". In most programming groups Java is the new Cobol, considered anything but new. Often it is a legacy language.
Oracle likes Java, but that's because their products are largely code produced over a decade ago.
Java at Twitter
Java at Facebook
Java at Amazon
Strange, because I have met many of them.
As well as many VB jockeys, who would look at you with a blank stare if you mentioned either OO or functional programing.
Maybe you should work in bad companies more ;-)
That may be because data structures is what we actually need. Data structures largely determine the computational complexity of operations and I think it makes little sense to act as if we could always think in terms of abstract responsibilities, interfaces, encapsulation, message passing, etc.
These things are useful organizational principles for coping with large systems, but at the core of most large systems is some algorithmic transformation of one data structure into another.
So a project (well at least in my experience) progresses like this:
"Wonderful architecture" > "glad I designed this project well, its' paying dividends!" > "hmmmm I never considered this paradigm before" > "new guy joins team" > "argh this code is crap"
Object oriented programming can be really elegant... but I can see why people hate on it.
The fact is, abstraction is key to programming. People who have a hard time managing extra abstractions in their head probably aren't nearly as good of a programmer as they think.
Go ahead and just fiddle around in that million loc c codebase. Or that million loc java codebase. (and ignore for a second that that c codebase is a large compiler and that java codebase is an elaborate hello world). Or a hypothetical million line haskell codebase.
In C you have to understand modules, functions working on structures and functions controlling the architecture. In Java you have to understand class hierachies and classes or functions managing the control flow. In haskell, you have to understand abstract data types, type classes and monads and functions managing control flow.
FP is great when expressing computations, but we often are just gluing nominal entities together, where OOP excels over FP. I like to have a few FP options in my languages (C#, LINQ), but my mind is firmly rooted in objects when it comes to overall macro design of the program.
In most systems - changes over time, archival data, and relations between objects are important. And with OO it's ugly to keep them. You end up implementing relational db backed by object collections. And your nice objects instead of representing nouns (Employee, etc.), start representing relations (Employement, etc.).
So people use relational db with ORMs and load everything from database into objects only to show window/edit data, call one or 2 methods on these objects, and save data back into database. All this ceremony to write employee.giveRaise(raise) instead of giveRaise(employee, raise).
I use objects in reactive (non-persistent/DB) systems all the time. Objects aren't the problem, but you do have to manage your dependencies dynamically by tracing/dirtying/and cleaning. Objects actually excel at encapsulating and managing state, it is much harder to do this with functions (see all the work on functional-reactive programming).
BTW, I learned to program on a Texas (TI-55) calculator. What symptoms should I be presenting? ;-)
Why is it so hard to understand that there is an implicit set of limitations based on the tools (and/or materials) we use in our projects?
Think skyscraper... now think wooden skyscraper.
Hail, Torat Exists, the holy teachings of the existential type!
Among the C++ crowd (particularly over at Stack Overflow) there's this infuriating attitude that any code that doesn't use std::string, std::vector or boost::magic_super_auto_ptr is language sacrilege and the developer should be burned with fire because it's not C++ it's C and malloc is deprecated and arrays are deprecated, and, and...
Normal malloc, and dealloc can get stupidly complicated when lots of other objects reference one memory location, which is why these referencing auto pointers come in, with built bounds checking etc
Using those things is defensive programming.
I agree with what you said. I tried hard to use C++ language features (especially STL) in a previous job and it was more hassle than it was worth, honestly.
Then sometimes actually getting a external c libary to build(If it's not in the package manager) is sometimes trouble. ./configure ./make usually ends up in some obsercure error or depedency... C++ usually makes the errors even more unreadable...
Hmm... I never ran into too many problems with this myself, but it could just be outside of my experience. Can't TYPEDEFs help with this?
Also, better to have the code to step through, rather than decrypting STL/template compiler errors, no?
And what's the harm in a bit of repetition of code structures?
> Then sometimes actually getting a external c libary to build(If it's not in the package manager) is sometimes trouble. ./configure ./make usually ends up in some obsercure error or depedency... C++ usually makes the errors even more unreadable...
C++ is the main thing I'm comparing C to. Yes, sorting out dependencies isn't fun.
Yeah, but in C you end up creating your own data structures from scratch every time.
is not true.
ie: To use an ORM you must use a relational database. Things like mongoose exist, but they're not ORMs since they don't map objects to a relational database.
What is substituted is not the relational DBMS but the relational model. ORMs are supposed to let you think in terms of objects instead of sets of tuples.
ORMs do these automatically, and go beyond.
But people tend to just blindly copy everything into an object model and perform operations on those objects that could just as well have been done in a set oriented way with a lot less code causing a lot less network traffic.
Obviously there are scalability downsides and not everything is easier to express in terms of sets, so I try to be pragmatic. You can of course do set operations through an ORM but that's not its purpose and the performance implications are sometimes tricky.
However there is one thing, most ORMs by default transfer the whole object. What is you only need a few variables?
OOP might not be more modern but I think it was trying to move into the direction of less specialization. Unfortunately, it has gotten side tracked.