You're the one who brought up assembler, and expanded the topic beyond just objects in Java. So, no, that's not just what we're talking about -- we're talking about the *concept* of pass-by-reference, and then applying that to Java. You've expanded the scope of the discussion, so it's ingenuous for you to try to narrow it back down again.
Your "fix" to the provided code merely demonstrates that you are unfamiliar with the concept of pass-by-reference, and thus are not qualified to hold an opinion on the subject. Please go and take an introduction to programming course from a reputable institution. This is a concept any second-year computer-science student should have been exposed to.
You keep getting hung up on where the objects are created, instead of paying attention to variables and parameters.
Seriously, did you even bother to run the code? And then contrast that with a language that is acknowledged to have pass-by-reference semantics?
Objects are never placed on the stack - which is where parameter "passing" takes place. It's always been like that, even back in the days of assembler..
Um, there are conventions where no stack is used to pass parameters. An when you get to the level of writing assembler, a stack is purely optional. So, no, even back in the days of assembler, parameter passing was not necessarily done with a stack. Even now, passing parameters in registers is an acceptable convention on register-rich hardware.
At this level, it's best to think of Java as having nine primitive types: boolean, character, byte, short integer, integer, long integer, float, double, and object pointer (or object reference, but that just leads to confusion when talking about pass-by-reference). When you "pass an object" to a method in Java, you actually pass the _value_ of the object pointer to the method.
When you use a language with "actual" pass-by-reference semantics, there are certain behaviors you expect to see, such as the one I described. We do not see those behaviors in Java.
Just because the object reference is automatically dereferenced in Java doesn't mean that we can get away with saying that "Everything is passed by value", since object never are passed by value.
Actually, we can.
If the language didn't actually allocate an object pointer variable distinct from the object itself, I'd concede your point. In that case, the memory location aliased by a variable would be the actual object, and that would arguably be a pass-by-reference language. It would also be a noticeably different language.
Seriously, show me how to write a method in Java that sets the parameters in the calling scope to null, and I'll agree with you.
e.g.,
Object s = "can't touch this";
Object t = new Object();
foo( s , t );/* at this point, s and t should both be null */
I've never been able to figure out a way to do this in Java.
And that's why I call Java a pass-by-value language.
Anyone who does not appreciate what JEE brings to the table is not a serious enterprise developer.
I *appreciate* what J2EE brings to the table.
That doesn't mean I _like_ it.
I generally agree with your list (with AJAX and WSDL being a notable exception; those are flaws, not a features, but the evils of AJAX and WSDL are another discussion entirely), but feel that it misses an important point: J2EE is just nasty.
It's like C++ -- the *list* of features does not mitigate the sheer soul-draining/wrongness/. And like C++, it's a reasonable "early effort", and we're now at the point of needing someone to look at J2EE with a critical and analytical eye, and to devise for J2EE what Java was to C++: something, while perhaps not perfect, is a few orders of magnitude *better*.
Your list is an important place to start, if not in actual features, then in issues addressed by those features that any successor *must* address just to get a seat at the table.
In C++, when you overload an operator, you change the order of precedence for that operator. This can result in some very annoying bugs.
Before I ever jump on the "operator overloading is a good thing" bandwagon, I'd like to see it done right in a language, somewhere. Until that time, the preponderance of the evidence, to me, is that unrestricted operator overloading isn't worth the trouble it brings with.
I have a sneaking suspicion that to do operator overloading "right", you'll have to implement a field.
Everything in Java is passed by value. And every object variable is a reference.
Those two statements are mutually exclusive:-)
Objects are passed by reference, which means that NOT everything is passed by value. Only the reference to the object is passed by value:-)
This is what happens when you don't start students with Pascal and give them proper training in what lexical scope really means.:)
Let's cover the basics, shall we?
Variables are aliases for memory locations.
When we say "pass by value", I mean that the _value_ of a variable is passed to the subroutine.
When we say "pass by reference", I mean that the _location_ of a variable is passed to the subroutine.
Java is a pass-by-value language, with one of the types being an "object-reference". When I pass such a type to a subroutine (method), the *value* of the variable is passed, and/not/ the location of the variable.
If Java were a pass-by-reference language, then the output of:
public class IfJavaWereAPassByReferenceLanguage {
public static void main( String [] args ) {
String s = "Hello ";
System.out.print( s );
foo( s );
System.out.println( s );
}
But it isn't, so Java isn't a pass-by-reference language. It helps to draw a picture. It can take a bit of effort to understand what's going on for some people, but drawing a picture of what's actually going on helps a lot.
You're passing in a "type" flag in an object-oriented language and you consider that to be a "clean" design? Your aesthetic is *vastly* different from mine.
When I'm programming in an OO language, I strive to eliminate type flags (you have a means of type-selection -- the object system. use it!), switches, or nested conditionals.
I guess that's why there's so much noise and fury about desirable or undesirable features in languages -- some of the idioms used by one group are anti-patterns to another group, and, arguably, vice-versa. Presumably, the goals of OO are different as well -- is it to be used primarily to organize the code for clarity and maintainability, or is it to be used to maximize code reuse?
Many of the "improvements" to Java were done without the thought necessary to make them work right, such as the Generics capability.
However, I disagree about the problem of abstract static methods. I have come to dislike static methods and would prefer to see their use limited *further*, since much of the absolutely terrible code I've had to deal with over the years has been a result of the (ab)use of static methods.
Many colleges teach Java as a good first language, as the perceived alternative is C++, which is a terrible first language for anyone. Java's not a good first language, but it's by no means the worst.
Java Generics are indeed a total hack, which is a result of trying to cram features into a language without thinking through the consequences. Generics were the cool thing, therefore, to remain relevant, Java must have Generics... and thus we get this festering sore on the language.
I do not agree with the analysis for abstract static methods. In the Java object model, the concept makes no sense (unlike, say, Smalltalk), and, indeed, is arguably worse than useless. A great deal of the terrible code that I've run across over the years has been a direct result of programmers favoring static methods with only the shakiest of justifications.
It's true that meta-programming is awkward, but in the languages where it isn't, and is heavily used, I fail to see a significant improvement in code readability or maintainability. It allows for clever techniques that can be extremely difficult to debug, much less understand from reading the source code. Awkwardness in this domain is a disincentive, which is arguably a good thing.
Exception handling is awkward... and arguably more informative than in any other language in common use. Some languages allow the exception handler to "fix" the problem and resume, which is amazing and powerful and wonderful... until you discover a programmer who uses this capability for mixins and flow control, making the code virtually impossible to follow.
But then, I'm one of those throwbacks who consider having to use a debugger to develop or read code to be a bad thing. Code is a form of literature, not a performance art.
Multiple inheritance is an abomination.
Not all types being object is a wart, and not a significant one. Autoboxing is a hack that's worse than the flaw it attempts to hide.
Java is a language full of flaws, but when one tries to envision a replacement language, one needs to consider not its flaws, but what it did *right*, and/why/ that design decision was right for the language. (I assert that what's "right" may be different in the context of a different language; "these are my favorite things" is a poor way to assert what's right.)
In my opinion, some of the things Java did that was right was:
1) It ran on several platforms. MSWindows was the dominant desktop environment, and it sucked, and sucked hard. The more useful systems (Solaris and Linux at first) were far nicer for developers, but those systems weren't what the users and managers were using. Java could be developed on the hippie's Linux box, tested on the corporate Solaris server, and demonstrated to the manager on his MSWindows desktop.
That's a huge win. Nobody feels that the language chosen is being used to force someone else's environment on everyone else.
2) It supported concurrent programming out of the box. Most of the time, in most of the code, there's not a need to handle threaded or concurrent code. But in that window where it is useful to separate tasks into concurrent threads of execution -- such as keeping the database-access code out of the GUI drawing thread -- it's made vastly simpler in Java.
And given that MSWindows at the time had a laughable concurrency model, Java's ability to bring this sort of concurrency to Java was *very* attractive. You didn't have to rewrite the algorithms developed on a UNIX-type machine to handle the broken MSWindows environment, which ties into
Cite, please, Gosling admitting that interfaces were (probably) a mistake. They're one of my favorite features of the language, especially when the time comes to work with other developers. In my experience, a well-defined interface reduces integration time and coupling, while multiple inheritance increases 'em.
(To be fair, the increased integration time and coupling problems might have been due to other features of C++.)
I emphatically *don't* want a C++ style macro compiler or include system. That leads to incomprehensible and unmaintainable code. Been there, done that, got burned. Java's biggest selling point was that it wasn't C++. Java's biggest failings are when it tries to ape C++.
I disagree. Driving is *always* fun. Well, at least when it's more than just a couple of minutes, or you have a sprained ankle, etc.:)
but most of what people have to use cars for is serious and boring. sitting in rush hour traffic isn't fun, driving to and from the same place every day for a decade isn't fun.
I dunno.
Serious, maybe. boring? Only if you're not having fun.
(To be clear, I'm not thinking of "fun" as "playful", but as "enjoyable" or "satisfying".)
Granted, on rush hours. I don't like rush hours, so I adjust my schedule and route to avoid them.
And driving to and from the same place every day *is* fun. You need to pick a route (or routes) that avoids things you/don't/ enjoy.
some of us just want them as tools which do something useful.
I just don't understand this thinking. I want my tools to be enjoyable to use, appropriate to the task, reliable, *and* useful. I don't have one hammer in my toolbox, I have six hanging on the pegboard on the wall.
I can't afford six cars, nor do I have a garage big enough if I could.
Except the track isn't the sort of fun I'm talking about. Track days may be exciting, but they're also stressful, expensive, exhilarating, amusing, harrowing, and potentially embarrassing.
And you don't buy a horse just to ride it, unless you've got a ton of extra cash going to waste. You buy a horse because it's an obsession.
Thus, your analogy works, because the sort of people who are THAT obsessed with driving are the guys who like spending their weekends at the track (aka ranch) and messing about with their cars (horses) every evening during the week.
I wouldn't be one of them. I like road trips.
Next up, let's get a Trusted Computing Platform out there, and bring the price of computers that allow you to compile your own OS up to the $50k range. After all, that's not really necessary, and it would be much safer if almost everyone stopped using the Internet from untrusted computers.
Bah. You aren't driving, you're just riding in a box. You don't even need to own it -- you can just rent it for you trip.
We already have that. We call them "cabs".
And they're sometimes useful.
Which may be the way to sell this, more than "it's a car you don't have to drive!". Why bother? The *point* of owning a car is to drive it. Driving is *fun*.
(And if it isn't, please, please, please take the bus, train, or trolley. If you don't enjoy driving, you're not going to be paying attention, which, frankly, makes you part of the problem.)
The problem with driverless cars is not that they're going to be unsafe, but that they're basically useless. We HAVE means of transporting people so that they don't have to pay attention already.
And yet we still own cars. Why? Because they're _fun_. Who's going to drop US$50,000 on a car that they don't get to drive?
I would find Tesla's case a lot more convincing if they had something more than computer logs. Perhaps they should get some of the BBC employees who were there at the track that day to give sworn statements as to their perception of what happened.
(Not that human testimony is all that reliable, but corroboration with some other source would seem necessary.)
At the moment it's a he-said-she-said argument. The BEST approach would be for Tesla to offer a rematch, and to have a couple of Tesla-certified technicians on hand to diagnose any problems, lest some idiot jump to the wrong conclusion on account of some idiot light on the dashboard lighting up at an inopportune time.
After all, that's the scientific method, isn't it? When you have a dispute, run the test again, and verify the results.
Surely nobody objects to the scientific method *here*.
Actually, I by far prefer to have a deployment environment different from my development environment.
Some of the biggest causes of crappy applications (once you eliminate idiot developers and insane management, of course) are the assumptions we bring to the table. When your development environment differs from your deployed environment, you learn to identify and document the hidden dependencies of your application, which sucks in the short run but is a huge win in the long run.
Want to deploy to a RedHat linux box? Develop on a Mac, do the integration/systems testing on a Debian box, and then do the acceptance testing on a RedHat box. You'll expose hidden dependencies early on, and make explicit the assumptions you're making about the environment you expect to be in.
Which just makes the application that much better.
Why is there this assumption that an ISP will give out more than one (or five) IPv6 address(es) per account? (Especially in the US, where charging for SMS messages is acceptable, even though they're effectively zero-cost on the providers.)
Whining about how NAT breaks stuff like FTP misses an important point: FTP and friends are fundamentally broken. People who have invented protocols since the invention of NAT who adopted the FTP model are guilty of being egregiously stupid.
Logging into a firewall / NAT-box to open up a port through to a specific machine is not difficult. The advent of networked games showed us that it's well within the capabilities of non-technical people to properly configure their firewall/NAT systems to accomplish this.
NAT is a fact of life, like DHCP, and it isn't going away. IPv6 won't kill NAT, it won't kill DHCP, and it won't magically make poorly-designed VOIP systems work (better).
There's no particularly good reason for my network to look like more than one computer to anyone outside my network. There are very good reasons for one of my computers to look like several distinct computers within my network.
IPv6 won't change this. All it will do is (a) make me set up DNS for my local network, because it's not practical to try to remember an arbitrary IPv6 address, and (b) make me set up a subnet with a translation proxy, so my network-capable embedded devices and "legacy" computer systems can still use the network. We're still going to have NAT, we're still going to have DHCP, and very likely, we're still going to only have a small number of internet-accessible IP addresses.
I work with someone like that. He hits a lot of keys in a very short period of time... but almost half of them are the backspace key, because he almost never hits the key he wants to hit.
It sounds like he's getting a lot of work done. If you look over his shoulder, you might find out he's spent the past five minutes trying to scp his editor's configuration file from one machine to another.
Perl... now Perl isn't always terribly friendly on a touch-typist. But maybe that's just because I haven't mastered the opposite-hand-shift like I should.
A moderate typing speed suffices. Say, oh, 30wpm, or thereabouts?
If you're not typing at a reasonable speed, you're going to have an incentive to shorten variable and function/method names from something reasonable to something cryptic. You're going to avoid typing documentation, or worse, propose that your cryptic POS code is 'self documenting'. You're going to be an unpleasant partner if you end up pair-programming. All this means you're not only affecting/your/ productivity, but you're now negatively affecting the productivity of others -- all because you're too damn lazy to learn to type.
It's not really about raw speed. Typing should be an unconscious reflex... you want words and symbols to appear on the screen, and they should do so, without you having to think about it. That way you can think about the problem at hand, and not about the act of entering the code to solve the problem.
If a bank only lets you connect via one OS/browser combo, you are effectively co-opted into the software ecosystem as designed by the bank- it's all their system.
I agree. I disallow any client-side code to run in my browser, and that makes it difficult or impossible to use many financial websites (not because allowing it would be more secure, but because the developers of the website go out of their way to make it that way).
Responsibility needs to go hand-in-hand with the power to make a decision; if a bank requires particular combinations of software, or disallows my preferred security policies, then it's their decision, and should be their responsibility. If the bank merely recommends software, but doesn't seek to subvert my security policy, then yes, faults in my security policy are my own damn fault.
The only way you could do what you want to do is to set up some kind of tunnel on a routable host. Both sides of the link would connect out to the proxy, and then the proxy would forward packets between the connections. It would work, but only with a lot of hacking. It would be difficult to use standard web tools and your aunt edna definitely couldn't connect to your home web server...
The problem with asserting that some solution is the only way is that the assertion is hard to prove (and often not true). It's a sign of arrogance, just like the old-time "we might as well close the patent office because everything worthwhile has been invented" thinking we like to laugh at.
NAT at the ISP level can be done and still leave me the ability to connect to my home server, all without some external proxy. Figuring out how is a matter of taking off the evangelical hat and putting on an engineer's hat. Here's the problem, here's the constraints, find a solution.
Remember that network communication is almost never IP to IP. We use UDP or TCP on top of IP.
When your browser connects to a web server, the packets are identified by a 5-tuple: source ip, destination ip, protocol, source port, and destination port.
So one possible solution (that we may not like) is this:
The ISP sets up a NAT. You, as a customer, are assigned a static non-routable IP address, and a set of ports that will be reserved for your use alone. Let's say that the ISP has been assigned 123.45.67.89 for its IP address, and you're given 10.11.12.13 for your (internal-to-the-ISP) IP address, plus they've assigned ports 2037-2044 to you. Anyone connecting to 123.45.67.89:2040 will be connected to 10.11.12.13:2040.
If TWO people connect to 10.11.12.13:2040, that's okay, because if the source addresses are different or the source ports are different, there's no ambiguity. If ONE person connects twice to 10.11.12.13:2040, their ISP can ensure that separate source ports are used, and so there is still no ambiguity.
One problem with this scheme is that the source-ports will quickly become exhausted.
But there's no reason why the ISP can't re-used source ports as well. When you connect to two different web-servers (i.e., separate IPs), there's no reason why the ISP can't re-use the source-port. It's a different connection, after all, so there's still no ambiguity, at least not until you open up two parallel connections to the same server. At that point, the ISP will need to allocate another source-port to handle the connection. And, of course, that source-port doesn't have to be reserved for your use alone -- the ISP can re-use that port all day long, so long as the 5-tuple is unique.
Sure, it's hairy. And ugly. And will piss off a lot of people. But it will work good enough, most of the time. It'll fall over in pathological situations, but what doesn't?
How can you expect users to reliably and _correctly_ make piecemeal decisions on what can or cannot be done?
I don't. I expect the technically advanced users to do so. I expect the technically mediocre users to play around with it. And I expect the technically unsophisticated users to download pre-packaged "adjustments" from trusted communities and repositories, or to ignore the whole thing and just blindly trust everything.
The point is... they have a choice. Just as we say they have a choice with open-source software -- they can, if they choose to, and have the expertise, examine and modify the source code; the fact that they may not be able to do so reliably does not diminish the value of open-source software.
Further, given that technically astute folks could easily "fix" broken scripting, we could avoid some of the more egregious obnoxiousness that comes from arrogant developers. Client-side authentication would be a favorite target, but right after that would be client-side checking of browsers and/or operating systems (don't you get annoyed when a website checks for your browser and tells you that you must upgrade to IE7 or better?), and all sorts of brain-dead scripting tricks.
Eventually, when the client-side inanities prove to have no actual effect, we can hope they'll just go away. Instead of putting a test in the script to verify that only $developers_favorite_browser is being used, a developer would just write the script, test it on a couple of mainstream browsers, and let the user communities for the less-popular browsers "fix" the scripts. Ideally, good fixes could be rolled back into the production scripts, leading to better code all around, and perhaps
websites that work without javascript being enabled at all.
I would not expect my parents to inspect the code. I would like the ability to check out websites that are giving them grief, and devise a set of patches for the lame/broken/stupid scripts, and thus ease their pain. Lessen their annoyance. Maybe give them something cooler than what's on the stock website.
Have templates of sandboxes. Deny the unsafe/unnecessary actions by default.
So far as I'm concerned, it's all unsafe and unnecessary. And yet, deleting or disabling those actions causes a bit of grief -- not on the better class of websites, that degrade gracefully -- to the point where it seems that a lot more websites are dealing with the problem of "your website sucks without scripting enabled" with "test for scripting, and then berate the user if they won't enable it".
So I don't see how better or different sandboxes would help. Perhaps I'm misunderstanding your point.
Disk is not cheap in a laptop, either in financial terms or in space/heat/power terms.
Sure it is.
My old laptop had a 30GB disk (I still have 9-10GB free), and my new laptop cost a third less, and came with an 80GB disk. Believe me, compared to what it used to be, disk is cheap, in financial, space, heat, and power terms. And it is only getting cheaper.
Plus, nothing in my scheme required that you disable scripting for all websites; if you want to run wide-open and trousers-down, that's your business; no additional disk space required.
The problem is that those of us who would like a LITTLE more sanity in our browsers don't get that choice. We can disable everything, or we can use the crude approximation of assurance with tools like NoScript and Muffin, or we can give up and turn everything on and pray really hard every night that nothing bad will ever happen to us.
Just how much Javascript do you download and run in a day, if the disk requirements for my little scheme are significant? Or is your objection a knee-jerk reaction to the "disk is cheap" meme?
Why is everyone in love with checksums?
Disk is cheap
But bandwidth, less so.
Yes, but if you're enabling scripting, you've already downloaded the scripts. If you're downloading replacement recipes, that's a single-time effort. I'm NOT advocating that a browser should go to some other site to check to see if it should replace the current web-page's scripts... that would be wasteful of bandwidth.
There's also a copyright issue. If the noscript people start distributing Google's gmail scripts, they leave themselves open to a cease & desist letter or a lawsuit. Distributing just a hash makes it easier to argue that.
Good point; getting mixed up in the copyright debate is not something that will help this. URL + function name + hash would be sufficient identification for the "key", especially if the hash was generated from some tokenized representation that could handle formatting changes, comments, and variable renames.
If it didn't come with a whitelist it would be much better, but then even fewer people would use it.
Yah, the first thing I do with noscript is to eviscerate the default whitelist. I thought we learned that "default on" configurations were a bad idea in the 90s, but I guess each generation has to relearn the lessons of the past the hard way.
It does seem likely, but it's not completely given that dynamically-generated scripts are malicious.
If enough people presume that dynamically-generated scripts are malicious, they will be. Consider web-bugs -- they CAN be innocuous, but nobody I know of (aside from the marketing weenies) considers them anything but underhanded.
At a minimum, if you DO trust a site that dynamically generates a unique script every time you connect, you should at least have a way of finding out without having to "view source" every time to hit that website.
You're the one who brought up assembler, and expanded the topic beyond just objects in Java. So, no, that's not just what we're talking about -- we're talking about the *concept* of pass-by-reference, and then applying that to Java. You've expanded the scope of the discussion, so it's ingenuous for you to try to narrow it back down again.
Your "fix" to the provided code merely demonstrates that you are unfamiliar with the concept of pass-by-reference, and thus are not qualified to hold an opinion on the subject. Please go and take an introduction to programming course from a reputable institution. This is a concept any second-year computer-science student should have been exposed to.
You keep getting hung up on where the objects are created, instead of paying attention to variables and parameters.
Seriously, did you even bother to run the code? And then contrast that with a language that is acknowledged to have pass-by-reference semantics?
It doesn't look that way to me. :(
Um... what?
Are you sure you meant to write "immutable" here?
Um, there are conventions where no stack is used to pass parameters. An when you get to the level of writing assembler, a stack is purely optional. So, no, even back in the days of assembler, parameter passing was not necessarily done with a stack. Even now, passing parameters in registers is an acceptable convention on register-rich hardware.
At this level, it's best to think of Java as having nine primitive types: boolean, character, byte, short integer, integer, long integer, float, double, and object pointer (or object reference, but that just leads to confusion when talking about pass-by-reference). When you "pass an object" to a method in Java, you actually pass the _value_ of the object pointer to the method.
When you use a language with "actual" pass-by-reference semantics, there are certain behaviors you expect to see, such as the one I described. We do not see those behaviors in Java.
Actually, we can.
If the language didn't actually allocate an object pointer variable distinct from the object itself, I'd concede your point. In that case, the memory location aliased by a variable would be the actual object, and that would arguably be a pass-by-reference language. It would also be a noticeably different language.
Seriously, show me how to write a method in Java that sets the parameters in the calling scope to null, and I'll agree with you.
e.g.,
Object s = "can't touch this"; /* at this point, s and t should both be null */
Object t = new Object();
foo( s , t );
I've never been able to figure out a way to do this in Java.
And that's why I call Java a pass-by-value language.
I *appreciate* what J2EE brings to the table.
That doesn't mean I _like_ it.
I generally agree with your list (with AJAX and WSDL being a notable exception; those are flaws, not a features, but the evils of AJAX and WSDL are another discussion entirely), but feel that it misses an important point: J2EE is just nasty.
It's like C++ -- the *list* of features does not mitigate the sheer soul-draining /wrongness/. And like C++, it's a reasonable "early effort", and we're now at the point of needing someone to look at J2EE with a critical and analytical eye, and to devise for J2EE what Java was to C++: something, while perhaps not perfect, is a few orders of magnitude *better*.
Your list is an important place to start, if not in actual features, then in issues addressed by those features that any successor *must* address just to get a seat at the table.
Very true.
In C++, when you overload an operator, you change the order of precedence for that operator. This can result in some very annoying bugs.
Before I ever jump on the "operator overloading is a good thing" bandwagon, I'd like to see it done right in a language, somewhere. Until that time, the preponderance of the evidence, to me, is that unrestricted operator overloading isn't worth the trouble it brings with.
I have a sneaking suspicion that to do operator overloading "right", you'll have to implement a field.
This is what happens when you don't start students with Pascal and give them proper training in what lexical scope really means. :)
Let's cover the basics, shall we?
Variables are aliases for memory locations.
When we say "pass by value", I mean that the _value_ of a variable is passed to the subroutine.
When we say "pass by reference", I mean that the _location_ of a variable is passed to the subroutine.
Java is a pass-by-value language, with one of the types being an "object-reference". When I pass such a type to a subroutine (method), the *value* of the variable is passed, and /not/ the location of the variable.
If Java were a pass-by-reference language, then the output of:
public class IfJavaWereAPassByReferenceLanguage {
public static void main( String [] args ) {
String s = "Hello ";
System.out.print( s );
foo( s );
System.out.println( s );
}
public static void foo( String reference ) {
reference = "World";
}
}
would be "Hello World".
But it isn't, so Java isn't a pass-by-reference language. It helps to draw a picture. It can take a bit of effort to understand what's going on for some people, but drawing a picture of what's actually going on helps a lot.
You're passing in a "type" flag in an object-oriented language and you consider that to be a "clean" design? Your aesthetic is *vastly* different from mine.
When I'm programming in an OO language, I strive to eliminate type flags (you have a means of type-selection -- the object system. use it!), switches, or nested conditionals.
I guess that's why there's so much noise and fury about desirable or undesirable features in languages -- some of the idioms used by one group are anti-patterns to another group, and, arguably, vice-versa. Presumably, the goals of OO are different as well -- is it to be used primarily to organize the code for clarity and maintainability, or is it to be used to maximize code reuse?
Many of the "improvements" to Java were done without the thought necessary to make them work right, such as the Generics capability.
However, I disagree about the problem of abstract static methods. I have come to dislike static methods and would prefer to see their use limited *further*, since much of the absolutely terrible code I've had to deal with over the years has been a result of the (ab)use of static methods.
Many colleges teach Java as a good first language, as the perceived alternative is C++, which is a terrible first language for anyone. Java's not a good first language, but it's by no means the worst.
Java Generics are indeed a total hack, which is a result of trying to cram features into a language without thinking through the consequences. Generics were the cool thing, therefore, to remain relevant, Java must have Generics... and thus we get this festering sore on the language.
I do not agree with the analysis for abstract static methods. In the Java object model, the concept makes no sense (unlike, say, Smalltalk), and, indeed, is arguably worse than useless. A great deal of the terrible code that I've run across over the years has been a direct result of programmers favoring static methods with only the shakiest of justifications.
It's true that meta-programming is awkward, but in the languages where it isn't, and is heavily used, I fail to see a significant improvement in code readability or maintainability. It allows for clever techniques that can be extremely difficult to debug, much less understand from reading the source code. Awkwardness in this domain is a disincentive, which is arguably a good thing.
Exception handling is awkward... and arguably more informative than in any other language in common use. Some languages allow the exception handler to "fix" the problem and resume, which is amazing and powerful and wonderful... until you discover a programmer who uses this capability for mixins and flow control, making the code virtually impossible to follow.
But then, I'm one of those throwbacks who consider having to use a debugger to develop or read code to be a bad thing. Code is a form of literature, not a performance art.
Multiple inheritance is an abomination.
Not all types being object is a wart, and not a significant one. Autoboxing is a hack that's worse than the flaw it attempts to hide.
Java is a language full of flaws, but when one tries to envision a replacement language, one needs to consider not its flaws, but what it did *right*, and /why/ that design decision was right for the language. (I assert that what's "right" may be different in the context of a different language; "these are my favorite things" is a poor way to assert what's right.)
In my opinion, some of the things Java did that was right was:
1) It ran on several platforms. MSWindows was the dominant desktop environment, and it sucked, and sucked hard. The more useful systems (Solaris and Linux at first) were far nicer for developers, but those systems weren't what the users and managers were using. Java could be developed on the hippie's Linux box, tested on the corporate Solaris server, and demonstrated to the manager on his MSWindows desktop.
That's a huge win. Nobody feels that the language chosen is being used to force someone else's environment on everyone else.
2) It supported concurrent programming out of the box. Most of the time, in most of the code, there's not a need to handle threaded or concurrent code. But in that window where it is useful to separate tasks into concurrent threads of execution -- such as keeping the database-access code out of the GUI drawing thread -- it's made vastly simpler in Java.
And given that MSWindows at the time had a laughable concurrency model, Java's ability to bring this sort of concurrency to Java was *very* attractive. You didn't have to rewrite the algorithms developed on a UNIX-type machine to handle the broken MSWindows environment, which ties into
Cite, please, Gosling admitting that interfaces were (probably) a mistake. They're one of my favorite features of the language, especially when the time comes to work with other developers. In my experience, a well-defined interface reduces integration time and coupling, while multiple inheritance increases 'em.
(To be fair, the increased integration time and coupling problems might have been due to other features of C++.)
I emphatically *don't* want a C++ style macro compiler or include system. That leads to incomprehensible and unmaintainable code. Been there, done that, got burned. Java's biggest selling point was that it wasn't C++. Java's biggest failings are when it tries to ape C++.
I disagree. Driving is *always* fun. Well, at least when it's more than just a couple of minutes, or you have a sprained ankle, etc. :)
I dunno.
Serious, maybe. boring? Only if you're not having fun.
(To be clear, I'm not thinking of "fun" as "playful", but as "enjoyable" or "satisfying".)
Granted, on rush hours. I don't like rush hours, so I adjust my schedule and route to avoid them.
And driving to and from the same place every day *is* fun. You need to pick a route (or routes) that avoids things you /don't/ enjoy.
I just don't understand this thinking. I want my tools to be enjoyable to use, appropriate to the task, reliable, *and* useful. I don't have one hammer in my toolbox, I have six hanging on the pegboard on the wall.
I can't afford six cars, nor do I have a garage big enough if I could.
Good point.
Except the track isn't the sort of fun I'm talking about. Track days may be exciting, but they're also stressful, expensive, exhilarating, amusing, harrowing, and potentially embarrassing.
And you don't buy a horse just to ride it, unless you've got a ton of extra cash going to waste. You buy a horse because it's an obsession.
Thus, your analogy works, because the sort of people who are THAT obsessed with driving are the guys who like spending their weekends at the track (aka ranch) and messing about with their cars (horses) every evening during the week.
I wouldn't be one of them. I like road trips.
Next up, let's get a Trusted Computing Platform out there, and bring the price of computers that allow you to compile your own OS up to the $50k range. After all, that's not really necessary, and it would be much safer if almost everyone stopped using the Internet from untrusted computers.
Bah. You aren't driving, you're just riding in a box. You don't even need to own it -- you can just rent it for you trip.
We already have that. We call them "cabs".
And they're sometimes useful.
Which may be the way to sell this, more than "it's a car you don't have to drive!". Why bother? The *point* of owning a car is to drive it. Driving is *fun*.
(And if it isn't, please, please, please take the bus, train, or trolley. If you don't enjoy driving, you're not going to be paying attention, which, frankly, makes you part of the problem.)
The problem with driverless cars is not that they're going to be unsafe, but that they're basically useless. We HAVE means of transporting people so that they don't have to pay attention already.
And yet we still own cars. Why? Because they're _fun_. Who's going to drop US$50,000 on a car that they don't get to drive?
I would find Tesla's case a lot more convincing if they had something more than computer logs. Perhaps they should get some of the BBC employees who were there at the track that day to give sworn statements as to their perception of what happened.
(Not that human testimony is all that reliable, but corroboration with some other source would seem necessary.)
At the moment it's a he-said-she-said argument. The BEST approach would be for Tesla to offer a rematch, and to have a couple of Tesla-certified technicians on hand to diagnose any problems, lest some idiot jump to the wrong conclusion on account of some idiot light on the dashboard lighting up at an inopportune time.
After all, that's the scientific method, isn't it? When you have a dispute, run the test again, and verify the results.
Surely nobody objects to the scientific method *here*.
Actually, I by far prefer to have a deployment environment different from my development environment.
Some of the biggest causes of crappy applications (once you eliminate idiot developers and insane management, of course) are the assumptions we bring to the table. When your development environment differs from your deployed environment, you learn to identify and document the hidden dependencies of your application, which sucks in the short run but is a huge win in the long run.
Want to deploy to a RedHat linux box? Develop on a Mac, do the integration/systems testing on a Debian box, and then do the acceptance testing on a RedHat box. You'll expose hidden dependencies early on, and make explicit the assumptions you're making about the environment you expect to be in.
Which just makes the application that much better.
Why is there this assumption that an ISP will give out more than one (or five) IPv6 address(es) per account? (Especially in the US, where charging for SMS messages is acceptable, even though they're effectively zero-cost on the providers.)
Whining about how NAT breaks stuff like FTP misses an important point: FTP and friends are fundamentally broken. People who have invented protocols since the invention of NAT who adopted the FTP model are guilty of being egregiously stupid.
Logging into a firewall / NAT-box to open up a port through to a specific machine is not difficult. The advent of networked games showed us that it's well within the capabilities of non-technical people to properly configure their firewall/NAT systems to accomplish this.
NAT is a fact of life, like DHCP, and it isn't going away. IPv6 won't kill NAT, it won't kill DHCP, and it won't magically make poorly-designed VOIP systems work (better).
There's no particularly good reason for my network to look like more than one computer to anyone outside my network. There are very good reasons for one of my computers to look like several distinct computers within my network.
IPv6 won't change this. All it will do is (a) make me set up DNS for my local network, because it's not practical to try to remember an arbitrary IPv6 address, and (b) make me set up a subnet with a translation proxy, so my network-capable embedded devices and "legacy" computer systems can still use the network. We're still going to have NAT, we're still going to have DHCP, and very likely, we're still going to only have a small number of internet-accessible IP addresses.
We just won't be able to remember them.
Stop imagining them in their underwear.
I work with someone like that. He hits a lot of keys in a very short period of time... but almost half of them are the backspace key, because he almost never hits the key he wants to hit.
It sounds like he's getting a lot of work done. If you look over his shoulder, you might find out he's spent the past five minutes trying to scp his editor's configuration file from one machine to another.
You think C++ is more concise than Java?
It is to laugh.
Perl... now Perl isn't always terribly friendly on a touch-typist. But maybe that's just because I haven't mastered the opposite-hand-shift like I should.
A moderate typing speed suffices. Say, oh, 30wpm, or thereabouts?
If you're not typing at a reasonable speed, you're going to have an incentive to shorten variable and function/method names from something reasonable to something cryptic. You're going to avoid typing documentation, or worse, propose that your cryptic POS code is 'self documenting'. You're going to be an unpleasant partner if you end up pair-programming. All this means you're not only affecting /your/ productivity, but you're now negatively affecting the productivity of others -- all because you're too damn lazy to learn to type.
It's not really about raw speed. Typing should be an unconscious reflex... you want words and symbols to appear on the screen, and they should do so, without you having to think about it. That way you can think about the problem at hand, and not about the act of entering the code to solve the problem.
I agree. I disallow any client-side code to run in my browser, and that makes it difficult or impossible to use many financial websites (not because allowing it would be more secure, but because the developers of the website go out of their way to make it that way).
Responsibility needs to go hand-in-hand with the power to make a decision; if a bank requires particular combinations of software, or disallows my preferred security policies, then it's their decision, and should be their responsibility. If the bank merely recommends software, but doesn't seek to subvert my security policy, then yes, faults in my security policy are my own damn fault.
The problem with asserting that some solution is the only way is that the assertion is hard to prove (and often not true). It's a sign of arrogance, just like the old-time "we might as well close the patent office because everything worthwhile has been invented" thinking we like to laugh at.
NAT at the ISP level can be done and still leave me the ability to connect to my home server, all without some external proxy. Figuring out how is a matter of taking off the evangelical hat and putting on an engineer's hat. Here's the problem, here's the constraints, find a solution.
Remember that network communication is almost never IP to IP. We use UDP or TCP on top of IP.
When your browser connects to a web server, the packets are identified by a 5-tuple: source ip, destination ip, protocol, source port, and destination port.
So one possible solution (that we may not like) is this:
The ISP sets up a NAT. You, as a customer, are assigned a static non-routable IP address, and a set of ports that will be reserved for your use alone. Let's say that the ISP has been assigned 123.45.67.89 for its IP address, and you're given 10.11.12.13 for your (internal-to-the-ISP) IP address, plus they've assigned ports 2037-2044 to you. Anyone connecting to 123.45.67.89:2040 will be connected to 10.11.12.13:2040.
If TWO people connect to 10.11.12.13:2040, that's okay, because if the source addresses are different or the source ports are different, there's no ambiguity. If ONE person connects twice to 10.11.12.13:2040, their ISP can ensure that separate source ports are used, and so there is still no ambiguity.
One problem with this scheme is that the source-ports will quickly become exhausted.
But there's no reason why the ISP can't re-used source ports as well. When you connect to two different web-servers (i.e., separate IPs), there's no reason why the ISP can't re-use the source-port. It's a different connection, after all, so there's still no ambiguity, at least not until you open up two parallel connections to the same server. At that point, the ISP will need to allocate another source-port to handle the connection. And, of course, that source-port doesn't have to be reserved for your use alone -- the ISP can re-use that port all day long, so long as the 5-tuple is unique.
Sure, it's hairy. And ugly. And will piss off a lot of people. But it will work good enough, most of the time. It'll fall over in pathological situations, but what doesn't?
I really (seriously) wonder why such devices ship with Javascript functionality anyway. Wouldn't a simple malicious script kill 'em dead?
For example, wouldn't
or kill such a device dead?I don't. I expect the technically advanced users to do so. I expect the technically mediocre users to play around with it. And I expect the technically unsophisticated users to download pre-packaged "adjustments" from trusted communities and repositories, or to ignore the whole thing and just blindly trust everything.
The point is... they have a choice. Just as we say they have a choice with open-source software -- they can, if they choose to, and have the expertise, examine and modify the source code; the fact that they may not be able to do so reliably does not diminish the value of open-source software.
Further, given that technically astute folks could easily "fix" broken scripting, we could avoid some of the more egregious obnoxiousness that comes from arrogant developers. Client-side authentication would be a favorite target, but right after that would be client-side checking of browsers and/or operating systems (don't you get annoyed when a website checks for your browser and tells you that you must upgrade to IE7 or better?), and all sorts of brain-dead scripting tricks.
Eventually, when the client-side inanities prove to have no actual effect, we can hope they'll just go away. Instead of putting a test in the script to verify that only $developers_favorite_browser is being used, a developer would just write the script, test it on a couple of mainstream browsers, and let the user communities for the less-popular browsers "fix" the scripts. Ideally, good fixes could be rolled back into the production scripts, leading to better code all around, and perhaps websites that work without javascript being enabled at all.
I would not expect my parents to inspect the code. I would like the ability to check out websites that are giving them grief, and devise a set of patches for the lame/broken/stupid scripts, and thus ease their pain. Lessen their annoyance. Maybe give them something cooler than what's on the stock website.
So far as I'm concerned, it's all unsafe and unnecessary. And yet, deleting or disabling those actions causes a bit of grief -- not on the better class of websites, that degrade gracefully -- to the point where it seems that a lot more websites are dealing with the problem of "your website sucks without scripting enabled" with "test for scripting, and then berate the user if they won't enable it".
So I don't see how better or different sandboxes would help. Perhaps I'm misunderstanding your point.
Sure it is.
My old laptop had a 30GB disk (I still have 9-10GB free), and my new laptop cost a third less, and came with an 80GB disk. Believe me, compared to what it used to be, disk is cheap, in financial, space, heat, and power terms. And it is only getting cheaper.
Plus, nothing in my scheme required that you disable scripting for all websites; if you want to run wide-open and trousers-down, that's your business; no additional disk space required.
The problem is that those of us who would like a LITTLE more sanity in our browsers don't get that choice. We can disable everything, or we can use the crude approximation of assurance with tools like NoScript and Muffin, or we can give up and turn everything on and pray really hard every night that nothing bad will ever happen to us.
Just how much Javascript do you download and run in a day, if the disk requirements for my little scheme are significant? Or is your objection a knee-jerk reaction to the "disk is cheap" meme?
If enough people presume that dynamically-generated scripts are malicious, they will be. Consider web-bugs -- they CAN be innocuous, but nobody I know of (aside from the marketing weenies) considers them anything but underhanded.
At a minimum, if you DO trust a site that dynamically generates a unique script every time you connect, you should at least have a way of finding out without having to "view source" every time to hit that website.