Kuro5hin.org: technology and culture, from the trenches
create account | help/FAQ | contact | links | search | IRC | site news
[ Everything | Diaries | Technology | Science | Culture | Politics | Media | News | Internet | Op-Ed | Fiction | Meta | MLP ]
We need your support: buy an ad | premium membership

[P]
C# From A Java Developer's Perspective

By Carnage4Life in Technology
Mon Nov 19, 2001 at 02:10:44 AM EST
Tags: Software (all tags)
Software

The C# language is an object-oriented language that is aimed at enabling programmers to quickly build a wide range of applications for the Microsoft .NET platform. The goal of C# and the .NET platform is to shorten development time by freeing the developer from worrying about several low level plumbing issues such as memory management, type safety issues, building low level libraries, array boundschecking , etc. thus allowing developers to actually spend their time and energy working on their application and business logic instead. As a Java developer the previous sentence could be described as "a short description of the Java language and platform" if the words C# and the .NET platform were replaced with words Java and the Java platform.

What follows is an overview of similarities and differences between the language features and libraries of the C# and Java programming languages based on my experience using both languages. All code snippets below were tested on Microsoft's .NET Framework Beta 2 for C# snippets and Java™ 2, Standard Edition (J2SE™) version 1.4 Beta 2 for the Java snippets.


Index
  1. The More Things Change The More They Stay The Same
    This section describes concepts and language features that are almost exactly the same in C# and Java.
    1. We Are All Objects
    2. Keyword Jumble
    3. Of Virtual Machines and Language Runtimes
    4. Heap Based Classes and Garbage Collection
    5. Arrays Can Be Jagged
    6. No Global Methods
    7. Interfaces, Yes. Multiple Inheritance, No.
    8. Strings Are Immutable
    9. Unextendable Classes
    10. Throwing and Catching Exceptions
    11. Member Initialization at Definition and Static Constructors

  2. The Same But Different
    This section describes concepts and language features that differ either only in syntax or in some similarly minor manner between C# and Java.
    1. Main Method
    2. Inheritance Syntax
    3. Run Time Type Identification (is operator)
    4. Namespaces
    5. Constructors, Destructors and Finalizers
    6. Synchronizing Methods and Code Blocks
    7. Access Modifiers
    8. Reflection
    9. Declaring Constants
    10. Primitive Types
    11. Array Declarations
    12. Calling Base Class Constructors and Constructor Chaining

  3. An Ever So Slight Feeling of Dèjà Vu
    This section describes concepts and language features that exist in C# that are similar to those that exist in Java but with a significant difference.
    1. Nested classes
    2. Threads and Volatile Members
    3. Operator Overloading
    4. switch Statement
    5. Assemblies
    6. Collections
    7. goto (no longer considered harmful)
    8. Virtual Methods (and final ones too)
    9. File I/O
    10. Object Serialization
    11. Documentation Generation from Source Code Comments
    12. Multiple Classes in a Single File
    13. Importing Libraries
    14. Events
    15. Cross Language Interoperability

  4. Now For Something Completely Different
    This section describes language features and concepts that exist in C# and have no Java counterpart.
    1. Deterministic Object Cleanup
    2. Delegates
    3. Enumerations
    4. Value Types (Structs)
    5. Boxing
    6. Run Time Type Identification (as operator)
    7. foreach Statement
    8. Properties
    9. Multidimensional Arrays
    10. Attributes
    11. Indexers
    12. Preprocessor Directives
    13. Aliases
    14. Runtime Code Generation
    15. Pointers and Unsafe Code
    16. Pass by Reference
    17. Variable Length Parameter Lists
    18. Verbatim Strings
    19. Overflow Detection
    20. Explicit Interface Implementation

  5. Wish You Were Here
    This section describes language features and concepts that exist in Java and have no C# counterpart.
    1. Checked Exceptions
    2. Cross Platform Portability (Write Once, Run Anywhere)
    3. Extensions
    4. strictfp
    5. Dynamic Class Loading
    6. Interfaces That Contain Fields
    7. Anonymous Inner Classes

  6. Conclusion
  7. Resources
  8. Acknowledgements

Sponsors

Voxel dot net
o Managed Hosting
o VoxCAST Content Delivery
o Raw Infrastructure

Login

Poll
Which C# features do you wish Java had?
o Boxing 11%
o Pass By Reference 3%
o Enumerations 11%
o Operator Overloading 22%
o Pointers and unsafe code 14%
o Attributes 0%
o None 14%
o I wish C# had some Java features 22%

Votes: 62
Results | Other Polls

Related Links
o Microsoft' s .NET Framework Beta 2
o Java™ 2, Standard Edition (J2SE™) version 1.4 Beta 2
o The More Things Change The More They Stay The Same
o We Are All Objects
o Keyword Jumble
o Of Virtual Machines and Language Runtimes
o Heap Based Classes and Garbage Collection
o Arrays Can Be Jagged
o No Global Methods
o Interfaces , Yes. Multiple Inheritance, No.
o Strings Are Immutable
o Unextendab le Classes
o Throwing and Catching Exceptions
o Member Initialization at Definition and Static Constructors
o The Same But Different
o Main Method
o Inheritanc e Syntax
o Run Time Type Identification (is operator)
o Namespaces
o Constructo rs, Destructors and Finalizers
o Synchroniz ing Methods and Code Blocks
o Access Modifiers
o Reflection
o Declaring Constants
o Primitive Types
o Array Declarations
o Calling Base Class Constructors and Constructor Chaining
o An Ever So Slight Feeling of Dèjà Vu
o Nested classes
o Threads and Volatile Members
o Operator Overloading
o switch Statement
o Assemblies
o Collection s
o goto (no longer considered harmful)
o Virtual Methods (and final ones too)
o File I/O
o Object Serialization
o Documentat ion Generation from Source Code Comments
o Multiple Classes in a Single File
o Importing Libraries
o Events
o Cross Language Interoperability
o Now For Something Completely Different
o Determinis tic Object Cleanup
o Delegates
o Enumeratio ns
o Value Types (Structs)
o Boxing
o Run Time Type Identification (as operator)
o foreach Statement
o Properties
o Multidimen sional Arrays
o Attributes
o Indexers
o Preprocess or Directives
o Aliases
o Runtime Code Generation
o Pointers and Unsafe Code
o Pass by Reference
o Variable Length Parameter Lists
o Verbatim Strings
o Overflow Detection
o Explicit Interface Implementation
o Wish You Were Here
o Checked Exceptions
o Cross Platform Portability (Write Once, Run Anywhere)
o Extensions
o strictfp
o Dynamic Class Loading
o Interfaces That Contain Fields
o Anonymous Inner Classes
o Conclusion
o Resources
o Acknowledg ements
o Also by Carnage4Life


Display: Sort:
C# From A Java Developer's Perspective | 134 comments (121 topical, 13 editorial, 0 hidden)
Scope of GoTos (4.33 / 3) (#2)
by TheophileEscargot on Sun Nov 18, 2001 at 03:38:35 PM EST

You mention that Goto statements have been retained, but what is their scope? Can you jump to anywhere, or is it restricted to within a class, or within a function?

IMHO: Global gotos still bad!
----
Support the nascent Mad Open Science movement... when we talk about "hundreds of eyeballs," we really mean it. Lagged2Death

Gotos and scope (5.00 / 1) (#6)
by Carnage4Life on Sun Nov 18, 2001 at 03:53:39 PM EST

The documentation I read states that they are restricted it to statement blocks from what I've seen in practice this means they are restricted to jumps within a function.

[ Parent ]
Hmmmm (4.00 / 1) (#12)
by TheophileEscargot on Sun Nov 18, 2001 at 04:13:10 PM EST

Well, that effectively limits their awesome destructive power I suppose. Hardly seems worth leaving them though: why complicate the language when it doesn't have to be backwards-compatible anyway?

I've programmed enough VB 5 and 6 that I'm heartily sick of intra-function Gotos. Pah to the lot of them! Pah!
----
Support the nascent Mad Open Science movement... when we talk about "hundreds of eyeballs," we really mean it. Lagged2Death
[ Parent ]

gotos are useful... (4.00 / 1) (#35)
by Delirium on Sun Nov 18, 2001 at 09:06:08 PM EST

...as multi-level breaks. Often they can be avoided, but sometimes using a goto to do the equivalent of "break(2 levels)" is the cleanest way to implement some things. For example:

for(x=0; x < val; x++)
  while(other_stuff)
    if(some_condition)
      goto finished;

finished:

is simpler and more readable than:

bool done = false;
for(x=0; x < val && !done; x++)
  while(other_stuff)
    if(some_condition)
    {
      done = true;
      break;
    }


[ Parent ]

maybe... (5.00 / 2) (#39)
by pb on Mon Nov 19, 2001 at 01:44:29 AM EST

In a language like Java, though, they use exceptions for things like that; it seems roughly equivalent to what is being allowed here with the goto.

Unfortunately, gotos are only really useful when they aren't limited by scope; then you can use them to *implement* things like function calls.

Of course, the short answer is, if you don't know why it's useful, then don't use it. 99% of the time, you probably shouldn't use a goto statement. But that 1%, man, it just makes you wanna strangle the asshole who purposely left the goto out of Java, and RESERVED the KEYWORD!

I mean, I don't know about you, but I don't feel the need to kiss Dijkstra's ass that heavily; especially since he was probably messing around with graph theory and not trying to write a speedy interpreter/compiler whenever he wrote that paper...
---
"See what the drooling, ravening, flesh-eating hordes^W^W^W^WKuro5hin.org readers have to say."
-- pwhysall
[ Parent ]
labelled loops (5.00 / 4) (#41)
by mlc on Mon Nov 19, 2001 at 03:50:17 AM EST

the following code in java will do what you want.

It makes use of a feature called labelled breaks (I think), which do what you want in the clean case, without allowing you to goto random locations within your function.

OUTERLOOP: for(x=0; x < val; x++)
   while(other_stuff)
      if(some_condition)
         break OUTERLOOP;

There is also labelled continue which behaves as you'd expect.

--
So the Berne Convention is the ultimate arbiter of truth and morality. Is this like Catholicism? -- Eight Star
[ Parent ]

Portability (3.00 / 5) (#8)
by svampa on Sun Nov 18, 2001 at 04:02:22 PM EST

As far as I know Java was designed with the idea of plataform portability. C# has been designed to be "internet language", I'm sure it could be ported to other OS, but I don't think that is M$ idea.

Besides java scripts, Java is used in a lot of internet servers, no matter if they are w2000, Sun or Linux, will C# cover this environment?

If M$ were brave enough to release versions for several OS, M$ would beat Java and anything. Loosing protability is going backward from a technical point of view.

I don't think M$ would do so, I think it's a strategy to tie everything to M$'s operating systems. It is a pity



Microsoft porting C# to other OSes (5.00 / 2) (#11)
by Carnage4Life on Sun Nov 18, 2001 at 04:08:07 PM EST

Microsoft has a team working on a BSD version of C# and the Common Language Infrastructure (CLI), I was even at a presentation they had in Redmond over the summer. Here's a C|Net article on Microsoft and Corel porting C# and the CLI to FreeBSD.

[ Parent ]
ok (none / 0) (#56)
by Ender Ryan on Mon Nov 19, 2001 at 10:52:04 AM EST

Ok, that's nice, but what about Linux? Does Microsoft have the balls to port C# to Linux?

Either way, I don't think it really matters as Microsoft is supplying enough information for people to build their own C# compilers. There are 2 already in the works for Linux, one being developed by (I don't know...) and the other by Ximian.

Does anyone know any more about this? Is Microsoft really playing nice or do they have some trick up their sleeve?

It certainly would be great if Microsoft would quit worrying about maintaining their monopoly and instead truly started "innovating". Maybe that's what they're doing, they have to realize that they can't maintain their monopoly forever and should instead shift their focus to writing good software.


-
Exposing vast conspiracies! Experts at everything even outside our expertise! Liberators of the world from the oppression of the evil USian Empire!

We are Kuro5hin!


[ Parent ]

Linux (none / 0) (#60)
by ucblockhead on Mon Nov 19, 2001 at 11:49:45 AM EST

The GNOME guys are supposedly working on a Linux version.

How "nice" Microsoft is remains to be seen, but up to this point, they've been nicer than Sun has with Java.
-----------------------
This is k5. We're all tools - duxup
[ Parent ]

He mentioned them, the other is dotGNU (none / 0) (#62)
by Carnage4Life on Mon Nov 19, 2001 at 12:11:55 PM EST

The GNOME guys are supposedly working on a Linux version.

The GNOME guys are also the Ximian guys. The other project Ender Ryan is probably thinking about is dotGNU but from what I've seen they aren't trying to implement a Linux version of C# and the .NET Framework but instead a Linux version of .NET My Services (formerly Hailstorm).

[ Parent ]
java firmly entrenched in servers (4.50 / 2) (#13)
by rebelcool on Sun Nov 18, 2001 at 04:28:18 PM EST

Certainly, java's ability to work with any OS, and more importantly, any webserver (whether it be apache, IIS or any other) has made it easy for servlet developers to make solutions that fit a wide range of needs... i think ms will have a real difficult time convincing people who've already switched to java to switch to them. Especially given their track record of 'it only works with our own software'

COG. Build your own community. Free, easy, powerful. Demo site
[ Parent ]

This works for me. (4.20 / 5) (#15)
by Maniac_Dervish on Sun Nov 18, 2001 at 05:32:37 PM EST

It is kind of weird to just have a TOC as a story. But, given the length of the story, it is understandable. I don't really think this is MLP material, either - its too good for the section :) Thanks for a great piece of work, C4L - i'm going to be sending several of my more intelligent friends to your site to look around. :) ~Dervish

A quibble with your conclusion... (4.50 / 2) (#18)
by Jetifi on Sun Nov 18, 2001 at 06:10:02 PM EST

To quote:

... features that are missing in Java that will seem glaring in their absence once one uses them in C#, such as boxing, enumerations and pass by reference...

Now, you're right about enums. It's frickin' annoying, and any decent language should have them, they make things like contstants and what have you much more elegant and less error-prone.

However, I looked at the code snippets you used for testing pass by reference. Um. String may have been a bad choice, as it's status as an object is iffy:

There are basic types (boolean, char, byte, int, long, double, and float) that are not treated as objects and are therefore passed by value. These all have Object counterparts (Integer, Character, Boolean, Byte) for conversion operations etcetera, and these can be passed by reference.

String is the 'special case' in that it's an object, so you can do thisIsASring.startsWith("bar"), and, paradoxically, thisIsAString += anotherString etcetera, and it is also passed by value as if it were a primitive type. All other objects (arrays, Class, Object, ...) are passed by reference, as they should be, as I'm sure you know, seeing as how you're a Java developer.

So I'm afraid your testing for pass by reference the resulting conclusion and is a little misleading in that respect, unless you wanted to demonstrate the only place in Java (that I am aware of) where an object is passed by value.

With respect to multiple inheritance, I have heard it said that a strict hierarchical object structure is of course good, but that it should be voluntarily adhered to, as opposed to enforced at the syntax level. But Java has never let programmers hang themselves with their own spaghetti code :-)



You seem to have misunderstood the example (none / 0) (#20)
by Carnage4Life on Sun Nov 18, 2001 at 06:27:22 PM EST

So I'm afraid your testing for pass by reference the resulting conclusion and is a little misleading in that respect, unless you wanted to demonstrate the only place in Java (that I am aware of) where an object is passed by value.

The object reference of a strings is passed by value in Java. This means I can't alter what the original variable (i.e. the one declared outside the method and passed to it as a parameter) points to while in C# I can specify that it should be passed by reference and change what the actual original variable points at. The String example was to show how pass by reference affects objects.

PS: There was also a pass by reference example involving integers where I wrote a swap function in Java and C# and showed the differing output.

[ Parent ]
The example is loud and clear. (none / 0) (#23)
by Jetifi on Sun Nov 18, 2001 at 06:50:06 PM EST

I know that the basic types such as int, etc. are passed by value. If you want to pass integers by value, you use the 'Integer' object, not 'int'.

The String example was to show how pass by reference affects objects

This also I understand. What I am saying is that if you wish to demonstrate the pass by value/reference differences between Java and C#, the 'String' object is a bad example, because all other objects (i.e. not primitive types) will be passed by reference. String is an exception to that rule. So that (for example) Object obj; foo( obj ); will create an Object named 'obj', operate on obj, and subsequent instructions will work on the same Object, i.e. 'obj', that was operated on in foo.

Perhaps the paragragh you quoted wasn't clear enough. What I meant is: to state in your conclusion that Java does not support pass by reference, based on tests using primitive types and a special case of an object, is wrong. Java supports pass by reference, and the exceptions to these rules are primitive types, as you demonstrated, and the String object.



[ Parent ]
Java does NOT support pass by reference (none / 0) (#25)
by Carnage4Life on Sun Nov 18, 2001 at 06:59:50 PM EST

Java supports pass by reference, and the exceptions to these rules are primitive types, as you demonstrated, and the String object.

Java does not support pass by reference. Java allows you to pass object references as parameters but instead of the actual object reference being passed a copy of the value of the object reference is passed instead of a reference to the object reference. This means you can alter the object via the parameter passed in but can not alter what the actual object reference points at, in a language that supports pass by reference, you can.

[ Parent ]
yes you can. (5.00 / 1) (#26)
by rebelcool on Sun Nov 18, 2001 at 07:16:32 PM EST

i think this is what you're saying... suppose i have

Vector myVector
doStuff(myVector)
...

doStuff modifies the original vector.

COG. Build your own community. Free, easy, powerful. Demo site
[ Parent ]

That is NOT what I am saying (none / 0) (#28)
by Carnage4Life on Sun Nov 18, 2001 at 07:36:48 PM EST

This is what I am saying, given:
Vector vec = new Vector();
Vector originalRef = vec;
changeRef(vec);
There's no way in Java that vec != originalRef will ever be true, whereas in langauges that support pass by reference like C# and C++ it is possible for vec != originalRef to be true after vec is passed to the changeRef method.

[ Parent ]
ahh okay. (none / 0) (#31)
by rebelcool on Sun Nov 18, 2001 at 08:16:40 PM EST

now i see what you're talking about.

Though for the record, ive never seen that as a limitation of java... never needed it. Makes memory leaks or over-deletion of memory space impossible unlike in C++.

COG. Build your own community. Free, easy, powerful. Demo site
[ Parent ]

Pleae explain... (5.00 / 1) (#32)
by Carnage4Life on Sun Nov 18, 2001 at 08:30:22 PM EST

Though for the record, ive never seen that as a limitation of java... never needed it.

Many times I've needed to return multiple values from a method and the only solution was to create wrapper classes that held multiple objects. Also it isn't possible to create "out" parameters which is why CORBA had to resort to Holder classes in the Java implementation.

Makes memory leaks or over-deletion of memory space impossible unlike in C++.

Exactly how does this enable memory leaks or over deletion of memory? I can't see how these are justified, please explain.

[ Parent ]
wait what about this... (none / 0) (#36)
by rebelcool on Sun Nov 18, 2001 at 09:28:43 PM EST

Might just be another bad example...BUT..
Vector originalRef = (Vector) ver.clone()

Will accomplish what you just posted. It will copy the data from ver into originalRef. Modifying originalRef will only modify itself, and not ver. Look up object.clone().

COG. Build your own community. Free, easy, powerful. Demo site
[ Parent ]

You are confusing issues (none / 0) (#37)
by Carnage4Life on Sun Nov 18, 2001 at 09:46:20 PM EST

The point is that I can pass vec to a method and the when the method is done vec will point to a different object than the one from before the method call.

I can alter the contents of vec by hand to cause the same effect but it will take more code and is more error prone than an assignment would be if Java supported pass by reference.

[ Parent ]
This may help (5.00 / 2) (#38)
by forgotten gentleman on Sun Nov 18, 2001 at 10:08:59 PM EST

This article.

[ Parent ]
Java does NOT support pass by reference?! (none / 0) (#27)
by Jetifi on Sun Nov 18, 2001 at 07:30:29 PM EST


//A simple piece of code to demonstrate passing by reference in JAVA. :-)
class Test {

  //this method takes one argument: an array of string.
  //Remember that an array is an object,
  //no matter what the array contains!
  void swapTwoElementArrayOfString( String[] arrayOfString ) {

    //Here we swap elements 0 and 1.
    String temp = arrayOfString[0];
    arrayOfString[0] = arrayOfString[1];
    arrayOfString[1] = temp;

  }

  Test() {

    //Let's create an array of string!
    //Remember that an array is an object...
    String testStringArray[] = new String[2];
    testStringArray[0] = new String( "This is element Zero" );
    testStringArray[1] = new String( "This is element One" );

    //just to test, we shall print out the array now.
    System.out.println("Before calling swapTwoElementArrayOfString");

    for( int i = 0; i != testStringArray.length; i++ ) {
      System.out.println( "testStringArray[" + i + "] = " + testStringArray[i] );
    }

    //we call the method that swaps the two elements:
    swapTwoElementArrayOfString( testStringArray );

    //we print out the array elements:
    System.out.println("\nAfter calling swapTwoElementArrayOfString");

    for( int i = 0; i != testStringArray.length; i++ ) {
      System.out.println( "testStringArray[" + i + "] = " + testStringArray[i] );
    }
  }


  public static void main( String[] args ) {
    new Test();
  }
}

Now let us look at sample output:

Before calling swapTwoElementArrayOfString
testStringArray[0] = This is element Zero
testStringArray[1] = This is element One

After calling swapTwoElementArrayOfString
testStringArray[0] = This is element One
testStringArray[1] = This is element Zero

To quote you again:

Java allows you to pass object references as parameters but instead of the actual object reference being passed a copy of the value of the object reference is passed instead of a reference to the object reference.

Well, as the above code demonstrates, there is no copy being made of the variable testStringArray when it was passed to swapTwoElementArrayOfString.

This means you can alter the object via the parameter passed in but can not alter what the actual object reference points at, in a language that supports pass by reference, you can.

And as Java is a language that supports pass by reference, you can alter any object you pass to a function, be it an Array, Integer, Object, Class, Vector, Hashtable... as demonstrated by the above snippet of code. Try it yourself if you don't believe me!

I don't mean to sound nasty, but how much research did you actually do for that honking big document? Missing something as fundamental as this is pretty whacked. I think I should go through the rest of it, and point the rest of the mistakes. Care to engage me as a fact-checking consultant? :-)

I would be interested in reading your reply. If not for the rebuttal, then just for the entertainment value :-)



[ Parent ]
That isn't pass by reference (5.00 / 2) (#29)
by Carnage4Life on Sun Nov 18, 2001 at 07:41:37 PM EST

In Java, the following method does nothing
void changeMe(String[] foo){

foo = {"A", "B", "C"};
}
to the array passed in because Java does not support pass by reference. In C++ and C#, the original array can be made to now be an array containing the strings A, B and C. This is what is meant by pass by reference.

[ Parent ]
To be continued! (none / 0) (#30)
by Jetifi on Sun Nov 18, 2001 at 08:01:31 PM EST

It's 01:53 here, and I have work tomorrow. I have the nasty feeling the last two <p>'s are going to come back and bite me on the ass, but so be it. Until then... :-)



[ Parent ]
/me eats crow, damnit. (4.66 / 3) (#33)
by Jetifi on Sun Nov 18, 2001 at 08:30:33 PM EST

Well now I feel stupid. So it turns out java handles objects by reference, and passes them by (wait for it...) value. An important distinction which I didn't make. Whoops.

At which point my previous posts in this thread look pretty dumb, if not arrogant/insulting(sorry 'bout dat), but such is life, live and learn, etc. They'll only be in the Google cache for the next ten years...



[ Parent ]
Nomenclature difference (5.00 / 1) (#49)
by srichman on Mon Nov 19, 2001 at 10:28:13 AM EST

I'm sorry, but I feel you're just misusing the phrase "pass by reference". More strongly, I feel you're wrong.

I consider pass by value to be what C/C++ does when you pass an object to a function: it makes a complete copy of the object on the stack so no changes to the object by the callee are visible in the caller:

struct foo { int i; };
void func(foo f) {
f.i = 3;
}
Here, func's change won't be visible to the caller. This is what I call pass by value. Now, let's look at this:
void func(foo& f) {
f.i = 3;
}
Here, func's change is visible to the caller, exactly as in Java. This is what I call pass by reference. Now, let's assign a whole new object to f:
void func(foo& f) {
foo f2 = {5};
f = f2;
}
In C++, by default this just does a field-by-field copy from f2 to f, i.e., it's equivalent to:
void func(foo& f) {
foo f2 = {5};
memcpy(f, f2, sizeof(foo));
}
This is sorta bad, since it's often not what people want to have happen in OO programming. Therefore, C++ allows the programmer to define operator= to copy foos in some more sane way. Java doesn't allow operator overloading, so you would have to name your copy method something else, but it should be clear that a Java method named copyFrom or copyTo method would work no differently.

Now lets say you want a C++ function to make an variable in the caller refer to a different object than it did before the call, e.g.:

void func2() {
foo a, b;
// somehow call func3 to make the variable a
// refer to the object currently called b
}
The goal is to make the variable a refer to the same object as the variable b. Maybe you want all changes via a to be reflected in b, or maybe foos are just 10 bazillion byte structures and you can't afford a memcpy. The point is, as I've declared the variables, you will never ever ever ever be able to write such a function func3 in C++ and call it in such a way that it will do what you want. This is just as in Java. Why? The reason is because a cannot be reseated. You would have to change the definition of a to make it a foo* in order for this to be possible. But this has nothing to do with call by reference versus call by value; the point is you are changing the type of a to a new type, to a pointer type. You can do the same thing in Java and achieve the same effect:
class Pointer {
public Object o;
public Pointer(Object o) { this.o = o; }
}
void func2() {
Pointer a = new Pointer(new foo());
foo b = new foo();
func3(a, b);
}
This comes at the cost of compile-time type safety. That is because Java doesn't currently have generic types (Pointer<foo>) but they're coming (in the next version???).

[ Parent ]
Or, immutable (none / 0) (#50)
by srichman on Mon Nov 19, 2001 at 10:31:30 AM EST

Maybe you want all changes via a to be reflected in b, or maybe foos are just 10 bazillion byte structures and you can't afford a memcpy.
I should have also mentioned, "or maybe foo is an immutable type (as String is in Java)."

[ Parent ]
See spcmanspiff's comment (none / 0) (#77)
by Carnage4Life on Mon Nov 19, 2001 at 02:04:59 PM EST

I was about to respond when I saw spcmanspiff's excellent comment and I decided that is all the response needed and hopefully this clarifies the discussion.

[ Parent ]
Link (none / 0) (#98)
by srichman on Mon Nov 19, 2001 at 08:23:22 PM EST

Your link to the comment seems to be broken. This one works.
I was about to respond when I saw spcmanspiff's excellent comment and I decided that is all the response needed and hopefully this clarifies the discussion.
Not to be too egotistical, but his comment seems to say pretty much the same thing as mine. I don't know... I kinda like that point that reseating variables (in C++; not C#) requires a different type, and Java can do the same thing if you give it a new type.

[ Parent ]
Um .... (5.00 / 5) (#67)
by spcmanspiff on Mon Nov 19, 2001 at 12:40:01 PM EST

This is an area of some confusion in Java.

The correct answer is that everyone here is right: Java works exclusively with its objects by reference, so passing objects around always works by reference.

However, arguments themselves cannot be 're-pointed' at any other object because the reference is passed by value. It's analgous to this (In C using pointers to make it all explicit):

int swap(int* a, int* b) {
   int * tmp;
   tmp = a;
   a = b;
   b = tmp;
} // That did a whole lot of NOTHING because the references(pointers) were passed by value on the stack, and changing what they point at is only in scope for this function.

int swap(int* a, int* b) {
   int tmp;
   tmp = *a;
   *a = *b;
   *b = tmp;
} // This swapped the _values_, but each pointer is still pointing at the same memory location -- in Java, this would be like calling a method a.copyFrom(b) or some such.

int swap(int** a, int** b) {
   int* tmp;
   tmp = *a;
   *a = *b;
   *b = tmp;
} // This version would swap the pointers around so a would now point at b and b at a -- not only are you passing by reference, but you're passing your references by reference so they can be changed outside of scope.

Java works like (1) and (2), but what you (Carnage4Life) are talking about is more like (3)... It's all pass-by-reference, but the references themselves are passed by value in Java and by reference in C# -- according to what you've been saying; I've never used C#. Also, as a side note, C++ references act differently from both of these -- They're exactly like (1), except that all operations on the reference type are automatically 'de-referenced' and act on the pointed-to object. (Maybe C# does this, instead... hard to say!) So { int& a; a = 23 } is the same as { int*a; *a = 23 } ...

Pheew! (Not responsible for it's-too-damn-early errors :)



[ Parent ]

Definition of "Pass by Reference" (5.00 / 1) (#34)
by Delirium on Sun Nov 18, 2001 at 08:54:38 PM EST

I think the confusion is over the definition of the term "pass by reference." In the strict sense that you're using it, neither Java nor C have pass by reference, while C++ and C# do. However, many C programmers refer to the following as "passing x by reference":

SomeObject x;
someFunc(&x);
.
.
.
void someFunc(SomeObject *ptr) {
   /* do stuff */
}

While as you correctly pointed out it's strictly speaking "passing a reference to x by value." But in reality, the two aren't really very different - most (all?) C++ compilers implement passing by reference internally as passing references by value (I think). So with this looser definition of "pass by reference," Java has passing by reference in the same sense C does - you can pass references to objects by value, which is functionally very similar to passing objects by reference in most cases.

[ Parent ]

Java Strings are passed by reference, too! (none / 0) (#126)
by Shpongle Spore on Tue Nov 20, 2001 at 01:26:45 PM EST

...the 'String' object is a bad example, because all other objects (i.e. not primitive types) will be passed by reference. String is an exception to that rule.

Actually there's no exception for String objects; they are passed by reference* just like any other object, but since String objects are immutable (i.e. no method can change the value of an existing string) it appears as if they were passed by value. You can get the same effect by writing your own immutable objects.

String objects appear to me mutable because of the += operator, but this actually creates a new String object rather than modifying and existing one. If you look at the methods of the String class you'll find that none of them correspond to the += operator.

*I'm not making the distinction others in this thread are making between passing by reference and passing a reference by value.


__
I wish I was in Austin, at the Chili Parlor bar,
drinking 'Mad Dog' margaritas and not caring where you are
[ Parent ]
Strings in Java (5.00 / 3) (#21)
by Matrix on Sun Nov 18, 2001 at 06:29:10 PM EST

Actually, its worth noting that Strings ARE just like every other object in Java, even with the ability to do thisIsAString += "Foo";. Why? Because Strings are immutable. So thisIsAString += "foo"; doesn't really concatenate foo to thisIsAString. It creates a copy of the string, concatenates foo to that, and assigns it to thisIsAString... Which doesn't modify, say, a String passed into some function.


Matrix
"...Pulling together is the aim of despotism and tyranny. Free men pull in all kinds of directions. It's the only way to make progress."
- Lord Vetinari, pg 312 of the Truth, a Discworld novel by Terry Pratchett
[ Parent ]

Yup, point taken. (none / 0) (#24)
by Jetifi on Sun Nov 18, 2001 at 06:53:33 PM EST

You're right. string1 += string2; is basically a syntactical shortcut for something like string1 = string1.concat(string2);

My mistake.



[ Parent ]
Strings (none / 0) (#43)
by Matrix on Mon Nov 19, 2001 at 08:38:44 AM EST

Well, you were right that strings are handled as a wierd special case. (Including where the toString() function is made use of) It is one of the things I dislike about Java, but I think the next major revision is planned to include tools so one can do the same thing with one's own classes.


Matrix
"...Pulling together is the aim of despotism and tyranny. Free men pull in all kinds of directions. It's the only way to make progress."
- Lord Vetinari, pg 312 of the Truth, a Discworld novel by Terry Pratchett
[ Parent ]

String concatnation (none / 0) (#46)
by hardburn on Mon Nov 19, 2001 at 10:06:46 AM EST

thisIsAString += anotherString

Doing string concatnation in Java this way has always generated compiling errors for me. It could be that I usually use Jikes for development instead of Javac and Jikes has some bugs here. I always have to write the above as:

thisIsAString = thisIsAString + anotherString;

Which works fine. The += operators works for other primitive types just fine (ints, shorts, etc.), just not Strings.

If I was at my home computer right now, I could give you specific examples, but I'm not, so I can't.


----
while($story = K5::Story->new()) { $story->vote(-1) if($story->section() == $POLITICS); }


[ Parent ]
beautiful.... (4.50 / 6) (#40)
by pb on Mon Nov 19, 2001 at 02:06:48 AM EST

What a lovely, in-depth comparison. I feel like I learned something from just the index, in fact.

The truth is, I haven't read it all yet, but so far, I like it. And I like C# just a teeny bit more now, mostly for the scoping and namespace stuff I just read about.

I remember ranting about that same very issue, and it's nice to see the protected keyword actually *protect* something again. Although, IIRC, Java defaults to "friendly" if you don't specify anything, not "protected". ("friendly" is just package scope, and a dumb name to boot; I think it won out in favor of "useless")

Also, I liked the keyword table; it looks like C# stole keywords from *everybody*, not just Pascal. (I see some Perl, Lisp, and Scheme influence as well)

Oh, and the default capitalization conventions? I think it's brain-damaged. I mean, for C# and Java both. Maybe it helps some people, but it just pisses me off, and makes me stick to lowercase. Then again, I also hate Hungarian notation... :)

Anyhow, +1, FP, and your articles are one of the few things I still *read* on Kuro5hin. Laters...
---
"See what the drooling, ravening, flesh-eating hordes^W^W^W^WKuro5hin.org readers have to say."
-- pwhysall
Good stuff (4.00 / 1) (#44)
by ggeens on Mon Nov 19, 2001 at 08:55:55 AM EST

I read a similar article on TheServerSide.com a while ago, with pretty much the same conclusions.

The first articles I read about C# indicated that it was basically a Java-clone. After reading the in-depth comparision, I'd say it's a (slightly) better Java.

I am currently employed as a Java programmer, so I'm probably a bit biased. I also prefer to stay with J2EE because I have had a rather bad experience with Microsoft development tools.


L'enfer, c'est les huîtres.


I disagree with some "completely different&qu (4.25 / 4) (#45)
by srichman on Mon Nov 19, 2001 at 09:48:15 AM EST

I haven't read the whole thing yet, but there are some things in the Now For Something Completely Different: This section describes language features and concepts that exist in C# and have no Java counterpart. section that I completely disagree with.

Run Time Type Identification (as operator)
Java most definitely has runtime type identification. What do you think the instanceof operator is for? What do you think the Object.getClass() method does? The java.lang.Class class offers very, very rich RTI, including completely introspection of methods, ctors, and fields.

The C# as operator is completely analogous to C++'s dynamic_cast construct. The semantics of the as operator are that it attempts to perform an explict cast to a type and returns null if the operation was unsuccessful.
Yeah, in Java it's called casting:
try {
   SubClass o = (SubClass) superClassInstance;
} catch (ClassCastException cce) {
   ...
}
Pass by Reference
In Java the arguments to a method are passed by value meaning that a method operates on copies of the items passed to it instead of on the actual items.
Your examples are all correct, and the difference between Java and C# in this regard is real, but your nomenclature is a bit off. Java is not pass by value; it is pass by reference for all types except primities (char, int, et al.). In pass by value, if I pass you an object and you modify it, the changes aren't visible in my copy of the object: a whole new copy of the object is made (usually on the stack) for the callee. C++ uses call by value by default:
In C++:
struct foo { int bar; };
void func(foo f) {
   f.bar = 42;
}
void print() {
   foo f;
   f.bar = 0;
   func(f);
   // prints 0, not 42:
   cout << f.bar << endl;
}
In C++, this prints 0; in Java, it would print 42. You're incorrectly referring to reseating the caller's reference (the object that a variable name in the caller points to) as pass by reference. What you're talking about would, in C, be a function that takes a double pointer.
In C#, as in C++ and in a sense C, it is possible to specify that the arguments to a method actually be references to the items being passed to the method instead of copies.
Why "in a sense" C? Why is C any less capable than C++ in this regard? If you're thinking of C++ references ("&"), then you're confused. A C++ reference won't give you the ability to reseat a variable in the caller. For instance, if you changed the above example so that func was defined as void func(foo& f), then it would be the same as in Java: the 42 would be visible by the caller. If you assigned some other foo object to f within func (rather than assigning to a member of f as the example is now), then the change would not be visible in print. To make that work, func would have to be defined as void func(foo*& f) or as void func(foo** f), and print would have to define a foo pointer rather than a foo and pass that pointer or a pointer to that pointer (respectively).

We just went over this in another thread (none / 0) (#47)
by Carnage4Life on Mon Nov 19, 2001 at 10:25:34 AM EST

Java most definitely has runtime type identification. What do you think the instanceof operator is for? What do you think the Object.getClass() method does? The java.lang.Class class offers very, very rich RTI, including completely introspection of methods, ctors, and fields.

I know about the instanceof operator and in fact I mention that the C# is operator is the same as the Java instanceof operator and I also mention similarities and differences between reflection in both languages. The fact is that Java does not have anything analogous to C#'s as operator or C++'s dynamic_cast.

Your examples are all correct, and the difference between Java and C# in this regard is real, but your nomenclature is a bit off. Java is not pass by value; it is pass by reference for all types except primities (char, int, et al.). In pass by value, if I pass you an object and you modify it, the changes aren't visible in my copy of the object: a whole new copy of the object is made (usually on the stack) for the callee. C++ uses call by value by default:

We just went over this in another thread. Java does not have pass by value. Instead of repeating myself here some links,
  1. Javaworld article that explains how Java does NOT have pass by reference
  2. Sample code that highlights how Java has no pass by reference
  3. Another piece of code that highlights how Java has no pass by reference


[ Parent ]
I meant Java does not have pass by reference (none / 0) (#52)
by Carnage4Life on Mon Nov 19, 2001 at 10:34:31 AM EST

We just went over this in another thread. Java does not have pass by value. Instead of repeating myself here some links,

This should read:
We just went over this in another thread. Java does not have pass by reference. Instead of repeating myself here some links,


[ Parent ]
Value/reference (none / 0) (#53)
by srichman on Mon Nov 19, 2001 at 10:36:10 AM EST

Sorry about not posting my value/reference thing in the other thread. Please see by subsequent post in that thread that argues that you are wrong.

[ Parent ]
RTI (none / 0) (#55)
by srichman on Mon Nov 19, 2001 at 10:50:00 AM EST

The fact is that Java does not have anything analogous to C#'s as operator or C++'s dynamic_cast.
I'm sorry, but I still don't understand what you're talking about. Why is standard Java casting any different from as or dynamic_cast? What is wrong with my example from my previous post? I'll restate it here:
try {
SubClass o = (SubClass) superClassInstance;
} catch (ClassCastException cce) {
...
}
Do you not like that fact that it throws rather than returning null? I should remind you that that's exactly what C++ does when a dynamic_cast of a reference fails (throwing bad_cast).

[ Parent ]
dynamic_cast of refs (none / 0) (#64)
by srichman on Mon Nov 19, 2001 at 12:25:07 PM EST

I should remind you that that's exactly what C++ does when a dynamic_cast of a reference fails...
Sorry, what I meant to say was: "I should remind you that that's exactly what C++ does when a dynamic_cast to a reference fails..."

[ Parent ]
Be careful .... (5.00 / 2) (#84)
by spcmanspiff on Mon Nov 19, 2001 at 04:52:01 PM EST

Java _does_ pass objects by reference, since the *only* way to refer to an object in Java is via a reference.

This means that if you have foo(Object a) { }; then anything foo does to a happens not to its own, local copy of a, but to the same instance of a that was passed to it.

Rephrasing, repeating:

Pass-by-value would mean that a new _instance_ of a would be created on the stack, foo() would operate on that new, locally-scoped copy of a that exists only during the function call, then return.

In java, since objects are *always* accessed via a reference, all object functions arguments are pass-by-reference. Foo's reference a points to the same instnace a that was passed; not a stack copy as would be created in pass-by-value.

Now, here's where the confusion comes in:
foo() does not has its own locally-scoped instance of a, but it _does_ have its own locally-scoped reference to a.

The code examples you link to fail not because they attempt to modify the referenced object (which works fine, as others have pointed out) but because they modify the reference itself. This fails because the reference lives on the call stack and goes out of scope as soon as the function returns.

In C or C++, this is exactly analagous to passing a pointer as an argument. Modifying the pointed-to entity works fine, but changes to the pointer itself don't last because it is limited to function scope.

Most people, when they say "pass by reference," refer to the following behavior:
- A function-scope, local copy of the argument is not created on the stack (saving time and memory for any non-trivially-sized objects).
- Changes made to the argument (the object, not the reference) take effect on the same instance passed to the function (again, not a copy of the instance that lives on the stack).

Just because the reference itself lives on the stack and has only function scope does not mean that java lacks pass-by-reference! Pointers in C and references in C++ exhibit the exact same behavior, with the addition in C++ that you cannot change the reference (re-point it at something else) and dereferencing is a transparent operation.


[ Parent ]
a good way to look at this (none / 0) (#113)
by suntzu on Tue Nov 20, 2001 at 12:38:18 AM EST

sorry to be nitpicky, but java really doesn't pass by reference. all of this is much easier to understand if you forget the common lie "java does not use pointers." really, java does not manipulate pointers, but it uses them. you can't manually assign addresses, and you can't do pointer arithmetic, but they're there. when you create an object in java, what do you do? this:

Object foo = new Object();

in the above line of code, you created a pointer to an instance of an Object named foo, and then you allocated an object and assigned it to that pointer. so, when you pass foo to a function (or "method" or whatever), you passing the variable foo, by value, to the function. the pointed to value is manipulated. if you could pass by reference, you'd be able to initialize objects without returning them, because you could just pass in a pointer to the pointer and change what's being pointed to to newly allocated memory, a la C (keep in mind, C only passes by value. when you want to get pass by reference behavior, you pass a pointer to the parameter to be manipulated, and dereference it in the function. c++'s & modifier when used in formal function parameters allows true pass by reference behavior.).



[ Parent ]
Agreed, sort of. (none / 0) (#119)
by spcmanspiff on Tue Nov 20, 2001 at 11:35:08 AM EST

This other post I wrote is a little bit less rambly, and quite similar to what I think you're saying. Just substitute "reference" for "pointer" in your post (or vice versa in my post), since there's very little practical difference between the two, anyway.

The way I think about it is that all objects in java exist only as references, with '.' being the dereferencing operator.

Now, about 'Java does not pass by references', well ... when you call a function with an object, you pass a reference to that object into the fucnction, right? How is that not pass by reference?

Any changes made to the object via methods or properties take effect, as you would expect, to the instance of the object you passed, not some function-scope stack copy. Pass by reference, no?

The trick is that any changes you make to the reference are discarded because the reference is passed on the stack and goes out of scope when the function returns.

Like you said, this is exactly like passing a pointer in C, only implicit. That doesn't mean it's not pass-by-reference; the important behavior of passing stuff by reference is still there -- the difference is that you can't change the reference itself. (Which holds for C++ references as well as C pointers passed into functions. Like you pointed out, you'd need to pass a pointer to a pointer in order to modify it from within a function).

I guess the important distinction is whether one is talking about the object instance (the usual case) in which case it is absolutely true that pass-by-reference is happening, or the Java variable ("pointer", reference, whatever) itself, in which case it is passed by value.

Finally, as a side note: C++'s & operator has a few effects: One, it passes by memory address rather than value. Two, dereferencing is implicit (anything you do to the reference really happens to the referenced object). And three, you can't 're-point' the reference to a different memory address -- a) you're not allowed to, b) the reference only has function scope since it was passed-by-value (memory address) on the stack, and c) because of implicit dereferencing you can't really refer to the reference properly anyway. Implicit dereferencing is the only place where C++ references really differ from java object variables off the top of my head.

Okay, back to work now. *sigh* ... (I'm being forced to do Visual Basic code for MS Access... Nooooooooooooooo!)



[ Parent ]

Values, RTTI (none / 0) (#48)
by forgotten gentleman on Mon Nov 19, 2001 at 10:26:18 AM EST

Your examples are all correct, and the difference between Java and C# in this regard is real, but your nomenclature is a bit off. Java is not pass by value
Java is in fact "pass by value." When dealing with objects, it passes references by value. Take a look below at the very long thread for more explanation.

I don't like the confusion for programmers coming from C/C++ either, but it reduces side effects.

I think you're right about RTTI. Maybe the author could explain if we're wrong.

[ Parent ]

Pass by value/reference (none / 0) (#51)
by srichman on Mon Nov 19, 2001 at 10:34:11 AM EST

As far as not posting under the thread below, yeah, I'm an idiot. A cursory read of the top-level comment made me think it was about enums, not the value/reference thing. Please read my more detailed argument about the value/reference debate that I subsequently posted in the thread below.

[ Parent ]
RTTI (none / 0) (#54)
by forgotten gentleman on Mon Nov 19, 2001 at 10:39:22 AM EST

I see now. The "as" operator is far cleaner than testing with instanceof and using a cast. It's debatable whether that's "something completely different", but definitely a large improvement, since I dislike making conditional branches depending on the results of an instanceof.

[ Parent ]
lexicon and semantics are boring. (none / 0) (#57)
by jforan on Mon Nov 19, 2001 at 10:55:32 AM EST

I looked quickly over the "differences" but coudln't find much more than semantic differences. I didn't notice what I think is one of the most important differences... the difference between the java byte code and the C# (or more specifically the dot-net) intermediary language. I understand that while the Java byte code is very assembly like, the dot-net "byte code" is basically the parse tree that is created in the first step of compilation, enabling for simple(r) transitions back to code from the intermediary language. This also enables simpler code to code conversioning; if microsoft can go backwards from this intermediary language to C#, and they can go from VB or C++ or Java to the intermediary language, then conversion of code between languages (or at least TO C#) becomes fairly simple.

Anybody here know about this more than me?
What about other implications of this?

These questions seem much more important than the semantics and lexicon of c# and java.

Jeff
I hops to be barley workin'.
CIL's bytecodes are not that different from JVM's (none / 0) (#66)
by alder on Mon Nov 19, 2001 at 12:37:24 PM EST

For a reference you may want to check "Common Language Infrastructure (CLI ) - Partition III CIL Instruction Set", it's in Microsoft.NET/FrameworkSDK/Tool Developers Guide/docs/Partition III CIL.doc if you have .NET SDK installed. If you are familiar with JVM bytecodes you'll see that the CIL bytecodes most probably have ancestry in MS JVM, i.e. in Java bytecodes (the most interesting is the bytecode table on page 7). Though they are now reworked to reflect more ambitious goals.

Parsing trees are used in Juice which is Oberon's "VM". Another thing is that it's not that difficult to build AST from bytecode represenation, provided there are metadata attached to them, and we known they are there :-)

[ Parent ]

IL vs. Java byte codes (none / 0) (#69)
by Carnage4Life on Mon Nov 19, 2001 at 01:09:19 PM EST

the difference between the java byte code and the C# (or more specifically the dot-net) intermediary language. I understand that while the Java byte code is very assembly like, the dot-net "byte code" is basically the parse tree that is created in the first step of compilation, enabling for simple(r) transitions back to code from the intermediary language.

From what I've seen IL is similar to Java byte codes except that IL was designed from the start to support lots of languages besides C# while Java byte codes were designed with Java in mind and nothing else. For instance IL has support for tail recursion.

Although an important distinction is that while Java byte codes are interpreted, IL is compiled on loading to native code. Here is an article on C# Help that tries to explain the .NET Framework to Java developers

This also enables simpler code to code conversioning; if microsoft can go backwards from this intermediary language to C#, and they can go from VB or C++ or Java to the intermediary language, then conversion of code between languages (or at least TO C#) becomes fairly simple.

There have been decompilers built that convert IL back to code but this is more because of the nature of IL and the amount of metadata in assemblies than IL being similar to a parse tree as opposed to an actual instruction set.

[ Parent ]
Questions about IL (none / 0) (#81)
by ttfkam on Mon Nov 19, 2001 at 03:45:43 PM EST

While specifying tail recursion in IL could be a good thing, is it more of a hint or does it make a measurable difference. In other words, will it make my code faster or do most modern JVMs simply recognize certain patterns in bytecodes and convert them to tail recursion algorithms silently?

I guess the proof would be in the benchmarks.

With regards to "Java byte codes are interpreted, IL is compiled on loading," while I read the linked article, this point was still not clear. They both have a unified datastructure that must be parsed and converted to native code in memory. With regards to CLR's ability on Windows machines to compile at installation time, this could be a good thing. But how is inherently better than the use of gcj (GCC's Java front end) to compile Java class files to native binaries? Is it just a matter of convenience where a Linux distro could (for example) package gcj with the default install and write a JAR to ELF binary conversion script?

-----

One of the great things about Java was in fact the reduced number of ways to do things. When you are getting things done, many times this is an asset. It helps reduce the overall complexity of an assignment -- makes it easier to visualize sometimes. This seems to have been missed in your writeup.

While C# may have the "unsafe" keyword, how is it any great advantage over Java's "native" keyword? Hear me out here. The point of "unsafe" is three-fold: letting the programmer twiddle things that aren't usually accessible (or fast enough), letting the compiler know that you accept the risks, and to let other programmers know that you are doing something potentially hazardous. The "native" keyword in Java allows access to the system/memory that is not usually accessible (or fast enough), lets the compiler know that things are being twiddled outside of the protections of the JVM, and is a visual cue to other programmers that something potentially hazardous is going on off the beaten trail.

In fact, it could be argued that with Java, this separation is made much clearer for everyone involved -- the unsafe code is completely detached and basically impossible to mistake for "safe" code.

The additions of C# make it closer to the complexity level of C++ and further from Java. While C# may be used like Java (and made just as simple), so can C++. The issue that many people have with C++ is that due to the amount of features available to the programmer, it is an unwieldy language that is difficult to master.

Allocate on the stack or the heap? Java answers the question for you and rightly asserts that most of the time, it doesn't matter. When it does matter, there's always "native."

In fact, the Java Hotspot compiler was made with the premise that code that runs for extended periods of time will have changing hotspots in code and different servers will have different performance characteristics. Does .NET have a comparable answer to this or is another "time will tell?"

C# has extra features which adds to complexity, but lacks features such as C++ templates that allow an even greater flexibility. The next version of Java (1.5) is rumored to have template support. Time will tell whether this will make it that much better of a language or push it too much toward C++ complexity, but there is something to be said for greater simplicity in the language.

If I'm made in God's image then God needs to lay off the corn chips and onion dip. Get some exercise, God! - Tatarigami
[ Parent ]
Not true at all (none / 0) (#71)
by core10k on Mon Nov 19, 2001 at 01:19:39 PM EST

And if you need convincing, write a simple program in Java, compile it, and then run the program 'JAD' (found on the internet with google easily) on the resulting class file.

About the only thing that gets stripped that I've noticed so far is mathematical constants. (i.e. '( 4 + ( 3 * 2 ) )' in the original Java file will be stripped down to '10' in the resulting decompilation.

What the heck, here's an example:( from some u(god awful ;-) ) code of mine). Please forgive the lack of line breaks... Kuro5hin doesn't seem to support the PRE tag.

----TCRectangle.java---

/******** TCRectangle.java *********/ package tc.Math; import java.awt.*; public class TCRectangle { public Point position; public Dimension size; public TCRectangle() { position = new Point( 0, 0 ); size = new Dimension( 0, 0 ); } public TCRectangle( Point aPos, Dimension aSize ) { position = new Point( aPos ); size = new Dimension( aSize ); } public TCRectangle( DblPoint aPos, Dimension aSize ) { position = new Point( (int)aPos.x,(int) aPos.y ); size = new Dimension( aSize ); } }

---------

]javac tc/Math/TCRectangle.java

]jad tc/Math/TCRectangle.class

Parsing tc/Math/TCRectangle.class... Generating TCRectangle.jad

--------TCRectangle.jad-------------

// Decompiled by Jad v1.5.7f. Copyright 2000 Pavel Kouznetsov. // Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html // Decompiler options: packimports(3) // Source File Name: TCRectangle.java package tc.Math; import java.awt.Dimension; import java.awt.Point; // Referenced classes of package tc.Math: // DblPoint public class TCRectangle { public TCRectangle() { position = new Point(0, 0); size = new Dimension(0, 0); } public TCRectangle(Point point, Dimension dimension) { position = new Point(point); size = new Dimension(dimension); } public TCRectangle(DblPoint dblpoint, Dimension dimension) { position = new Point((int)dblpoint.x, (int)dblpoint.y); size = new Dimension(dimension); } public Point position; public Dimension size; }



[ Parent ]
wow, you're hard core (5.00 / 1) (#116)
by jacob on Tue Nov 20, 2001 at 01:15:41 AM EST

To my feeble brain, the syntax and semantics of a language are pretty darned important. I guess you're the sort of person who looks at Prolog and GW-BASIC and says, "Bah, just syntactic and semantic differences. Whatever. The same thing for all intents and purposes."

I bow before your superior nonchalance.



--
"it's not rocket science" right right insofar as rocket science is boring

--Iced_Up

[ Parent ]
Do more research, try again. (none / 0) (#58)
by Rift on Mon Nov 19, 2001 at 11:21:18 AM EST

After reading the value / reference calling thread, I checked out the section "Wish you were here". And found two errors:

  1. Extensions: Unless you are modifying the java interpreter, even the 'core' libraries (on my platform, anyway) must be in the classpath. So 'extending' the language consists of putting a jar file in the classpath. C# has the same thing, called the global assembly cache. - now, before you say, yes, but you have to add a reference to it, I want you to remember that you have to reference every assembly you use, including System.dll - there is a (customisable) set of references appended by default by the c# compiler.
  2. Dynamic class loading: you skip over Reflection everywhere, as far as I can see, and here is no exception: I have written an app that finds all the .dll's in a directory, instatiates each class in those dll's that implement an interface or have a certain (custom) attribute, and then calls methods and responds to events from those classes. It is possible, using reflection's emit classes to have your code write those classes before calling them. I have used this same thing to accept url's of web services to call them dynamically (for testing). How is it possible you missed something so major to the language? (check out Assembly.Load(), Object.GetType(), and Type.Invoke..)

It makes me wonder if I can trust the research done on the rest of the article. Thanks for the effort, much of it is very well written... but if I can't trust it all, it's not much use to me.

--Rift
A pen is to a car what a meteor is to a _____
Maybe you should have read more carefully (5.00 / 1) (#65)
by Carnage4Life on Mon Nov 19, 2001 at 12:29:57 PM EST

Extensions: Unless you are modifying the java interpreter, even the 'core' libraries (on my platform, anyway) must be in the classpath. So 'extending' the language consists of putting a jar file in the classpath. C# has the same thing, called the global assembly cache. - now, before you say, yes, but you have to add a reference to it, I want you to remember that you have to reference every assembly you use, including System.dll - there is a (customisable) set of references appended by default by the c# compiler.

Extensions are a way of avoiding explicitly putting classes in your CLASSPATH, if the JVM you use still requires you to put rt.jar in your CLASSPATH then it is broken. A C# analog would be a mechanism to avoid having to reference certain assemblies during compilation. The fact that the unit of code distribution in Java is a class versus an assembly or .EXE in makes it a case of comparing apples to oranges in a runtime sense.

Dynamic class loading: you skip over Reflection everywhere, as far as I can see, and here is no exception: I have written an app that finds all the .dll's in a directory, instatiates each class in those dll's that implement an interface or have a certain (custom) attribute, and then calls methods and responds to events from those classes. It is possible, using reflection's emit classes to have your code write those classes before calling them. I have used this same thing to accept url's of web services to call them dynamically (for testing). How is it possible you missed something so major to the language? (check out Assembly.Load(), Object.GetType(), and Type.Invoke..)

Reflection is not dynamic class loading and from the example you describe it looks like you don't understand the difference. .NET's lack of an analog to dynamic class loading is a fact that has been confirmed by people working at MSFT a few of whom read the article before I posted to kuro5hin. Dynamic class loading happens automatically and is handled by the JVM while using reflection explicitly is exactly that using an explicit mechanism to simulate dynamic class loading

I skipped over Reflection? I think not.

[ Parent ]
ext? (none / 0) (#86)
by ttfkam on Mon Nov 19, 2001 at 05:12:10 PM EST

"A C# analog would be a mechanism to avoid having to reference certain assemblies during compilation."

What about the jre/lib/ext? Any jar files that you put in that directory are automatically available to the JVM during compilation and runtime without an explicit classpath entry.

The only problems I can see with that are per user defaults, but if we get into multi-user environments and Windows, things will digress rapidly.

If I'm made in God's image then God needs to lay off the corn chips and onion dip. Get some exercise, God! - Tatarigami
[ Parent ]
That's what we are talking about (none / 0) (#94)
by Carnage4Life on Mon Nov 19, 2001 at 06:23:50 PM EST

What about the jre/lib/ext? Any jar files that you put in that directory are automatically available to the JVM during compilation and runtime without an explicit classpath entry.

This is the Extension mechanism that we are talking about. Java has it and C# doesn't.

[ Parent ]
Perhaps I should but... (none / 0) (#95)
by Rift on Mon Nov 19, 2001 at 06:48:46 PM EST

Both JVM's I use need to have any jar either in the classpath or in the same dir (or subdir) as the java interpreter binary, or the lib/jre, etc dirs. Putting it in the these dir's is no different than copying it to the classpath in my mind, as that structure is simply an implied permanent (and systemwide) classpath - like the global assembly cache.

The main difference here, that you seem to be pointing out is that you have to explicitly reference everything you want to use in c# - but remember, this is true of Everything, even the core runtime (System) namespaces - so perhaps that (and not language extension) is your point.)

However, I can add classes to the System namespace.

I do agree that comparing the units of distribution is unwise, but in terms of extending the language, I think this is not an issue.

So - yes, Java has that, but (in my perhaps wrong mind), it's not really language extension issue, but simply a major difference in how compile-time binding is performed. (explicit references vs. implicit and explict references, you might say)


Perhaps I do misunderstand dynamic class loading vs. Runtime class loading. I will look into it before shouting my ignorance.

--Rift
A pen is to a car what a meteor is to a _____
[ Parent ]
Do more research, try again. (2.66 / 3) (#59)
by Rift on Mon Nov 19, 2001 at 11:21:38 AM EST

After reading the value / reference calling thread, I checked out the section "Wish you were here". And found two errors:

  1. Extensions: Unless you are modifying the java interpreter, even the 'core' libraries (on my platform, anyway) must be in the classpath. So 'extending' the language consists of putting a jar file in the classpath. C# has the same thing, called the global assembly cache. - now, before you say, yes, but you have to add a reference to it, I want you to remember that you have to reference every assembly you use, including System.dll - there is a (customisable) set of references appended by default by the c# compiler.
  2. Dynamic class loading: you skip over Reflection everywhere, as far as I can see, and here is no exception: I have written an app that finds all the .dll's in a directory, instatiates each class in those dll's that implement an interface or have a certain (custom) attribute, and then calls methods and responds to events from those classes. It is possible, using reflection's emit classes to have your code write those classes before calling them. I have used this same thing to accept url's of web services to call them dynamically (for testing). How is it possible you missed something so major to the language? (check out Assembly.Load(), Object.GetType(), and Type.Invoke..)

It makes me wonder if I can trust the research done on the rest of the article. Thanks for the effort, much of it is very well written... but if I can't trust it all, it's not much use to me.

--Rift
A pen is to a car what a meteor is to a _____
Mostly Correct... (4.00 / 1) (#61)
by alder on Mon Nov 19, 2001 at 12:11:08 PM EST

Very interesting and handful comparison. IMNSHO, a little biased here and there, but that's OK - our experience engraves a lot in the way we see things which are different (well, you are absolutely right though - C# is not that different :-) and maybe this is good)

Ragarding some errors: you probably misread parts of documentation (cannot comment on en entire piece - I just scanned through it), and at least in one place, where you claim:

Java only supports serializing objects to a binary format and does not provide a way of overriding the standard serialization process
you are not correct. If you reread information about java.io.ObjectOutputStr eam you'll find the following piece:
Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException;
private void writeObject(java.io.ObjectOutputStream stream) throws IOException
But, I guess that makes them even more similar, isn't it? :-)

Good catch (none / 0) (#63)
by Carnage4Life on Mon Nov 19, 2001 at 12:16:09 PM EST

Thanks for pointing that out. I guess this shows that I'm still mostly familiar with J2SE 1.3 and not J2SE 1.4. I'll change this once I go read up on the java.io.ObjectOutputStream class and try out some code.

Should be updated in an hour or so.

[ Parent ]
Well, it was there even before 1.3 ... (4.00 / 1) (#68)
by alder on Mon Nov 19, 2001 at 12:48:06 PM EST

Here's another link this time to 1.2

[ Parent ]
Ahh, but that is not the end of it :-) (5.00 / 1) (#111)
by alder on Mon Nov 19, 2001 at 11:38:39 PM EST

In the modified version you write:
Since the above methods are private there is no interface that can be implemented to indicate that a Java class supports custom serialization
As you are probably already suspecting, that is not correct. Here's another interesting link for you. It's about java.io.Externalizable interface, and a quote:
The writeExternal and readExternal methods of the Externalizable interface are implemented by a class to give the class complete control over the format and contents of the stream for an object and its supertypes. These methods must explicitly coordinate with the supertype to save its state. These methods supercede customized implementations of writeObject and readObject methods.


[ Parent ]
Other ways to serialize Java (none / 0) (#90)
by daveq on Mon Nov 19, 2001 at 05:41:12 PM EST

There are third party tools (of course you could always write your own) to serialize Java into all sorts of things, usually XML though. Here some persistance in XML stuff:

http://directory.google.com/Top/Computers/Programming/Languages/Java/Databases_and_Persistence/XML/

[ Parent ]
Bad Example (none / 0) (#91)
by daveq on Mon Nov 19, 2001 at 06:01:19 PM EST

All they have there is JSX. But look and you will find

[ Parent ]
Good SEMANTIC comparison (none / 0) (#70)
by MSBob on Mon Nov 19, 2001 at 01:09:44 PM EST

I liked the your paper a lot but I've got this general feeling that while the languages themselves maybe similar the distinguishing factors will lie in the class libraries they support. C# is a new kid on the block and what I really want to find out about it is:
  • Does it have a JDBC like API?
  • Is there a way of building distributed objects similar to (and preferably better than) EJB?
  • Does C# have containers (aka Collections)?
  • Do they suck as much as the Java ones?
  • Can I control the works of the JVM garbage collector with runtime switches? Or programatically?
  • Are C# platform libraries going to be cross platform? What about the UI ones?
  • Does C# mean death to the dreaded MFC libraries?
  • Will MS ever write a decent UI class library for C++? It can be done just look at QT.
Anyway, I have lots of questions like that and I'm sure so do many other developers. I have to say that so far Microsoft hasn't been very good at addressing them yet.
I don't mind paying taxes, they buy me civilization.

Some answers (4.00 / 1) (#73)
by Carnage4Life on Mon Nov 19, 2001 at 01:26:03 PM EST

Does it have a JDBC like API?

ADO.NET.

Is there a way of building distributed objects similar to (and preferably better than) EJB?

.NET Remoting and XML Web services.

Does C# have containers (aka Collections)?
Do they suck as much as the Java ones?


Discussed in my article

Can I control the works of the JVM garbage collector with runtime switches?

Not to my knowledge.

Or programatically?

The IDisposable makes finalization more deterministic

Are C# platform libraries going to be cross platform?

I doubt this since a large number of them aren't in the ECMA standard so even if it is ported to the other platforms, thinks like ASP.NET, ADO.NET and web services probably won't be there. Then again I have no idea what the FreeBSD team at MSFT is doing so this is just speculation on my part.

What about the UI ones?
Does C# mean death to the dreaded MFC libraries?
Will MS ever write a decent UI class library for C++? It can be done just look at QT.


I don't do GUIs so I can't really answer these questions although I doubt if the answer to any of the above questions is yes.

[ Parent ]
templates (none / 0) (#72)
by vladimir on Mon Nov 19, 2001 at 01:25:53 PM EST

I've heard rumors that templates will be introduced into Java in an upcoming release. Blind casting has certainly been the one feature of Java that I've disliked the most. I wonder if templates are supported in C#. It doesn't sound like it from this article. My general comment about C# is that it looks like a Java clone with a few relatively trivial differences. Some things, like operator overloading seem like a bad idea to me. The syntax seems rather uglier and more complicated than Java's. Introducing true 'references' may be a good idea. On the other hand I think it encourages more poorly written code and may pose an unnecessary maintenance headache in many cases. Vlad

blind casting? (none / 0) (#74)
by boxed on Mon Nov 19, 2001 at 01:38:32 PM EST

all casts in java are like the C++ dynamic_cast, what's "blind" about that?

[ Parent ]
templates and collections (none / 0) (#76)
by vladimir on Mon Nov 19, 2001 at 01:52:55 PM EST

What I mean by 'blind casting' is that when one is using collections in Java (ArrayList, HashMap, etc...), these structures use the Java 'Object' class. If I put a bunch of EmpRec objects into an ArrayList in one place and retrieve them somewhere else, I have to either blindly cast or use the 'instanceof' operator to check that the objects placed into the collection really are of type EmployeeRecord. Basically, in many cases a compile-time check that only a certain type of object is being placed into such a data structure would be very nice. Also, not having to cast all of the place would be helpful.

e.g. What I would like to see in Java is something like the following...

ArrayList<EmpRec> recs = new ArrayList<EmpRec>();

EmpRec newRec = new EmpRec();

recs.add(newRec);

EmpRec getRec = recs.get(0); //no casting

[ Parent ]

templates are kind of a weak hack (none / 0) (#112)
by Delirium on Mon Nov 19, 2001 at 11:58:32 PM EST

Well, it's not really "blind" if you use the instanceof operator.

On the whole I like Java's method of doing this sort of generic programming a lot better than templates - the syntax is cleaner and more consistent, and it's much more in the OO spirit of things (as fluffy grue pointed out elsewhere, templates are really just glorified type-safe macros). And it really is a lot easier to track down errors, at least in my experience, since it fits in the OO methodology of things the compiler knows how to deal with rather than being essentially a pre-processor hack (not technically a pre-processor, but something very similar, as templated classes/functions are converted by the compiler to definite-type before the actual compiling takes place; this also means that when you use a templated class 5 different times for 5 different types, you actually get 5 different compiled compiled versions of the class - with Java's method, you get one).

That said, it might be nice if Java had some sort of auto-casting. Since it obviously keeps track of type information internally, allowing the instanceof operator to work, it should be possible to do something like cast_this_to_whatever_it_is(object).

[ Parent ]

hm (5.00 / 1) (#114)
by jacob on Tue Nov 20, 2001 at 01:02:30 AM EST

And it really is a lot easier to track down errors, at least in my experience, since it fits in the OO methodology of things the compiler knows how to deal with rather than being essentially a pre-processor hack ...

C++ templates are something of a hack. Type parameterization in general, however, is not. Rather than thinking about it in terms of its C++ implementation, think about the extra expressiveness it gives to your type system: type-parameterization catches bugs at compile-time rather than run-time (yay!) and inspects every site at which bugs could occur for any possible value that could cause an error, rather than just testing selected call sites with selected values (yay again!). Since a language's type system has nothing to do with how ethically pure and virtuous its object system is (in most cases, PL/SQL being an exception -- an "object-oriented" language without subtyping! Brilliant, guys!), I don't see any reason why type parameterization doesn't have a place in OO methodology.

As for autocasting, I really don't understand how that could work. Sure, you can call a method auto_cast(Object f), but what's its return type going to be? How are you going to program to it? To put a finer point on it, if you assign its return value to a variable, what's the most specific type you can declare that variable to be? It's whatever the variable was in the first place, since you don't know anything more about it until run-time, which hasn't happened yet when you're programming the method :). And since Java's a typed language, I don't see what extra knowledge an auto cast would give you that instanceof doesn't. And besides, instanceof is the most un-object-oriented construct in all of Java [source: me sitting here and thinking about it for 30 seconds]. Use of it certainly isn't the sort of behavior we ought to encourage.



--
"it's not rocket science" right right insofar as rocket science is boring

--Iced_Up

[ Parent ]
not weak (none / 0) (#115)
by spacejack on Tue Nov 20, 2001 at 01:09:23 AM EST

You can call templates glorified macros, but I see 2 advantages:

1. The compiler will tell you when you're using the wrong type of object with a template, and what type it expects.

2. Memory allocation/efficiency -- STL container classes expand efficiently without you having to write your own object pools; e.g., you allocate both the object and its container space with a single push_back call, and your iterator is a simple pointer to the actual objects themselves.

Granted, as you mention, the drawback is generating code for each type of object for each template function/class. But then you can just store pointers or references if this is a problem, and use dynamic_cast to check types. Seems to me like you get the best of both worlds.

[ Parent ]
wtf? (none / 0) (#118)
by boxed on Tue Nov 20, 2001 at 05:51:45 AM EST

You mean to say that you want compiletime type checking for arrays like in C++ with templates. How the HELL has that anything to do with what you call "blind casting"? And how is it "blind" you KNOW what objects you put in the array? Besides, if you want a specialized class you can make one that just wraps the ArrayList to do what you want, that's not many lines of code.

[ Parent ]
GJ (Generic Java) (none / 0) (#87)
by Y on Mon Nov 19, 2001 at 05:21:32 PM EST

I believe you're thinking about GJ, which will be appearing in a modified form in Java 1.4. There is a beta already available from Sun's community downloads section.

The syntax is similar to C++ templates, but the implementation is different. In GJ, all type parameters are statically type-checked and then erased, with casts inserted into the bytecode to guarantee compatibility with legacy java code. There is only one method table per class with classes that make use of generic type parameters, as opposed to C++ which allocates a new method table for each instantiation of a parameterized class.

Another concurrent development, NextGen, expands on the framework provided by GJ, but keeps the type information at runtime instead of erasing it. As far as I know, the team working on NextGen is still working to implement parameterized methods, but there may be an alpha available.



[ Parent ]
Well (2.85 / 14) (#75)
by trhurler on Mon Nov 19, 2001 at 01:50:51 PM EST

You asked for my opinion. Unfortunately, my opinion is pretty much my opinion of Java. Both of these are languages designed to let people who can't master and consistently practice certain simple rules program, which latter activity consists of mastering and consistently practicing certain other simple rules along with a healthy body of theoretical knowledge. The simple rules are the easy part; the theoretical knowledge is harder. At first, this seemed to me to make such languages pointless, but while their claim to fame is "easy" programming because of garbage collection and so on, the truth is, that's not why they succeed.

Languages such as these succeed primarily because they let idiots program with a minimum of theory, rather than because they let you get away with some trivial crap related to memory or array bounds. For instance, both provide all the data structures most programs ever need. Both provide such a trivial and high level view of the system and its capabilities that a trained monkey can use them, provided he can find accurate documentation and work his way around often shoddy implementations of reasonably good ideas. And frankly, both are boring as hell. They're the COBOL of the new century. The same people who refuse to learn vi because it is "hard," and yet think they can and should be able to program, which they apparently do not regard as being "hard," choose Java or C# or whatever over languages with fewer Fischer-Price My First Programming Language "features."

That said, they're better than C++, simply because they have a type "object" from which you derive your objects. And also, a lot of good people use these languages because they reduce the need to reimplement the basics all the time(a good thing,) and also because the boss said so(not necessarily good, but if you work on a team of any size, it probably is. Moronic java is much nicer than moronic C.)

As for the article itself, I don't know either language well enough to critique the comparisons, but I will say that apparently C# contains some stupidities. "Delegates" are pretty obviously intended to facilitate delegation, which can quite easily be done in Java despite it lacking them, for instance. Microsoft seems to have used their usual kitchen sink approach, and the result is probably a bloated pig with lots of "hidden features," as usual. You wrote it well, for whatever that's worth:)

By the way, I am utterly uninterested in any replies criticizing my characterization of these languages from people who have not written code in at least one assembler to perform nontrivial operations, mastered C, and at least used C++. There seems to be a rash of "programmers" lately who've never used a language that doesn't coddle them, and who vehemently attack anyone who says they're idiots - but they're still idiots, so if that's you, shut your hole. You cannot possibly understand where your language fits in if you don't understand other languages - and not just three or four of the same kind!

--
'God dammit, your posts make me hard.' --LilDebbie

Oh, you troll (5.00 / 4) (#78)
by MSBob on Mon Nov 19, 2001 at 02:29:02 PM EST

Well, you're trolling a bit but I'll bite. Anyhoo my creds are 6502 and 68000 assembly (stuff I played with when in high school), a number of years of C that I first picked up at the tender age of 14 and at least one C++ app with >1,000,000 lines of code with a bunch of OpenGL to boot.

Java was not meant to be an equalizer for developer underachievers. Howver, I agree with you that Java made programming appear easier and thus attracted a very mixed pool of talent to the community. Same can be said of VB of course.

Java's semantics are easier than C++ but and this is an important but... Developing good Java is actually pretty hard, maybe even harder than doing good C++. The reason? The highly dynamic nature of the language couple with the non-deterministic behaviour of the garbage collector. This means two things. Good java requires more attention to object pooling than C++ does. Elimination of stack allocated objects means that a good developer needs to put up quite a fight to still have adequate performance figures at runtime. Additionally the ever elusive String class. This is a real killer. When I first went through my company's enterprise app with JProbe and examined the memory details I paid attention to the string class allocations. I almost fainted when I saw over 100,000 String objects getting allocated and destroyed during a single user session. It's stuff like this that gives Java performance a bad name. Java deserves some of the blame but it's mainly moronic coders that don't think twice about performance implications of the stuff they do.

The jury is out on whether the garbage collector actually makes life easier. Loitering objects are still an issue and I've found it just as difficult to trace loiterers as I did finding unmatched new operators. Thank goodness for Sitraka's JProbe.

Java isn't that bad and its performance doesn't have to suck but it requires just as much care and attention as any other programming lanugage. It's just that its gotchas are different. However, for one reason or another it also seems very appealing to morons from all walks of life who are aspiring to become l33t coders. A bit like perl I suppose but without the OSS zeal.

Nice Java apps are possible and JProbe itself can be a good example. Also Java's built in libraries are so extensive that it's just sheer convenience of having every imaginable api at hand is what attracts many good developers to Java. Of course the quality of those apis seems to be quite variable but in general the APIs provided are not generally disastrous (like the good ol' MFC for instance).

It ain't all bad but must be used in moderation and handled with care. Just like everything else I suppose.

I don't mind paying taxes, they buy me civilization.

[ Parent ]
Writing good Java easier than good C++? (3.00 / 2) (#79)
by Carnage4Life on Mon Nov 19, 2001 at 02:47:59 PM EST

Java's semantics are easier than C++ but and this is an important but... Developing good Java is actually pretty hard, maybe even harder than doing good C++.

No offence but this statement strikes me as very facetious. Good C++ is HARD primarily because the language is so complex that even the language gurus can't agree on what constitutes good C++ code and the subtleties and inconsistencies are massive. Questions like how do I overload the ->* operator or what does private inheritance do have no analog in the Java world. Secondly almost every language feature you use in C++ is a step or two away from undefined behavior compared to Java where the worst that happens is that some Exception gets thrown if you screw up but then again nothing is so difficult that you can screw up that badly anyway.

Writing good Java code is not hard, writing good C++ code on the other hand is extremely difficult. This is the major reason why Java is slowly winning over C++ in industry and academia in most fields of endeavor programming-wise.

[ Parent ]
Correct code vs. good code (none / 0) (#83)
by MSBob on Mon Nov 19, 2001 at 03:55:36 PM EST

There is a subtle but important difference between writing correct code and good code. I agree that Java makes writing correct code easier. Writing good java code is hard for the reasons I mentioned in my previous post.

On the other hand, good C++ is cetrainly possible and you know, not every feature of the language has to be used in every program. I tend to overload operators judiciously and sometimes even provide functions to do the equivalent thing (think .dotProduct() instead of overloading *). However, with the immense flexibility of the language I too can have lots of checking in C++. For instance I routinely use a memory leak checker that I wrote a while back that overload new/delete and it's served me very well so far. That coupled with using auto_ptr is half the battle to ridding of memor leaks. STL greatly helps in managing data structures in a way that Java's puny containers can't touch. There is a lot of things that are essentially easier to do in C++ especially when your data structures require complex arrangements (think map floats and of vectors of linked lists of strings!). Bad algorithms aside there is little one can screw up to kill performance the way programmers can in Java.

I don't mind paying taxes, they buy me civilization.

[ Parent ]
Bloated (C++) vs. Immature (Java) language (none / 0) (#89)
by alder on Mon Nov 19, 2001 at 05:27:35 PM EST

Well, that statement above is obviously a gross exaggeration. I just want to highlight my point with it :-) C++ was concieved at the time when OO had not been that well understood as it is now, so many mistakes were made, many "evil" features included that make us stumble if we deviate from safe practices. The issue is we can deviate and easily, especially if one lacks good coding skills, and sometimes knowledge about peculiarities of the platform.

Java limits what we can do (and succeeds in it :-) hence at least today it pushes masses towards safer programming but at the same time do not offer flexibility to those who can master intricate details.

Consider those containers. It appears that Java creators were looking at Smalltalk for their inspirations, but missed the point making Java statically types language. Where Smalltalk simply evaluates whether object understands the message at run-time Java has to know this beforehand. As a result - casting. C++ on the other hand has templates - a semantic bridge between static typing and dynamic nature of most containers (at least when they are useful, i.e. provide something beyond being a featureless "bag"). One can only hope that one day Java will have genericity as part of the language and you won't have to grumble about "puny containers".

C# on the other hand seams to go much faster in the direction of offering useful features to those who is able to master their use. Even something so impious as pointer arythmetic in "unsafe" code. All that offers more flexibility and as a result in skillfull hands will lead to productivity, better code and performance. Unfortunately, and this is a very big "unfortunately", there is no genericity in C# as well, though I read somewhere that they are working on adding it to the language some time down the road.

[ Parent ]

Only sort of true (none / 0) (#124)
by ucblockhead on Tue Nov 20, 2001 at 12:10:38 PM EST

OO was fairly well understood before C++. C++ hardly invented OO. Smalltalk was around for a long time before that. The trouble with C++ is not that OO was not well understood when it was designed, but with the particular design constrains imposed on C++. That is, C++ was designed to be (mostly) C compatible, a compiled language, and to perform as well as C code given constructs.

Templates, which complicate the language enormously, aren't really an OO feature, and probably weren't well understood when first added to the language. (At least in a real world context.) Generic programming is something different than OO.
-----------------------
This is k5. We're all tools - duxup
[ Parent ]

Nah (3.00 / 2) (#80)
by trhurler on Mon Nov 19, 2001 at 03:24:41 PM EST

A troll doesn't believe what he says. I believe what I said. Java's market penetration today would be nigh on zero were it not for the perception, correct or otherwise, that it is the modern business language for half trained idiots. Same with perl, for that matter, and so on.

The fact that my opinions may be controversial does not mean that I air them solely to stir the shit.

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
The message was different (5.00 / 1) (#88)
by MSBob on Mon Nov 19, 2001 at 05:26:44 PM EST

Java's market penetration today would be nigh on zero were it not for the perception, correct or otherwise, that it is the modern business language for half trained idiots.

Well, I remember that Sun were banging the drum on Java cross platform capability much more than they were on its supposed ease of use. I would like to think that it's the crossplatform nature that won it the acceptance in the enterprise. At my company it works quite nicely when we can have developers work individually on windows laptops/desktops and then when the overnight build gets done the .ear file gets deployed on Solaris for testing and production.

Buggy Sybase JDBC drivers aside, I've yet to encounter a single Java cross platform compatibility issue. Having said that I don't use Swing and have no idea how good its cross-platformness is.

I don't mind paying taxes, they buy me civilization.

[ Parent ]
Um... (1.00 / 1) (#100)
by trhurler on Mon Nov 19, 2001 at 08:44:22 PM EST

You're the first person I've ever heard claim that a Java program written on 'doze actually worked properly on a Unix jvm without mods and without careful planning to make it so. I'm inclined to disbelieve:)
Buggy Sybase JDBC drivers aside, I've yet to encounter a single Java cross platform compatibility issue.
Maybe if all you're doing is network connections and databases.

Anyway, the real reason Java swept in was twofold: buzzword compliance and a horde of newbie "programmers" who knew nothing but Java and were available immediately to hiring managers everywhere during the recent economic boom times. Cross platform was part of the buzzword compliance, but in fact, Sun's original target niche for Java never became significant in the real world(ie, applets with fancy guis and so on) due to problems with that very cross platform promise.

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
I feel insulted :( (5.00 / 2) (#106)
by MSBob on Mon Nov 19, 2001 at 11:10:49 PM EST

Maybe if all you're doing is network connections and databases.

Isn't that good enough for you? Let me tell you there is quite a bit into it (sockets api, threads, DBMS, Mail, message queues, XML, security etc). Probably more to it than you imagine. The areas I routinely tackle at work these days involve dealing with DBMSes and all that entails, distributed computing, distributed transaction handling, load balancing, fault tolerance, asynchronous network messaging and so on. If you think that you're l33t because you're working in the games industry or something and all enterprise programmers are uneducated morons I think you need a clue and a new job. I too worked for a games company for a while so listen carefully: enterprise computing is just as complex and challenging as writing 3d games (and definitely more lucrative). While I don't code in assembly at my day job anymore I wonder how many distributed deadlocks have you had a chance to debug and resolve? How many systems did you speed up by a factor of 200% by adding a custom designed load balancing algorithm? Make no mistake, challenges exist in all areas of computing, not just 3d graphics. If you want a doze of enlightenment on enterprise computing I recommend that you pay a visit to this site and read the papers and publications online. Much of it is actually quite applicable to what I face every day.

Back to the point of java's cross platform situation. While wrinkles still existed in 1.2 with 1.3 we've encountered no known compatibility issues yet we had about a dozen with the 1.2 series. I think I'm speaking for most of the Java community when I say that the "write once, run anywhere" situation is improving quite dramatically in the Java world and with the imminent release of the 1.4 series JDK Sun has done a terrific job of resolving the few outstanding compatibility issues that still existed.

I'm not claiming Java is a fix for everything. When I first started at my company I considered myself a long toothed C++ programmer and assumed that that I had nothing to learn from that Java crowd. Boy, was I ever wrong about that. I have just as much challenge with this job as with any other I held in the past and I'm learning new stuff almost every day.

I still see Java as having serious flaws not least of which is its massive memory footprint. So no, it's not a great gaming platform. However, for some serious distributed app development nothing comes close to Java. The sheer complexity of the task makes a low level language implementaion simply impractical. You see, I curbed some of my arrogance and I've learned a thing or two and over the past twelve months my perception of Java is not nearly as icy as it used to be. I'm not gonna make sweeping, idiotic statements here like 'once you start using Java you'll never look back'. That's nonsense. But trust me Java is pretty darn good for some things.

I don't mind paying taxes, they buy me civilization.

[ Parent ]
Hehe (none / 0) (#125)
by trhurler on Tue Nov 20, 2001 at 01:12:16 PM EST

Isn't that good enough for you? Let me tell you there is quite a bit into it (sockets api, threads, DBMS, Mail, message queues, XML, security etc). Probably more to it than you imagine.
Seeing as I know that particular field rather well(albeit not in Java,) I doubt there is much more to it than I imagine. It is not bad work, but if it was all I did, I'd get bored. Sure, there's immense complexity, but after awhile, it all looks the same. The code equivalent of miles and miles of cube farm. Which, actually, has its appeal sometimes too. You just never know.
The areas I routinely tackle at work these days involve dealing with DBMSes and all that entails, distributed computing, distributed transaction handling, load balancing, fault tolerance, asynchronous network messaging and so on.
Sounds like you've got a better job than most people in this particular field.
If you think that you're l33t because you're working in the games industry or something and all enterprise programmers are uneducated morons I think you need a clue and a new job.
I don't work in games. I work in what can most loosely be described as secure distributed computing. While everyone else talks about it and writes overcomplex, insecure "solutions," we've been quietly providing real, truly secure and truly scalable software for roughly a decade. I've been with the company for a bit over two years, and while I've studiously avoided any hint of authority, I'm the guy who does most of the work on our core product these days. I doubt you'd call it "enterprise computing" from where I sit, seeing as we've yet to ever have 40 employees on the payroll at once, but the people who buy our systems certainly call it that.
While I don't code in assembly at my day job anymore I wonder how many distributed deadlocks have you had a chance to debug and resolve?
I don't write assembler at my job either. I write C. We design our systems so that either they can't deadlock, or they won't. The idea of leaving one to the point of being a debugging problem strikes me as somewhat archaic, unless the problem is in some third party software that was produced by morons.
Make no mistake, challenges exist in all areas of computing, not just 3d graphics.
Lucky for me, since I've never tried 3d graphics:)
I think I'm speaking for most of the Java community when I say that the "write once, run anywhere" situation is improving quite dramatically in the Java world and with the imminent release of the 1.4 series JDK Sun has done a terrific job of resolving the few outstanding compatibility issues that still existed.
I'm glad to hear that on only their fifth try, they might actually have done what they said they did five years ago with the first:)
However, for some serious distributed app development nothing comes close to Java.
We manage to pull it off in a mix of C(at the bottom of things,) Perl, and traditional Unix shell tools, along with careful use of third party software to accomplish bits that aren't worth our time to implement locally. Java wouldn't be a bad idea, except that it would kill our scalability. Java does not lend itself well to putting 20,000 users' load on hardware in the sub-six-digit range, for instance, and still having the system run well.
But trust me Java is pretty darn good for some things.
So are COBOL and FORTRAN, but you won't catch me writing those either:)

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
Those arguments are very flawed (5.00 / 3) (#82)
by alder on Mon Nov 19, 2001 at 03:50:00 PM EST

While I respectfully agree with you, that Java atracted a lot of "developers" without proper background, and probably even may share some of your resentment towards that type of "software engineers", I cannot not to point that arguments you are using are very flawed.
Languages such as these succeed primarily because they let idiots program with a minimum of theory...
Langueages such as these let us solve certain class of problems easier and faster then we would normally do using only C/C++. They are definitely a bad choice for lower level progaramming (IMNSHO), as well as for very high-level (integration) programming where something like Python (well, I like it, so here it goes :-) is more suitable. People, especially overzealous people, are trying to use their tool/language of choice for any imaginable task, but the fact is that these two (Java, C#) have ability to cover quite a spectrum of problems. So an engineer skillful in, let's say, Java development would be able to apply the knowledge to a lot of very different projects. Maybe that is the reason for them to become so popular?
"Delegates" are pretty obviously intended to facilitate delegation, which can quite easily be done in Java despite it lacking them, for instance
Well, that has been chewed to death already -- it does not matter that same task may be solved using other languages (be it Java, C or assembler), it just so happens that this particular language offers enough syntactic sugar to make it the process of development more pleasant and aesthetic. Therefore some people like the feature, and sometimes disappointed that they cannot use this convenience (and some others) in the tool they are using right now. BTW, delegates are just method pointers (think about them as function pointers in C) - nothing misterious.
criticizing my characterization of these languages from people who have not written code in at least one assembler to perform nontrivial operations, mastered C, and at least used C++.
Well, credentials (-: assemblers - PDP-11, i8080, ix86, 68K, PA (though I must admit the latter two weren't used for nontrivial operations), as for MACRO-11 - during my internship (yes, I'm that old) I developed user-space preemtive thread manager for RT-11. I majored in robotics, so beyond assemblers for various projects I used mostly C (though once it was a big C++ project - Java did not exist then, otherwise it would be developed in Java; again - it's all about convenience of a toll for a particular task!) I switch to Java in 97, and that was the last time when I considered a tool, any tool, to be a panacea. They all have place under the sun, you just have to see what you need to use, where and how.

[ Parent ]
Or maybe... (2.50 / 2) (#85)
by trhurler on Mon Nov 19, 2001 at 04:57:52 PM EST

Langueages such as these let us solve certain class of problems easier and faster . . .
What book did you rip that sentence from? I know I've heard and read it a few thousand times now. I've never seen it actually justified; people just say it as though it is obviously true, but it is not. Training time, poor understanding(most "right tool for the job" people don't know ANY of their tools well enough to really have any business being paid to use them,) and many other factors are ignored by this ridiculously simplistic worldview.
BTW, delegates are just method pointers
I know what they are, and my criticism stands; they are intended to solve a problem that already has a solution, or that should, in any case, which does not require programmer intervention. In particular, by storing method pointers instead of object pointers, you avoid the object indirection. There's no good reason a programmer should have to hand-specify that; the first time such a thing(in object->method notation) is encountered, it should be converted into a hard reference to the method(even if at runtime,) and then used as such; if there are few calls, this will run slower, but it will not matter, because there are only a few calls, and if there are many, it will perform essentially as well as this "optimized" version.
I switch to Java in 97, and that was the last time when I considered a tool, any tool, to be a panacea.
By reframing a criticism of a certain set of tools as a criticism of all tools except one, you can make that criticism appear foolish to anyone who does not realize what you have done. This, however, is not productive.
They all have place under the sun, you just have to see what you need to use, where and how.
This is not justified by your previous statements; clearly, some things just plain out suck. For instance, there is no excuse for Visual Basic. In all of its forms, in all places it has ever appeared, it sucks.

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
I do not disagree ... (none / 0) (#93)
by alder on Mon Nov 19, 2001 at 06:20:23 PM EST

with most of what you are saying. But when you take it to the extreme it does "appear foolish".
most "right tool for the job" people don't know ANY of their tools well enough...
That sounds quite a bit contradictory to me - how one can choose a right tool without an explicit (intimate) knowledge about all (important) alternatives? That particular statement of mine, that appears unjustified to you, is based on my experience of using different approaches (and languages) to develop different parts of a complex system (C, Java, Python). They all found their place and were used to solve different problems. It is true that the thing could be developed in its entirety in C++, but taking into account a possible evolution during system's lifetime it's much better being decomposed into smaller task oriented parts, where, I expect and hope, the most stable and low level code will never change, and the most flexible (Python scripts) would be altered/extended "on a daily bases" by those who want to change the rules...
By reframing a criticism of a certain set of tools as a criticism of all tools except one...
I'm sorry, but I'm really missing the point here. Probably I was not clear in expressing my views (maybe I jumped on a diffrent subject... typing slower then think :-) and hence you misread me. Sorry, again. I do not wish to make you criticism to appear foolish. I fact (as I believe I already said) I agree with the spirit of what you are saying. Maybe just you examples do not hit the right target. Anyway I believe it's not the language's/platform fault that some (a lot of) "developers" aren't good enough to use it properly and, as a result, write bad code. If one is qualified and skillful, then the tool will be used in the right way, and in proper scope.

Maybe those "right tool for the job" people you were talking about are simply do not know anything BUT one tool (and badly), so they cannot choose the right tool because they are not ready to do this.

And, yes, I'm still convinced that even VB had/has it's place. Unfortunately, it's not used only where it is appropriate. Unfortunately that is also applicable to Java. Unfortunately, not everything we deal with today is/was developed based on technical merits - remember WORA, and it's child Swing?.. And even Swing has it's place.

[ Parent ]

Simians (5.00 / 3) (#92)
by oleandrin on Mon Nov 19, 2001 at 06:13:09 PM EST

Java does not let idiots program. Theory does not apply to assembly any more than to Java (which is to say, very little in either case). The only applicable metric here is the appropriateness of the tool to the job.

Use assembly if you need a highly optimized parallel 'Life' algorithm. Use Java if you're writing for an appserver environment. And use C# if you're writing for .NET.

In all of these cases, monkey writers will produce monkey code. Java is not for idiots because idiots are confused by memory allocation and thus can safely ignore it; the Java programmer who neglects memory management entirely will always be outdone by those who know better. The same is true when a high-level language programmer is ignorant of underlying system architecture.

Do you consider MATLAB a programming language? How about VHDL? Haskell? They are, and your limited idea of "programming without theory" is ludicrously far away from beginning to apply to them. SPICE, which I'm going to call the assembly of the circuit world, is so simple a monkey could determine acceptable CMOS high/low voltage ranges for some given Vcc, and yet have no idea how many bytes are needed to store his V(t) calculations.

Layers within layers within chocolatey caramel candy-wheels, man. So is it easier to write bad Java or bad assembly? Are assembly programmers better than Java programmers? Unfortunately, it isn't a valid comparison. If you don't understand why, then you're just another monkey.

Sunshine daydream!

[ Parent ]

You missed my point (none / 0) (#96)
by trhurler on Mon Nov 19, 2001 at 08:10:46 PM EST

Use assembly if you need a highly optimized parallel 'Life' algorithm. Use Java if you're writing for an appserver environment. And use C# if you're writing for .NET.
.NET and the "appserver environment" are nothing but life support systems for code written in a given language. You might as well say "write in Java if you're in a Java environment."
Java is not for idiots because idiots are confused by memory allocation and thus can safely ignore it; the Java programmer who neglects memory management entirely will always be outdone by those who know better.
The sad truth is, it doesn't matter. If his program works, or even if he can just fool someone into thinking it does(far more common than you probably think,) then he can be paid. The primary reason Java is in widespread use is that it lets managers hire people with deficient frontal lobes as "programmers," easing the hiring crunch. It may be that nobody "inside the system" sees it that way, but this is irrelevant. Yes, the resulting code sucks. Welcome to the real world.
So is it easier to write bad Java or bad assembly?
It is trivially easy to write bad code in any language. Only some languages, however, will let bad code actually function as expected.
Are assembly programmers better than Java programmers?
Which ones?
If you don't understand why, then you're just another monkey.
Oh, I understand why, given your premise, but your premise is that I said something I did not. If you're looking for a freshman undergrad or high school kid to mock, I suggest you move on quietly and keep looking:)

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
Umm ok.. (3.00 / 1) (#99)
by nebby on Mon Nov 19, 2001 at 08:24:25 PM EST

If his program works, or even if he can just fool someone into thinking it does(far more common than you probably think,) then he can be paid.

If his program works, then yes, he should get paid. If his program is broken, then someone else (another programmer, another company) will put the former out of business with superior work. Welcome to the free market!

Only some languages, however, will let bad code actually function as expected.

If, as you say, it works as expected, then who cares if the programmer didn't write a slick solution and implement every detail of his data structures? Christ some people are SO elitist. If he wrote "bad code" that would really affect the end use of the product, see my previous point. You don't hire the guy (or pay him) to optimize the NIC driver, but if he can make a pretty text editor, then let him do it.


Half-Empty: A global community of thoughts ideas and knowledge.
[ Parent ]

Ok... (5.00 / 1) (#101)
by trhurler on Mon Nov 19, 2001 at 08:53:34 PM EST

If his program is broken, then someone else (another programmer, another company) will put the former out of business with superior work.
Are you aware that the largest and most successful software firm in the world is known for producing some of the shoddiest software in samesaid world?
If, as you say, it works as expected, then who cares if the programmer didn't write a slick solution and implement every detail of his data structures?
Well, you see, it works on HIS machine. Or maybe "it works with THIS version of the driver." Or maybe "it works if you don't press this button." Or maybe "it works, but it lets people into your machine at their whim." Think about software you actually see in the real world, and ask yourself, "did competent people write this?" If you wonder what the upper bound for what competent people can achieve happens to be, I suggest looking at OpenBSD. It is living proof that software need not suck simply because it is complicated. We're not talking totally nonfunctional here, but we're also not talking elitest crap over whether the guy used our favored variable naming convention, either. There's space between those extremes.

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
Hmmm (none / 0) (#117)
by nebby on Tue Nov 20, 2001 at 02:07:22 AM EST

Are you aware that the largest and most successful software firm in the world is known for producing some of the shoddiest software in samesaid world?
And are you aware that using a single company in a unique situation as an all-compassing example is a logical fallacy? :) Seriously, Microsoft has been found guilty in a court of law of having a monopoly. They have no competition, so my point of the free market killing off shoddy software doesn't apply to them. Look at any other company with actual competition and you will find that they pay a lot more dearly for their mistakes.
Well, you see, it works on HIS machine. Or maybe "it works with THIS version of the driver." Or maybe "it works if you don't press this button." Or maybe "it works, but it lets people into your machine at their whim." Think about software you actually see in the real world, and ask yourself, "did competent people write this?"
Software companies that release software that breaks that easily (again, besides Microsoft,) usually go out of business or are overtaken by a competitor. All arguments based upon Microsoft, even their security measures, are by far the exception and not the rule.

The software I use in the real world usually is pretty decent, I find. Since XP came out I've realized that most of the problems with running Windows was the unstable OS, not bad application programming. Regardless, I fail to see how you can point to programs written in C++ as backing up your claim that Java and C# are babying programmers into being stupid and incompetent; nearly no software I use on my desktop is written in Java or C#.

I suggest you just stop fooling yourself and realize a good programmer will always be a good programmer regardless of the tool they use, and vice versa.


Half-Empty: A global community of thoughts ideas and knowledge.
[ Parent ]

A hint (5.00 / 2) (#123)
by ucblockhead on Tue Nov 20, 2001 at 12:02:58 PM EST

Software companies that release software that breaks that easily (again, besides Microsoft,) usually go out of business or are overtaken by a competitor.
Point of fact: something like 80% of all software written today is not written for sale.

Most software is written by companies for internal company use.
-----------------------
This is k5. We're all tools - duxup
[ Parent ]

Ah (5.00 / 1) (#127)
by trhurler on Tue Nov 20, 2001 at 01:37:43 PM EST

And are you aware that using a single company in a unique situation as an all-compassing example is a logical fallacy?
Fine. Computer Associates does the same thing. They're the SECOND largest, and they don't have any monopoly I'm aware of. Borland is notorious for the same thing, albeit mainly among those of us who were around when they were big enough to matter. In fact, the software industry at large is known for producing shitty products. Why you would even try to pretend otherwise is beyond comprehension.
They have no competition, so my point of the free market killing off shoddy software doesn't apply to them.
They have competition. Just recently, we beat them out for a contract. If you mean they have no competition in desktop operating systems, then I think you haven't examined their whole product line; that's just one item. In most areas, they face real competition, and in many, they're the underdog. Their newest (doomed) underdog is called X-Box, and while we aren't competing with THAT(we're not a game company,) I'm preparing to enjoy watching it lose money.
Look at any other company with actual competition and you will find that they pay a lot more dearly for their mistakes.
So Sun, for instance, has suffered grievously from releasing Java too early and needing five major revisions to deliver on the promises it made five years ago. Yep, they're about to be driven out of the market!
Software companies that release software that breaks that easily (again, besides Microsoft,) usually go out of business or are overtaken by a competitor.
Name one. Or rather, since you hate single examples, name three:)

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
The real world (none / 0) (#122)
by ucblockhead on Tue Nov 20, 2001 at 12:00:59 PM EST

his program is broken, then someone else (another programmer, another company) will put the former out of business with superior work. Welcome to the free market!

[*choke*][*spit*]Bwahahahahaha!

That's the funniest damn thing I've heard in months!

Yes, and Santa Claus rewards only good children, and the people always elect presidents who are honest, intelligent and forthright.

In the real world, some other poor sap will have to come along and fix it, while the guy who wrote the broken program goes on to the next consulting gig.

My God, I could write a thick ox-killing book of examples of idiot programmers surviving and thriving in today's business climate.
-----------------------
This is k5. We're all tools - duxup
[ Parent ]

...thoughts of a dry brain in a dry season... (5.00 / 1) (#103)
by oleandrin on Mon Nov 19, 2001 at 09:47:27 PM EST

I'm not trying to mock you; I'm telling you that your should take a harder look at your premise. Your basic idea appears to be that brain-damaged ward patients can write Java that "works", while it takes a real programmer to write assembly that does.

I'm saying that your definition of a "real programmer" is a misnomer: the problem is not with the programmer, it's with the language. Processor-level programming makes for a terrible language. You will make a more convoluted, unreadable, error-prone non-trivial program in some assembly language than in any high-level language, because that language is not designed for you.

No language lets bad code function as implemented. There are an infinite number of correct ways to implement any given algorithm, some being more efficient than others. Since Java is currently a popular language, you will find more hacks who couldn't tell a Vector from an ArrayList thinking they know Java.

That doesn't make writing an efficient, correct program in Java any easier than writing the same program in a different language. In some respects, it's actually more difficult, because it requires the programmer to understand how the VM works, in addition to all layers below it. So if Java programming is harder than assembly programming, why is everyone using Java? Because it's easier to write inefficient Java programs that work than any kind of usable assembly program. Which is what you're saying, I think.

I think you can draw a parallel here with Internet Explorer's "ability" to correctly render malformed HTML. That's bad. However, if someone writes an html file with overabundant use of tables and a superfluous, yet not syntactically incorrect, amount of other tags, should it still render in some mind-numbingly exgagonizingly slow way? I think so. It's not bad, just poorly-written.

If history teaches us one thing, it's that when something is popular, there's a lot of shoddy detritus around it. Don't pick on Java because there's poorly-designed Java out there--people say the same thing every time a new layer of abstraction comes around.

Java's not perfect. Java programmers aren't idiots. Assembly's not perfect. Assembly programmers aren't idiots. Just some are, and some aren't.

If history teaches us one thing... hehe... time to go away for another few months or so...

[ Parent ]

Argh. (5.00 / 5) (#97)
by nebby on Mon Nov 19, 2001 at 08:18:11 PM EST

I've written a handful of MIPS assembly, created a circuit for a MIPS CPU, coded thousands of lines of C and C++, thousands of lines of Scheme, etc. etc.

I think I can be considered a decent programmer.

You say that you have little experience with Java and C#, yet you supply "requirements" for people replying to your post in order to certify them being up to your standard of programmer.

You know, I was going to list reasons why I prefer modern languages like Java, and now C#, instead of living the dark ages, but I'm not going to bother anymore simply because anyone who knows better doesn't need to hear it, I think. As for you, go write a few thousand lines of a "idiot" language before you go trashing on it and thinking you have a big dick for writing the assembly code for your silly linked list data structure yourself. Use the right tool for the job, and don't bother re-inventing the wheel. Also, before you call implementations you've never used "often shoddy," I suggest you actually find out for yourself if they are indeed shoddy!

Oh yeah, and I can use vi, jerk.


Half-Empty: A global community of thoughts ideas and knowledge.
[ Parent ]
I see (5.00 / 1) (#120)
by trhurler on Tue Nov 20, 2001 at 11:51:09 AM EST

So, you think I go rewriting data structures every time I need them just because I don't have them supplied by my tool vendor. Somehow, I don't think it is me who is the idiot here.

I've written thousands of lines(tens of thousands, probably,) worth of a couple of "modern" languages with extensive libraries of every feature known to man and so on. If I never do it again, that'll be soon enough; the people you end up working with are invariably one other decent guy and a dozen idiots who can't find their assholes with both hands and a flashlight. I don't need that shit, and in my job, I don't put up with it; there is nobody incompetent anywhere "near" me in this organization. In fact, everyone I deal with on a daily basis is very, very good. Compare to your favorite trend-driven software madhouse. :)

As for shoddy implementations, which one isn't? Anyone who has used VB and is a competent programmer(ie, who has used something else and done interesting things in it, at a minimum,) knows that it doesn't even always do quite what its own docs say, and that there IS no standard to speak of. Java is better, I agree - but any language where people who want fast programs actually design them to make as few library calls of certain kinds as possible because those functions are inexplicably slow(ie, the Java I/O library in most or all implementations,) is shoddily implemented or else has a bad design. Take your pick, I guess.

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
Sounds like.. (5.00 / 3) (#102)
by DeadBaby on Mon Nov 19, 2001 at 09:41:44 PM EST

Someone is jealous that modern languages remove most of the brain numbing bloat and menial clean up tasks that are common place to them, due to their experience with non-modern languages.

There's a great demand for higher level languages because it's downright stupid to train people to do things a language can deal with itself. Sure, you don't have as much control but think the vast majority of programs that will be developed in C#/Java won't require it.

I remember people saying a lot of these same things everytime a higher level language has been introduced and accepted by programmers. C#/Java is evolution at work.


"Our planet is a lonely speck in the great enveloping cosmic dark. In our obscurity -- in all this vastness -- there is no hint that help will come from elsewhere to save us from ourselves. It is up to us." - Carl Sagan
[ Parent ]
Nah (5.00 / 1) (#121)
by trhurler on Tue Nov 20, 2001 at 12:00:12 PM EST

There's a great demand for higher level languages because it's downright stupid to train people to do things a language can deal with itself.
When people make comments like this, I'm always reminded of something I admit I tend to forget: most "programmers" are nothing but task scripters, and for them, any language would be good enough. That's true. However, I do real work, and I tend to think in terms of people who do real work. Yes, you could write most of what I do in Java - and if you spent months profiling it, running it through Sun's run time optimizer, and so on, the result might work roughly as well as my C programs work, if you pay five or ten times as much for better hardware than we use. In exchange for that six figure increase in hardware costs(and it is an ongoing expense, so don't kid yourself about salary vs capital expense,) you'll probably pay about the same for the Java programmer, and if anything goes wrong outside his JVM, he probably won't even understand what it is, much less know how to fix it.

Yes, I know there are Java programmers who know other things. They're the exception though, as you'd know if you actually went out and talked to some other than you and your obviously above average friends:) Most of them don't even understand the JVM, really - they just know some magic rituals that "make things better." I'd as soon take factory work as deal with that kind of bozo all day.

--
'God dammit, your posts make me hard.' --LilDebbie

[ Parent ]
So it is a cost/benefit analysis... (none / 0) (#128)
by technik on Tue Nov 20, 2001 at 02:40:41 PM EST

Yes, you could write most of what I do in Java - and if you spent months profiling it, running it through Sun's run time optimizer, and so on, the result might work roughly as well as my C programs work, if you pay five or ten times as much for better hardware than we use.

Which only proves that you can shift your expenses around to achieve the same result. That's the material of a cost/benefit analysis. In this case you can use less skilled programmers with an easier to manage language and/or expansive library and offset that by using more expensive hardware. No surprise. Along the same lines, occasionally it is surprising how well (but more often, how poorly) algorithms are implemented in these big libraries but usually the junior programmer can produce reasonably well functioning code.

...you'll probably pay about the same for the Java programmer, and if anything goes wrong outside his JVM, he probably won't even understand what it is, much less know how to fix it.

Cost/benefit analysis. As to what happens outside the VM, you're going after a separate issue: breadth of knowledge. This is why we have senior programmers working with junior programmers, to (hopefully) let the less experienced learn and to give the hard problems to the more experienced.
-technik

... and before anyone makes an ad hominem attack on me, I learned asm, Forth and C before C++, Perl, Python and Java. I continue to learn- as much by making and correcting mistakes as by reading textbooks.

[ Parent ]
but... (none / 0) (#129)
by diesel on Tue Nov 20, 2001 at 05:56:36 PM EST

The sad fact is, most Java programs probably don't need to work as well as your C programs work. You don't really see people building RC5 clients using Java, but they certainly do build a lot of web apps with Java. So there are many cases where you don't need the higher potential return of C, but do appreciate the (almost always) lower investment required of Java.

Those are probably the situations where you don't consider the app to be "real work". That's fine... just as long as you do realize that those applications are still important to businesses and individuals, and still need to be done by someone, as unsexy and unchallenging as you may find them.

I don't really have any response to all of your unkind comments about Java programmers, except to say, you seem awfully worked up about it.



[ Parent ]
us-and-them (4.00 / 1) (#134)
by reflective recursion on Sat Dec 15, 2001 at 09:23:44 PM EST

Does anyone remember a time when programming was actually used to make the computer do useful stuff? Or am a living dinosaur or something? Remember source code games and such being printed in Compute magazine? When did programming become "do it perfect or don't do it at all?" I used to think "programming" meant making the computer do what the user wished. I'm not so sure now..

Who cares if Java lets "idiots" make their computer function the way they wish? If it's possible to get the computer to do useful things without worrying about memory management, then why not? Is CS now a requirement to programming a computer (aka a "programmable machine")? Should end-user Joe be restricted to using that cute Windows GUI? If a much higher-level programming language came out tomorrow, shouldn't end-user Joe be able to use it without people looking down on him for doing so?

It is sad to see this "us-and-them" attitude about computers. Some people do not need theoretical computer knowledge for their goals. And I'm sure most "true programmers" should be nowhere near the application domains they are programming for.

[ Parent ]
Slashdotting has ended (4.00 / 2) (#104)
by daveq on Mon Nov 19, 2001 at 10:08:31 PM EST

Ok, I'll just put things down as I got through.

You don't disginguish between checked and unchecked exceptions (apperently C# has no checked exceptions).

Compilation for C# seems to require annoyingly longer commands

The finalizer discussion doesn't mention runFinalizersOnExit(), the shutdown hook system, or indeed even show that the author understands the Java garbage collection system. The truth is that it is much uglier than this in Java. Fortunately I have never felt limited by the lack of a good Java deconstructor system.

One might notice from the above code samples that there is slightly more granularity in the C# Reflection API than the Java Reflection API as can be seen by the fact that C# has a ParameterInfo class which contains metadata about the parameters of a Method while Java uses Class objects for that which lose some information such as the name of the parameter

I can imagine this being useful for Microsoft's C# IDE, but otherwise it sounds pretty useless.

float fArray[] = new float[100]; //valid, but isn't clear that fArray is an object of type float[]

Cute. I haven't commented on ugly looking C# syntax. Where was that one on sychronized methods...

Oh yeah, this article doesn't seem to differentiate what is possible and what is a good idea.

Fall-throughs are explicitly disallowed because they are a leading cause of hard-to-find bugs in software.

Another amusing one. So they've debilitated 'switch' and you call it a feature? Go figure.

By this point (IO operations) it is indeed quite clear that Microsoft has not done anything to hide the fact they are making a Java clone.

By default Java supports serializing objects to a binary format but does provide a way of overriding the standard serialization process. Objects that plan to override default serializations must implement methods with the following signatures

private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException;

private void writeObject(java.io.ObjectOutputStream stream) throws IOException

Since the above methods are private there is no interface that can be implemented to indicate that a Java class supports custom serialization

Not true. Libraries like JSX and others provide third party serialization to XML, and while I don't know in what version of Java it will come standard, XML object persistance is about to become an official part of the library.

What about doclets? C# doesn't seem to have much of a documentation system at all, and as with most of Java's cool features you don't give any examples of properly commented Java classes.

You refer to the individual restrictions of file vs. namespace based package definition to make Java look more restricted instead of just stating it flat out. You don't mention that you always know what file a certain class came from.

First the needed libraries must be referenced somewhere in the source file which is done via the using keyword in C# and the import keyword in Java. Secondly, there must be a way to tell the compiler where to find the location of the needed library. Specifying the location of libraries that will be used by a Java program is done using the CLASSPATH environment variable or the -classpath compiler option.

What about the classpath for the virtual machine? Jar files? Class Loaders? Are you trying to hide something else about C#?

list of languages retargetted for the Java Virtual Machine

You mean implementations, not retargettings.

The non-deterministic nature of finalization has long been bemoaned by Java developers, it is a welcome change to see that this will not be the case when using C#.

Ah, you didn't ignore the problems some people have with finalization after all.

Wait.... Why am I reading this article anyway? I got work to do. If i'm bored later maybe I'll continue. (note to self: at delegates) Dave

Another language flame warrior (3.60 / 5) (#105)
by Carnage4Life on Mon Nov 19, 2001 at 10:54:35 PM EST

You don't disginguish between checked and unchecked exceptions (apperently C# has no checked exceptions).

There's a section devoted to the lack of checked exceptions in C#.

Compilation for C# seems to require annoyingly longer commands

I use Makefiles to compile my programs so the length of compiler arguments is never an issue for me and I doubt it should be one for anyone who is competent with a build system such as ant or make.

float fArray[] = new float[100]; //valid, but isn't clear that fArray is an object of type float[]

Cute. I haven't commented on ugly looking C# syntax. Where was that one on sychronized methods...

Oh yeah, this article doesn't seem to differentiate what is possible and what is a good idea Cute. I haven't commented on ugly looking C# syntax. Where was that one on sychronized methods...


Your petulant sniping makes you sound like a novice programmer who becomes upset when his first language isn't universally embraced by all as the greatest thing since sliced bread. Once you learn enough programming languages you'll be embarassed at how religious you about were about syntactic features especially the bad ones in your language of choice when you first started programming.

We've all gone through this stage. Since it looks like your post was just a troll attempting to draw me into yet another pointless language flame war, I'll have to end this thread and this post prematurely since I have better things to do with my time.

[ Parent ]
When In Doubt, Attack the Poster (none / 0) (#130)
by daveq on Tue Nov 20, 2001 at 08:37:53 PM EST

I use Makefiles to compile my programs so the length of compiler arguments is never an issue for me and I I purposely did not bring build tools into the play because I didn't want to feel rude attacking C# for having basically no 3rd party software to support it. I religiously use Ant and many such programs that won't be available for C# for many years. I am indeed no novice. While I don't know Visual C++ and Microsoft propriatary hell, I speak Java, C++, C, Perl, Php, Python, Moterola 68k Assembler, and a few novelty languages enough to understand their relitive merits. Your petulant sniping makes you sound like a novice programmer who becomes upset when his first language isn't universally embraced by all as the greatest thing since sliced bread. Once you learn enough programming languages you'll be embarassed at how religious you about were about syntactic features especially the bad ones in your language of choice when you first started programming.

We've all gone through this stage. Since it looks like your post was just a troll attempting to draw me into yet another pointless language flame war, I'll have to end this thread and this post prematurely since I have better things to do with my time. Yet another of your attempts to avoid all attacks by calling them novice trolls who won't accept any other languages. I am mearly annoyed that you are passing such an incredibly one-sided article for a comparison. You call it a comparison to Java, yet it would best be characterized by a description of C# and where it is better than Java -- evidenced by the fact that you include many more C# examples than Java ones. Anyway, there's no point in arguing with someone who's trapped in a corner and unwilling to give any ground, so I won't visit this thread again either.

[ Parent ]

P.S. (none / 0) (#131)
by daveq on Tue Nov 20, 2001 at 08:42:58 PM EST

when you first started programming.

Actually I first started programming with JavaScript (for HTML) and then C++ (in school). Once I got to know Java, I quickly learned to love all of it's benefits over C++ (hell, with the lack of standards I'm not even sure you can call C++ a language).

[ Parent ]

Lack of C++ standards? (none / 0) (#132)
by Carnage4Life on Tue Nov 20, 2001 at 10:24:04 PM EST

Actually I first started programming with JavaScript (for HTML) and then C++ (in school). Once I got to know Java, I quickly learned to love all of it's benefits over C++ (hell, with the lack of standards I'm not even sure you can call C++ a language).

C++ is ISO/ANSI standard while Java is not. What exactly are you talking about?

[ Parent ]
Attacks? Are we at war? (none / 0) (#133)
by Carnage4Life on Tue Nov 20, 2001 at 11:55:43 PM EST

Yet another of your attempts to avoid all attacks by calling them novice trolls who won't accept any other languages.

I don't indulge in flame wars, I engage in enlightened discussion with knowledgeable and competent people.

Since I wrote the article I have received flames from Java people saying the article was too biased towards C# and from C# people claiming it was too biased towards Java. The truth is that many people (like you) read articles like mine with predefined prejudices and are incensed when any statement in the article does not reaffirm your prejudice. I am used to this and quite frankly it bores me to argue with people like you because you refuse to accept anything but total acquiscence of the person you are arguing with to your views.

[ Parent ]
Kudos, Delegates, etc. (3.00 / 2) (#107)
by BlakeCoverett on Mon Nov 19, 2001 at 11:28:11 PM EST

Great article all around. I'm going to pass along pointers to it to a number of my technical friends.

No real quibbles, but a few of things I think would be worth additional coverage:

  • Multicast Delegates - You mention them in passing, but this is one of the areas where a huge amount of manual plumbing code is removed.
  • Async Delegates - The fact that all delegate types can also called asynchronously via their .BeginInvoke()/.EndInvoke() methods is another very powerful aspect of the language.
  • Uncheck Exceptions - Anders was asked about this one at the PDC. The essense of his answer was that they realize it is an issue, but they feel the Java-esque solution is broken. (Primarily because it interoperates so poorly with versioning, but he touched on a few other reasons as well.) They have elected to omit this feature until a better solution can be found rather than introduce baggage that they will not want later.
  • Anonymous Inner Classes - There is no question that this is a useful feature, but as you pointed out the most common use of it in current Java code is to supply event callbacks. Since C# handles this case already with delegates, the lack is less likely to be noticed.

-Blake



Kudos, Delegates, etc. (1.00 / 3) (#108)
by BlakeCoverett on Mon Nov 19, 2001 at 11:28:32 PM EST

Great article all around. I'm going to pass along pointers to it to a number of my technical friends.

No real quibbles, but a few of things I think would be worth additional coverage:

  • Multicast Delegates - You mention them in passing, but this is one of the areas where a huge amount of manual plumbing code is removed.
  • Async Delegates - The fact that all delegate types can also called asynchronously via their .BeginInvoke()/.EndInvoke() methods is another very powerful aspect of the language.
  • Uncheck Exceptions - Anders was asked about this one at the PDC. The essense of his answer was that they realize it is an issue, but they feel the Java-esque solution is broken. (Primarily because it interoperates so poorly with versioning, but he touched on a few other reasons as well.) They have elected to omit this feature until a better solution can be found rather than introduce baggage that they will not want later.
  • Anonymous Inner Classes - There is no question that this is a useful feature, but as you pointed out the most common use of it in current Java code is to supply event callbacks. Since C# handles this case already with delegates, the lack is less likely to be noticed.

-Blake



Kudos, Delegates, etc. (1.00 / 3) (#109)
by BlakeCoverett on Mon Nov 19, 2001 at 11:28:49 PM EST

Great article all around. I'm going to pass along pointers to it to a number of my technical friends.

No real quibbles, but a few of things I think would be worth additional coverage:

  • Multicast Delegates - You mention them in passing, but this is one of the areas where a huge amount of manual plumbing code is removed.
  • Async Delegates - The fact that all delegate types can also called asynchronously via their .BeginInvoke()/.EndInvoke() methods is another very powerful aspect of the language.
  • Uncheck Exceptions - Anders was asked about this one at the PDC. The essense of his answer was that they realize it is an issue, but they feel the Java-esque solution is broken. (Primarily because it interoperates so poorly with versioning, but he touched on a few other reasons as well.) They have elected to omit this feature until a better solution can be found rather than introduce baggage that they will not want later.
  • Anonymous Inner Classes - There is no question that this is a useful feature, but as you pointed out the most common use of it in current Java code is to supply event callbacks. Since C# handles this case already with delegates, the lack is less likely to be noticed.

-Blake



Kudos, Delegates, etc. (1.00 / 3) (#110)
by BlakeCoverett on Mon Nov 19, 2001 at 11:29:45 PM EST

Great article all around. I'm going to pass along pointers to it to a number of my technical friends.

No real quibbles, but a few of things I think would be worth additional coverage:

  • Multicast Delegates - You mention them in passing, but this is one of the areas where a huge amount of manual plumbing code is removed.
  • Async Delegates - The fact that all delegate types can also called asynchronously via their .BeginInvoke()/.EndInvoke() methods is another very powerful aspect of the language.
  • Uncheck Exceptions - Anders was asked about this one at the PDC. The essense of his answer was that they realize it is an issue, but they feel the Java-esque solution is broken. (Primarily because it interoperates so poorly with versioning, but he touched on a few other reasons as well.) They have elected to omit this feature until a better solution can be found rather than introduce baggage that they will not want later.
  • Anonymous Inner Classes - There is no question that this is a useful feature, but as you pointed out the most common use of it in current Java code is to supply event callbacks. Since C# handles this case already with delegates, the lack is less likely to be noticed.

-Blake



C# From A Java Developer's Perspective | 134 comments (121 topical, 13 editorial, 0 hidden)
Display: Sort:

kuro5hin.org

[XML]
All trademarks and copyrights on this page are owned by their respective companies. The Rest © 2000 - Present Kuro5hin.org Inc.
See our legalese page for copyright policies. Please also read our Privacy Policy.
Kuro5hin.org is powered by Free Software, including Apache, Perl, and Linux, The Scoop Engine that runs this site is freely available, under the terms of the GPL.
Need some help? Email help@kuro5hin.org.
My heart's the long stairs.

Powered by Scoop create account | help/FAQ | mission | links | search | IRC | YOU choose the stories!