Forgot your password?
typodupeerror
Java Programming

What's wrong with HelloWorld.Java 181

prostoalex writes: "Daniel H. Steinberg posted an article on O'Reailly's OnJava.com discussing the difficulties and current problems with introductory Java in the classroom. The textbooks used in colleges are mostly the rewrites of C/C++ textbooks and thus start with HelloWorld program without really dwelling on object-oriented nature of Java and why it is important. In a nutshell, OOP even nowadays is treated as somewhat innovative concept in the classroom, mainly because of educators, who were taught C. Hence links and description of Rethinking CS101 Project."
This discussion has been archived. No new comments can be posted.

What's wrong with HelloWorld.Java

Comments Filter:
  • by BalkanBoy ( 201243 ) on Thursday August 22, 2002 @09:46PM (#4123932)
    People can never get this through their heads. OOP is _not_ about what language you use or what tool you use that more or less will or can facilitate OO programming. OOA&D (e.g. object oriented analysis and design) is not about mastering Java or C++, it is about mastering a new style, a new paradigm of thinking. This is precisely when Java or C++ is taught by "old skool" K&R C people who hate the thought of anything resembling OO (and I wont mention how many are of those out there... too many, rest assured) it looks like Java or C++ is C wrapped in objects. The usefulness of the paradigm is reduced and de-emphasized if the proper train of thought is not employed when analyzing solutions in an object oriented fashion.

    One has to be able to perceive problems in terms of objects. This may at a glance seem easy - our world is composed of objects, but when you start getting into more abstract concepts, e.g. trying to write OS's in a fully OO manner (akin to what BeOS was) , or other more complex applications like the entire JFC (for instance), then OOA&D does not seem so easy!

    Designing, or better yet, THINKING in OO terms is not something that happens overnight. This is precisely also the reason as to why 90% of large, pure OO projects either fail or start to degenerate into something that needs revamping every so often, only because the programmers who built the application did not take the time to properly analyze the problem and come up with the most natural solution possible. A natural solution is possible, but only at the hands of professionals, who understand what OO is all about (and it is least about WHAT LANGUAGE you use), who have experience in 'seeing' the world, or higher concepts through OO eyes and who are able to delimit, with crisp boundaries every concept/object available to them or as stated in the specifications by the customer and MOST importantly establish the PROPER relationships between those objects!

    Design patterns and such go a LONG way toward getting this objective, but one cannot fathom using or applying design patterns if he doesn't understand what OO design and analysis means, and without a shitload of experience to use toward this goal. True OO thinking is almost like a lithmus test of how good a programmer, or better said, an ANALYST, an ANALYTICAL person, or your ANALYTICAL skills are... In OO, 80% of the time or thereabouts is spend on analysis and design, 20% on the mechanics of writing the code. Then, and only then, will you be able to pull OO projects successfully through completion.

    And no, I'm not talking about your school/academic projects, I'm talking about large scale projects with possibly millions of lines of code where understanding the ESSENCE of the OO paradigm will either make or break a project and make it usable and extendable for a long time or make it a piece of crap that will never see the light of day...

    Most people shy away from OO or misunderstand it because they've never even read a book about OO either, such as the OO 'bible' by Rumbaugh/Premerlani "OO modeling and design using OMT", or some of Fowler's books on analysis, patterns, or Gamma's book on design patterns...

    Someone once said - pimpin' ain't E-Z! Well, neither is OO!
  • OOD101 or CS101? (Score:5, Insightful)

    by one9nine ( 526521 ) on Thursday August 22, 2002 @09:55PM (#4123964) Journal
    Are we talking about a beginning OOD class or a beginning CS/Programming class? When you first teach someone how to program, the last think you want to do is start with OOD. One must learn about variables, arrays, assignment vs. comparison, loops and conditional statements. Then one must learn about functions and how to separate code into them. Simple algorithms need to be introduced as well. Also, how to break down a problem into several steps and then code it. Finally you can start to teach about classes as well as one of my personal favorites, data structures.

    Just because Java is focused on objects doesn't mean you have to teach OOD right off the bad. You have to start with the basics. True, you going to have kids ask "What does static mean?". You just tell them to ignore it for now. Why is that looked upon as a bad thing? The same thing happens when you teach C++. You tell your beginners to ignore stdio. Later, when it's time, you can teach about includes and classes.

    This is why I didn't learn jack shit in college. Everything is focused on OOD. Object this and class that. I am not saying there anything wrong with OOD, but colleges don't focus enough on the fundamentals. That's why there are so many people who overengineer everything and who can't even tell you the difference between a Mergesort and a QuickSort or even know what a Red Black tree is!
  • by PD ( 9577 ) <slashdotlinux@pdrap.org> on Thursday August 22, 2002 @10:24PM (#4124055) Homepage Journal
    There really is no good OO way to print in Java. How are you going to make a hello world program print? System.out.println ("foo") isn't any better than the old BASIC

    10 PRINT "FOO"

    It does little good to make a version of hello world that has some objects in it when in the end there will be a System.out.println call.

    I think you're really arguing for a language that will let you write hello world like this:

    "hello, world".print

  • by Mr. Shiny And New ( 525071 ) on Thursday August 22, 2002 @10:29PM (#4124080) Homepage Journal
    I agree that a distinction has to be made between OOD and algorithms and basic programming fundamentals. I would say that a good way to learn software development would be as follows:

    • First, learn basics like arrays, data types, operators, functions, pointers, structures. Learn one or two languages.
    • Second, learn about algorithms and data structures. Learn about sorting and merging lists, learn about heaps, stacks, trees, etc. Learn about algorithm complexity. Make sure to emphasize modularization; that is, if you are learning about trees, make sure the code you write to manipulate the tree is cohesive.
    • Learn about objects and OOA/OOD. Learn how data structures lead to classes and objects. Learn about data hiding, iheritence and polymorphism.
    • Learn design patterns. Show how solutions to certain families of problems can be re-used. Show how algorithms can be made more generic by using polymorphism.


    • Somewhere along the line you should learn more about algorithm complexity, various programing paradigms (like functional programing), low-level languages like assembly, operating system and networking concepts, and any advanced topics like databases and distributed programming and real-time programming. But these are all extras. I still think that a programmer needs to learn what a loop is before he should be concerned about what an object is.
  • by PS3117 ( 603310 ) on Thursday August 22, 2002 @10:31PM (#4124087)
    The generation of code is the small (critically important, but small) part of development. The "game" is in the head, or more precisely the mind of the developer. Teaching someone to write code effectively is not a terribly daunting prospect. However, teaching someone to think, much much more complicated. In contribution to this difficulty the education system here in the USA is not geared towards excellence, it is geared towards the average, the everyday. Just an opinion, feel free to flame away, but the so termed fuzzy subjects such as art and music teach students to see not what is there, but what isn't, and more importantly what could be. There are a great many technicians out there who generate code, but virtuosity in any endeavor is art as much as science or technology, it is seeing, feeling. I had the privalege of speaking at my daughter's school on career day and when asked what I did, my response was, I build models. I build models of business process or at the moment engineering processes. In short what we do as developers is model behavior. I have maintained for years that the only way to get good at development is not education, it's scars, scars earned in the trenches getting beaten on by cranky code, twitchy servers and managers who haven't got a clue. The same is true for OO, get into it up to your neck, get it into your pores think it breathe it read it discuss it beat it to death. Then you can become a prophet in the wilderness of software development and have managers look at you like you're something to the left of a cultist. Balkanboy is right it's not easy, but "It's the hard that makes it great. If it was easy anyone could do it." (paraphrased from "A League of Their Own"
  • by Xavier Shirin ( 445036 ) on Thursday August 22, 2002 @11:52PM (#4124435) Homepage
    Everything IS an object, but most computer people don't think about things that way, because they learned to code procedurally. To many programmers, objects are auxiliary to functions, used only when it is necessary to organize.

    If you teach a student to think in an object oriented way from day one, they will think of everything as objects, just like most coders think in procedures now.

    But that's just my two cents.
  • by Dr. Bent ( 533421 ) <ben@NOSPAm.int.com> on Friday August 23, 2002 @12:34AM (#4124553) Homepage
    The real problem here is software development has moved beyond what a scientific discipline can handle. Much like modern electrical engineering evolved from the findings of early 20th century experiments with electricity, the need for real software engineering is starting to become apparent.

    But, as always, acedemia is behind the curve. Not that they should be on the bleeding edge, but now it's time to catch up. Computer Science programs across the country have started to straddle the fence when it comes to coursework. Do we teach theoretical science, or applied science? This is a mistake; Nothing done half-assed is ever worthwhile. Do not make Computer Science more like an engineering discipline. Instead, make Software Engineering an undergrad degree unto itself.

    You should be able to teach CS101 in any language. If you can't, then you're trying to teach engineering in a science class. A stack is a stack regardless of what langauge it's written in. Don't pollute computer science by trying to make it something it isn't. Instead, make a new Class (pun!)...Software Engineering 101. There you can teach design methodologies (Like OOP), proper use of the latest tools, automated testing methods, and other applied theory that has no business in a computer science class.

    This is not to say they there wouldn't be a great deal of overlap between a C.S. and S.E. degree. After all, you have to learn physics before you can be a Civil Engineer. But it's just not possible to teach you everything there is to know in 4 years. I've learned so many formalisms and techniques since I recieved my B.S. in C.S. that I wondered why I hadn't heard anything about them while I was in school. The answer, I realized, is the days of the computer Renaisannce man are ending. Developing an algorithm and developing a software system are two completely different tasks. Just as a physicst can't build a bridge and a Civil Engineer didn't invent Superstring thoery, you can't ask a computer scientist to build a software system or ask a software engineer to develop a new compression algorithm...it's just the wrong skillset for the job.

  • by Arandir ( 19206 ) on Friday August 23, 2002 @02:42AM (#4124924) Homepage Journal
    Sometimes you have to live in the real world, and you discover that not everything follows a single paradigm. Languages that follow a single paradigm have serious drawbacks. Java is one. There's a reason why Java isn't used for systems programming. There's a reason why Corel has yet to finish it's Java office suite.

    An int is four bytes on my CPU. Why should I have the overhead of an object wrapped around it? Why do I need runtime polymorphism on ints? For OO educational purposes, it makes sense to teach that an int is an object. But often in the real world it's far better to make an int simply four bytes in memory.

    Rule of thumb: if polymorphism doesn't make sense for an object, maybe it shouldn't be an object. What can you possibly derive from a bool that wouldn't still be a primitive bool?
  • by Anonymous Coward on Friday August 23, 2002 @03:32AM (#4125039)
    Bleurgh. OO isn't everything, and Java OO is deeply crippled and sucky anyway. Common Lisp, perhaps closely followed by Smalltalk, has the best OO programming (and is the _only_ language that can fully satisfy every feature on the OMG description of OOP!) - but, paradoxically, Lisp is a language where one seldom resorts to huge baroque OO stuff anyway.

    N.B. One should be teaching general principles, not language-of-the-day, anyway - I am not suggesting Lisp is the one-true-language, anymore than Java is - Lisp would suck for teaching manual memory management techniques, for example.

  • Python (Score:2, Insightful)

    by tdelaney ( 458893 ) on Friday August 23, 2002 @05:33AM (#4125279)
    print 'Hello, world!'

    It does exactly what it needs to, without anything extra. Each piece can be discussed separated, and picked apart or expanded as desired.
  • by Mr. Shiny And New ( 525071 ) on Friday August 23, 2002 @08:38AM (#4125620) Homepage Journal
    Well, in Java, and int is 4 bytes. An Integer is an object wrapped around an int, as you put it. This object is useful for many things. Math isn't really one of them. For plain math, use plain ints.

    C#, however, has automatic wrapping of primitive types with objects. This is supposedly done on an as-needed basis. I've never tried it, but I'd assume that the wrapping happens only when it's required, otherwise the VM will preserve the basic types for performance reasons.

    As to reasons for why there is a Boolean object, it's really just a question of convenience. The Boolean class contains methods for manipulating booleans, like making Strings out of them, or making new booleans from strings. What's the harm in extending this helper class to also represent a boolean value? It's still an object. Maybe you never need to subclass it? That doesn't mean it shouldn't be an object.
  • I think one problem is the structure of a language.

    I mean: what is a first class citizen? In C everything can be degenerated down to a pointer, except a preprocessor macro.

    So the only true first class citizen is a pointer, or in other words a memory address. Structs and functions seem to be something utterly different. Even besides the fact that you can take the adress of both.

    In C++ suddenly we have similarities: structs are similar to classes and similar to unions. With operator overloading you can manage to get a class behaving like a function, a functor.

    But: wouldn't it make more sence to say we only have *one* thing? And wouldn't it make sence to make far more stuff optional? Like return types, access modifiers, linkage modifiers ... void as return type, how silly. I have to write: "HELLO HERE IS NOTHING" instead of writing nothing.

    {
    int i =1;
    }

    Whats that? Data? A thing with a 1 inside stored in a thing with name i? Or is it a function with no name and a local variable i with value 1?

    lets give it a name:

    thing {
    int i = 1;
    }

    Why can't a language creator understand that OO and functional paradigms are just the two sides of the same medal? The thing above serves pretty well as function and as class.

    thing a = new thing;

    Create an instance of thing ... if (a.i == 1) is true!

    if (ting().i == 1) is true also, call thing like a function.

    There is no need to have functions and structs to be different kinds of language constructs and thus it makes no sence that a modern our day language forces one to distinguish it.

    In short: System Architects get a language wich allows to express the world they like to modell in terms of Objects/things and assign behaviour/functions to objects. Unfortunatly the language designers are mostly BAD OO designers and are not able to apply the first principles of OO correctly to the languages they invent: everything is an object.

    Even a for(;;) statement is not a statement. Its an object. Its an instance of the class for, the constructor accepts 3 arguments of type expression, you could say Expression(.boolean.) for the second one. Well, for the compiler it DEFINITLY is only an object: java.AST.statement.ForStatement ... or something. Why the heck can't it be a class available to the ordinary programmer? At least for the teacher and the student it should be viewable as a for object and not a for statement.

    Sample:

    for (Expression init; Expression(.boolean.) test; Expression reinit) { Block block }

    Hm? a function or a class with name for.
    Two parameter sections, one in () parenthesis and one in {} braces.

    What you pass in () is stored in init, test and reinit. What you pass in {} is stored in block.

    The compiler crafter puts a for class into the lirary:

    class for (Expression init; Expression(.boolean.) test; Expression reinit) { Block block } {
    init();
    loop {
    test() ? block() : return;
    reinit();
    }
    }

    Wow, suddenly everything is a class. Hm, a meta class in the case above probably. A language would be easy to use if I told my student:

    Ok, lets store an addressbook! What do you like to be in an adressbook? Name, first name, birthdate, phone number? Ok, then you do something like this:

    { Name, FirstName, Birthdate, PhoneNumber }

    We group it. That thing has an anonymous type.

    How to create objects?

    new { Name="Cool", FirstName="John", Birthdate="12/27/66", PhoneNumber="080012345" }

    Wow ... and now we need two of them, so lets give them a name:

    cool = new { ... }
    bad = new { ... }

    And we need to compare them and search them and suddenly we need to put "methods" aka "behavioural" objects into them. Oh, yes and the anonymous thing above needs a name, so it becomes a class.

    What I describe above is Lisp, but with a more C/Java/C++ like syntax.

    And a radicaly reduced language design. The best would be to put the language design into the runtime libraries.

    Yes: every typed language should be able to work typeless as long as you are in a "skteching" phase.

    Regards,
    angel'o'sphere

    Note, for template arguments I used (. and .) instead of what you expect ... /. eats the less and greater signs.
  • by scrytch ( 9198 ) <chuck@myrealbox.com> on Friday August 23, 2002 @01:04PM (#4127406)
    Go see that page, oop.ismad.com and you'll mod the parent up to +5 funny. Just ignore the gross misunderstanding of OO, the selective process of argument where he flips between implementation and concept, the plug for some vague "table driven programming" thing (that basically is OOP without inheritance), and the entire fallacy of division (google for it) that is promulgated throughout... probably a good fifth of the material is dedicated to red baiting, to the point of displaying a hammer and sickle flag. My congratulations on a masterful troll. It had me going for a bit. Love the "beat up spock" visual analogy for "abuse of logic" too.
  • by Tablizer ( 95088 ) on Saturday August 24, 2002 @02:05PM (#4133637) Journal
    As I've pointed out before, it's in the collective experience of legions of software developers..... It's hard to believe that they're all wrong on everything after all this time.

    1. Collective experience use to be that the world is flat.

    2. It could be subjective (the "mindfit" argument). That is fine, but 99% of the stuff on the shelfs implies that OOP is objectively better. I don't see disclaimers that the benefit list may be subjective.

    3. The "popularity metric" is that Windows is "better". Do you really want to back that?

    4. I have never seen a good survey that said most developers prefer OOP.

    and by your own admission, your experience comes from a very narrow field of programming, to which one approach seems much better suited. It's not surprising that you find that approach superior.

    Narrow, but large, I might point out. Not a single OO book ever limited it's braggings to specific domains, instead strongly implying a "step up in evolution" over procedural.

    Those of us who work in diverse areas of programming have often found OO to be at least as natural as, or more natural than, a purely procedural approach.

    Unless you can define/measure "natural", that appears to be a rather subjective thing.

    Plus, some OO fans here have said that OOP is *not* "natural" nor should that necessarily be the goal of it.

    I believe in the scientific process where you have to openly justify things based on open evidence, and not personal opinion and "feelings". Your "evidence" fails miserably here.

    BTW, who gave that ahole a "4"? It contains almost nothing but personal digs. Damned moderators!
  • by Anonymous Brave Guy ( 457657 ) on Tuesday August 27, 2002 @07:44AM (#4147482)
    There must be a pattern to what goes wrong with the non-OO equivalent. [...] Is it that so fricken hard to articulate?

    Not at all. There are some clear areas where OO designs tend to do better than procedural. Most of them, in fairness, are due to the fact that an average programmer is not an expert and OO makes it easier for him to avoid problems that an expert would avoid using either style. However, the programming population is dominated by those in the middle of the ability bell curve, so I think this is a reasonable case.

    The most obvious flaw with much procedural code that I have seen is that as projects grow, the design often becomes incoherent. In particular, special cases start appearing because it is easy to "just add another function" or "code the problem out with an if statement". These cases result in vast numbers of bugs, not because there is any inherent problem with using if per se, but because the approach does not scale. The number of possible results is exponential in the number of special cases, and sooner or later, special cases start conflicting and nobody notices. Even automated tests start suffering, because it becomes practically impossible to exercise all of the code paths and special cases systematically. (NB: I am not talking about cases where you have several genuinely different actions to take because your data is substantively different, which obviously happens frequently in programming whatever style you are using. I'm talking specifically about the little hacks that are put in rather than adjust a design to account for special cases cleanly throughout.) The greater range of design tools available to an OO programmer mitigates this effect somewhat, and the encapsulation and data hiding encourages the maintenance of a clean design without the proliferation of special cases.

    I also question whether typical procedural designs do adapt to change as well as typical OO designs. Again, lacking the emphasis on encapsulation and data hiding that OO advocates, there is a tendency for responsibility to become spread out. Instead of particular data being owned and used by a clearly defined subsystem (whether that be a class or set of classes in OO, or a particular table or set of related tables in relational), in procedural code, it is easy and common for "convenience" structures to appear and be passed around all over the place. This, again, is a common source of bugs. Data spreads, but the controlling logic does not, resulting in accidental changes that violate invariants, mutually dependent items of data being used independently, clashes over resource usage, etc.

    To me, the proliferation of special cases and the arbitrary spread of responsibility are the most common failings of moderate to large procedural designs. I'm sure a group of expert programmers would avoid many of them, but it is clear that typical, most-of-your-team coders do not. OO's approach helps to alleviate these problems with its emphasis on encapsulation and data hiding.

    Note also that none of this has anything to do with inheritance and polymorphism. IMHO, these are also valuable tools, but much of their value comes from the way they allow you to extend an OO design without breaking that focus on encapsulation, which is the source of the big benefits in most of the projects I'd consider "good OO". Of course, there are other advantages for things like type safety, but these, to me, are secondary.

    How does OOP allegedly fix [the special case problem]? Inheritance? I find that the granularity is often too large. You can't override 1/3 of a method for example if only 1/3 is different.

    It is true that you cannot do this in most OO languages, and I freely concede that on occasion this is annoying. However, in fairness, if your methods are reasonably well thought out and self-contained as they should be, this problem rarely arises in practice. When it does, it's usually because a new and significantly different set of requirements have been added to a previous design, and that is normally grounds to adjust that design, possibly by reorganising the methods available. Wanting to override 1/3 of a method is usually symptomatic of either an unfortunate original choice of responsibilities, or of such a change in requirements, and in either case the answer is usually the same.

    The second rewrite is often better simply because you have *hindsight*. IOW, learn from misktakes of the past. Thus, "rewrites" don't make very good comparisons.

    Unfortunately, most large-scale projects don't get written simultaneously by two identical programming teams in the different styles just to provide an objective comparison. Such porting exercises are the closest you can realistically get to a fair comparison. I agree that the second project will mostly likely have an advantage due to hindsight, but it's also often hampered by the lack of expert domain knowledge that was available when the original was written. Even neglecting that drawback, I question whether that advantage could have made a three-fold difference to development speed (which was sustained even in new development) and account for a 90% reduction in bug rate (which was also sustained). If you truly believe that this could be the case, then I have no further information I can provide about this case to convince you of OO's benefits.

    Unless you perhaps feel that the procedural version was the *best possible* that procedural can get. Do you feel that?

    No, I'm quite sure it wasn't. However, it was real procedural code that was actually produced by a real development team, not a theoretical, artificially perfect implementation produced by a team of 100% effective experts. The OO version to which I'm comparing it was also real world code produced by a real world team. This is what actually happened, which IMHO is far more important for most purposes than what might have happened in an ideal world. Ideal worlds don't pay the rent. :-)

    Perhaps, but one has to refactor *less* in p/r because most of the "noun model" is in the database. You just change relational formulas to get different "views" instead of physical code structure. It is like commanding and army instead of moving each and every soldier by yourself.

    That's hardly fair. Refactoring a class design, even right down the hierarchy, is no more of an endeavour than a similarly scaled adjustment of a database schema to allow the new relations you want to describe. More modest changes to a design don't require this scale of change in either approach.

    Well, there you go. Those are some actual, concrete, clearly defined situations where I feel that OO can convey significant advantages in measurable things like bug count and development rate, and an actual, concrete example where it worked in a real project. I can't do much better than that. :-)

"Wish not to seem, but to be, the best." -- Aeschylus

Working...