Java is a statically typed language which couldn't care less for type safety
-
-
This is one of the things that makes the JVM completely unfit for purpose as a runtime for a language with a proper static type system. Clojure skirts this issue, thankfully, by way of being a Lisp, and thus dynamically typed; Scala, on the other hand, smacks head-on into type erasure.
Looks like this
threadtopic is infested with the C++IDF and TypeF*****s too. Speaking inflammatorially.Some people think that types are the most important thing in a programming language, and that very strict enforcement of those types is absolutely important in doing programming. Others (including myself) disagree, and are willing to trade a higher likelihood of runtime failure for simplicity of development.
-
Error: ATWOOD_NOT_FOUND?
-
Some people think that types are the most important thing in a programming language, and that very strict enforcement of those types is absolutely important in doing programming. Others (including myself) disagree, and are willing to trade a higher likelihood of runtime failure for simplicity of development.
I have done enough Python and Clojure to appreciate the virtues of dynamic typing; its the people who conflate dynamic typing with PHP/JS-styled 'sloppy typing' who mess the show up for all of us, though.Filed under: dynamic type enforcement is a thing
-
Yeah. Crippling a language in expressiveness simply shifts the complexity from the language into your programs, something that the folks who uphold Java and C# as paragons of simplicity do not understand.
I doubt the language designers intentionally withheld generics from the languages to "cripple their expressiveness". After all, both Java and C# added them in later iterations. I imagine it was because of a combination of a) pressure to get the product to the market and b) the perceived usefulness of generics being deemed less than that of other features, or not worth the effort.
It's not like the Sun/Microsoft just ran "Programming Language Maker VX Ace", ticked some checkboxes for the features they wanted and pressed "Generate". Each feature takes time and effort to design, document and implement.
Don't take me wrong - I would love it of Java had generics (true generics, even), and lambdas, and all the other good things other languages have from the beginning. But I realize that for one thing to be included, another thing would have to be dropped, or the product would have to be delayed. And who knows, perhaps that would be even worse?
TL;DR: it's all capitalism's fault.
-
Some people think that types are the most important thing in a programming language, and that very strict enforcement of those types is absolutely important in doing programming. Others (including myself) disagree, and are willing to trade a higher likelihood of runtime failure for simplicity of development.
Look, I am very pragmatic man. I see programming languages as tools for writing assembly - some languages make better assemblies, some make worse, some are faster to work with, some are slower (extreme case is asm, which is almost literally assembly). I see objects as bunch of bytes that are kept together. I see methods as regular functions with implicit this pointer. I see types as an abstract concept that's meant to help me not shoot myself in a foot, but that has no meaning once the code is compiled to assembly. Dynamic languages are great - they let you do many things in many cool ways, and some tricks can reduce amount of code needed by order of magnitude. But static languages are great too - thanks to the type safeguards, you know you have not accidentally yourself in a foot. An extreme case of this is Haskell - the guards are so strong your code is virtually guaranteed to never crash or do anything (too) wrong. And that's great. Somewhere in the middle of spectre, we have C++ - it's more or less safe, unless someone somewhere did a cast, because then you are fucked unless that person thought about every possible case. Even further, we have Java - which with its type erasure and stuff, basically nullifies any gains of static typing, and at the same time doesn't allow anything that makes dynamic languages good - like adding methods on a whim. Java is where the worst of the two worlds meet.
-
being simpler is actually advantage for the average code monkey
Hm, I see. I didn't express myself well. I should have probably said dumber. Because Java isn't particularly simple. It just isn't expressive. Lisp is simple. Haskell is simple. They are too clever for average code monkey. Javascript is also simple, and easier. On the other end Assembly is the simplest, but totally dumb. Java and C# are not particularly simple. They are just not very clever, especially Java.
Oh go do yourself with a cactus, you fucking elitist. Simple is good. Being able to write code simply results in more code being created and more features being implemented. You want power, go write in assembly - but I guarantee you that a 10-minute scratch program in C# is gonna end up being your lifetime project.
Assembly? The simplest of the simple languages? You really think it has any power? No, it does not.
C# is not bad, but for scratch program I'd go to something that has the whipuptitude like Python (or Ruby or Clojure or Groovy etc.). Something that can express things without a lot of baloney (like declaring bunch of classes and interfaces and stuff). A lot faster to write in than C# (or anything statically typed for that matter).
But if I want manipulexity, I want something with the expressiveness. Java is really bad in this. C# is much better, but has it's limits. Adapting objects is particularly lacking part (proper tool is Haskell type-classes, also called traits in Rust, but in C++ it can be done if your templates are well written, though it's a bit ad-hoc). And while C#'s managed memory makes a lot of things easier, C++'s resource management via RAII can do so much more.
Of course as far as writing something fast goes, good libraries are actually most important. It is what makes Java useful despite the lack of expressiveness of the language itself. C# is actually worse in this regard. It's standard library feels kind of semi-finished to me. The things are there, but it still takes quite a bit of typing to tie them together. Of course in this respect C++ is aeons behind. It has some nice frameworks, but due to coming from different epochs of the language development, they are somewhat difficult to combine. And none of them is as portable as the core language.
Oh, and of course when I want something portable, C++ is the only language. It is a pain in the arse to make a C++ program portable. Huge pain in the arse. But at least it is possible. Some mobile platforms don't run Java, some don't run C# and some don't run either, but there was only one platform that didn't run C++, Windows Phone 7, and they were rather quickly abandoned exactly because lack of C++ prevented many applications from ever being ported.
-
Even further, we have Java - which with its type erasure and stuff, basically nullifies any gains of static typing
Overstating much? Sure, Java's type system is not the most sophisticated one, but it still provides a heckuva lot more safety guarantees than a dynamic language. If you have no unchecked warnings, you're guaranteed that each reference-typed variable references an object of its type (or
null
, but that's another story). And even if you have to do a manual cast, at least the runtime will detect if the cast object is of the wrong type, so the error is likely to be detected promptly.
-
Even further, we have Java - which with its type erasure and stuff, basically nullifies any gains of static typing
There are two benefits of static typing: increased static assurance of correctness and potential for more efficient code. Type erasure has zero impact on the former, because it's done after type checking. I'd hardly say that nullifies any gains.
-
You mention Backward Compatibility, but C# had no problems bolting on Generics after the fact.
Part of the problem is that Java bolted on Generics in places they probably shouldn't have. Why is
Class
generic, for instance?One of the major locations generations are used are Collections. C# did this the smart way: Create new Collections for Generics. Java did this the dumb way: Convert all existing Collections to use Generics and then patch all the related utility methods to allow you to set the generic return type... i.e.
java.util.Collection.<Integer>emptyList()
to get an empty unmodifiableList<Integer>
.
-
Hmm, true, FirefoxOS doesn't support C#.
-
And then it does so anyway with a simple cast, because somebody got pissed off at some compiler error.
That's a feature.
You see, I love robust code with proper separation of concerns and proper isolation so the components can't break each other. But sometimes you just find yourself holding the short end of the stick and then it helps if you can just ask the compiler to let you abuse something. So I don't want to protect against intentional abuse. I want to protect against accidental abuse and
const
helps a lot with that.
-
Not event talking about FirefoxOS. I work on application that runs on Windows CE, Android, iOS, Bada (ok, we are discontinuing that, it is major trouble and minuscule market) and Windows Phone 8. When we started, neither Android nor iOS could do C# (I know Xamarin now has a mono-based runtime for them) and Java was serious problem on WinCE. Not to mention that WinCE 4.2 had 32MiB limit on per-process memory and even the C++ application had hard time fitting in; Java with it's inefficient memory management would never manage. And while Android is mainly Java-based, it has it's own framework anyway, so we woudn't avoid some ugly conditional compilation anyway.
-
ask the compiler to let you abuse something.
How else do you discover compile errors like "I strongly object to casting 'pointer to integer' to 'char'."?
Or the kind of errors that old Apple compiler was known for.
-
Oh, and of course when I want something portable, C++ is the only language. It is a pain in the arse to make a C++ program portable. Huge pain in the arse. But at least it is possible. Some mobile platforms don't run Java, some don't run C# and some don't run either, but there was only one platform that didn't run C++, Windows Phone 7, and they were rather quickly abandoned exactly because lack of C++ prevented many applications from ever being ported.
Good luck running all your fancy managed code on a Tandem (now HP) NonStop running Guardian! C++ works on that platform, though, at least for a certain value of works...
-
No, and those Java fanatics who cannot admit that Java lost massive amounts of expressiveness and conciseness by going noun-fetishist are the crazy people.
Java is not an entity that is capable of sinning. Or making any kind of moral decisions, for that matter. Or making any kind of decision at all, for that matter.
I'm saying you're crazy because you posted the equivalent to, "a tree told me to love Hitler!" That is crazy-talk. From crazy-people.
-
There are two benefits of static typing: increased static assurance of correctness and potential for more efficient code. Type erasure has zero impact on the former, because it's done after type checking.
Correct me if I'm wrong, but doesn't type erasure mean that compiler has no way to statically check type safety of generic containers when interacting with precompiled 3rd-party library?
-
Java is not an entity that is capable of sinning. Or making any kind of moral decisions, for that matter. Or making any kind of decision at all, for that matter
Figurative speech anyone?
-
Something that can express things without a lot of baloney (like declaring bunch of classes and interfaces and stuff). A lot faster to write in than C# (or anything statically typed for that matter).
If you're writing a scratch program in C#, you have one class, which is static. And it's generated by the IDE. (You are using an IDE, aren't you?)
Why the holy fuck would you be writing interfaces (or more than one class) in a scratch program? If you need either, you're way beyond "scratch program."
And while C#'s managed memory makes a lot of things easier, C++'s resource management via RAII can do so much more.
Like what? Name one thing.
Of course as far as writing something fast goes, good libraries are actually most important. It is what makes Java useful despite the lack of expressiveness of the language itself. C# is actually worse in this regard. It's standard library feels kind of semi-finished to me.
Wow, another crazy-person. You think Java's standard library is better than C#s? You should form a club. You could meet in a closet, because it'd only ever have one member.
-
Figurative speech anyone?
No thanks, I just ate. (Am I the only one who hates that 'X, anyone?' language construct you see all over tech forums? Guh. Type like a human. One who doesn't post to Slashdot.)
I'm sure he was using it as a metaphor of some kind, but it's so nonsensical that until he explains it, I'm bucketing it in the crazy bucket.
-
Like what? Name one thing.
Guaranteed, deterministic file or db connection closing without explicit syntax (using
/with
/Java 7try
).
-
Guaranteed file or db connection closing without explicit syntax (using/with/Java 7 try).
So the one thing it can do that C#/Java/etc can't is... a thing C#/Java/etc can easily do-- but with slightly less typing.
Compelling argument.
Do I have to add the word "practical" every goddamned time I ask for an example of something? You guys can just assume I'm asking for a practical example and not just source code wankery.
-
You guys can just assume I'm asking for a practical example and not just source code wankery.
This site is built on source code wankery. You keep forgetting that.
-
So the one thing it can do that C#/Java/etc can't is... a thing C#/Java/etc can easily do-- but with slightly less typing.
I can't tell how much you're trolling vs actually believe what you write. By that logic you might as well not bother usingusing
in C#, because it's just syntactic shortcut for atry/finally{close}
, so why did they bother to introduce it?The point is that
using
makes it easier to do the right thing thantry/finally
, meaning people will make fewer mistakes. C++ makes it even easier to do the right thing. (In fact you almost have to try to get it wrong, as opposed to just forget or not know that a class needs to be closed.)
-
The point is that using makes it easier to do the right thing than try/finally, meaning people will make fewer mistakes. C++ makes it even easier to do the right thing. (In fact you almost have to try to get it wrong, as opposed to just forget or not know that a class needs to be closed.)
Oh, so C++ now enforces RAII? Because that would be an improvement in that mess of bullshit. That would only make 9/10ths of the language unbearable shit.
You keep saying C++ when you mean RAII and it's pissing me off. C++ doesn't make anything but spaghetti bullshit. Any good code in C++ has nothing to do with the language's design, and everything to do with having a small number of very careful programmers. And that good code will still probably have twice as much boilerplate as the C# version of same. (Not to mention the whole "taking twice as long to write" aspect of the whole thing.)
-
RAII goes away if you ever need to use a pointer/reference, too.
-
Oh, so C++ now enforces RAII?
What do you mean "enforces" RAII? It doesn't make you write an RAII class if you can of course, so you can make a subpar library that users can screw up. But if you mean I have an RAII class, like
fstream
, does it enforce it's closed? Yes, and it always has, except for the usual caveats about undefined behavior (the most relevant of which here is "oops Ilongjump
d over the frame where myfstream
was located, which should indicate how infrequently you actually have to worry about the destruction not happening).You keep saying C++ when you mean RAII and it's pissing me off.
C++ gives you the tools to do RAII. To the extent that the important thing about RAII is the release of the resources, most other languages do not give you those tools, and the closes they get is give you something you can put into ausing
.
-
C++ gives you the tools to do RAII. To the extent that the important thing about RAII is the release of the resources, most other languages do not give you those tools, and the closes they get is give you something you can put into a using.
Ok; but the only example you've given of why RAII is better is "it saves 5 characters of typing" which, and excuse me if you don't agree, is fucking stupid.
If you come here and slam down a list of 50 things RAII is great at, then you're like "C++ supports it, motherfucker!"... well, ok, then maybe you got an argument. But right now, I'd rather type
using{}
and bank the cost against the thousands of other lines of C++ boilerplate C# saves me from typing.
-
Java is not an entity that is capable of sinning. Or making any kind of moral decisions, for that matter. Or making any kind of decision at all, for that matter.
I know I've made that Drax joke several times, but you really don't understand metaphor, do you?
-
You think Java's standard library is better than C#s?
Anybody who thinks that shouldn't be allowed to program.
If NOTHING ELSE, the fact that it's so much more orthogonal than Java's is a major improvement.
People griped endlessly about the inconsistent naming order of functions in Windows (and Java, etc. etc) as well as the inconsistent order of parameters and so on. Microsoft obviously spent a significant amount of time fixing that in the CLR library.
-
I'm sure he was using it as a metaphor of some kind, but it's so nonsensical that until he explains it, I'm bucketing it in the crazy bucket.
It means "does bad things". Jeez.
-
I know I've made that Drax joke several times, but you really don't understand metaphor, do you?
I don't know what a drax is. But I do understand metaphor, and use it frequently in my own writing. I just don't understand impenetrable metaphor, like "before Java was able to figure out it had sinned."
-
I don't know what a drax is.
https://www.youtube.com/watch?v=h27AcB70Mvc
I've linked it repeatedly.
Sinning is bad, right? It's actually not impenetrable to people who understand metaphor. We could do a poll to see who understood that one, except half the people would complain about FILE_NOT_FOUND not being an option and so on.
-
I've linked it repeatedly.
Whatever, I don't give a shit about purple monster dude. If you have something to say, say it. Use words.
-
If you come here and slam down a list of 50 things RAII is great at, then you're like "C++ supports it, motherfucker!"... well, ok, then maybe you got an argument. But right now, I'd rather type using{} and bank the cost against the thousands of other lines of C++ boilerplate C# saves me from typing.
RAII classes are composable in a way that things that rely on try-finally or any shorthand syntax for it are not.
I can have a
[code]
class TransactionalCanceler
{
Transaction tran;
Canceler cancel;
/* ... */
};
[/code]
in C++, and it'll work without further ado to get the canceler to turn the cancel button back on or the transaction to clean itself up when it's done -- in fact, I use this pattern in the MFC project I'm working on right now to bind the cancel button to the DB transactions batch jobs run in. This can't be done in Java or C# without extra glue code inside theTransactionalCanceler
to tieclose()
methods together.
-
If you have something to say, say it. Use words.
I did, you troll. I used his words.
"His people are completely literal. They don't understand metaphors at all. Forget it, it'll go right over his head."
"Nothing goes over my head. My reflexes are too fast. I would catch it."Since I'm sure you won't get it, I'm comparing you to the guy who doesn't understand metaphor, even though you claim you do, because you clearly don't based on how you never do. Unless you want to claim Blakeyrat's just a persona and the underlying person does but he's pretending he doesn't.
-
I did, you troll. I used his words.
"His people are completely literal. They don't understand metaphors at all. Forget it, it'll go right over his head.""Nothing goes over my head. My reflexes are too fast. I would catch it."
Since I'm sure you won't get it, I'm comparing you to the guy who doesn't understand metaphor, even thogh yu clm u d, bcue$ @u$ %rl@ &d'tblah blahb oblah blahw blah blah'blah blah blah blahblahbalhblah blah__ _blah __blah __________...
GIVE UP ALREADY!
-
-
in C++, and it'll work without further ado to get the canceler to turn the cancel button back on or the transaction to clean itself up when it's done -- in fact, I use this pattern in the MFC project I'm working on right now to bind the cancel button to the DB transactions batch jobs run in. This can't be done in Java or C# without extra glue code inside the TransactionalCanceler to tie close() methods together.
Ok but again. You're talking about one tiny thing in a sea of shit.
C# is a sea of nice things with a couple turds floating around. C++ is a sea of turd with maybe one or two gems floating on top.
Unless C++ is holistically better than C# (and I know it's not), I still have no reason to use it. Even if I could save typing
using{}
or having two differentclose()
methods.The real question here is, does C++ know that it sinned? I only choose programming languages based on sin-know-age.
-
I'm working with Java 8. JDK8u20, to be exact. It has Observable class and Observer interface in standard library. And it doesn't make use of generics that were added quite a few versions back.
Java 2 version 1.8; get it right. And Observable/IObserver have been around since the first version of Java in 1991; no changes can be made, since that breaks compatibility.If I was one of the original developers of Java 1.0, I would fucking make real generics.
Java 2 version 1.5 back in 2004, which had to have bytecode compatibility with 1.4 and be callable from managed and native classes compiled in 1995 (Java 2 1.0).You mention Backward Compatibility, but C# had no problems bolting on Generics after the fact.
C# had the luxury of declaring "Common Language Runtime 2.0; if you're not built for me, go pound sand!" Java, politically speaking, didn't have that option.
Correct me if I'm wrong, but doesn't type erasure mean that compiler has no way to statically check type safety of generic containers when interacting with precompiled 3rd-party library?
Yup.
-
You guys can just assume I'm asking
But you've told us previously that assuming you might possibly mean anything other than a strictly literal reading of the exact words you type is listening to our shoulder aliens, and is a Really Bad Thingâ„¢.
-
Java, politically speaking, didn't have that option.
I guess this had a lot to do with the "fragmentation" of the JVM and specially of J2ME being in lots of mobile phones that couldn't update it, so you had to be backward compatible.
Also, any one correct me if I'm wrong, .Net major version aren't backward compatible, and since .Net is only available in a limited number of platforms, MS can go ahead and break it.
-
The real question here is, does C++ know that it sinned? I only choose programming languages based on sin-know-age.
Here's the problem: most of what you perceive as 'sins' in C++ are actually essential for what the language actually is good at, and that's being close to the problem domain and close to the machine at the same time. Is it convenient? Maybe not. But we will still need a systems programming language for the forseeable future, as our CPUs don't run JVM or CLR bytecode directly. C++ is the best systems language we have with any degree of acceptance at this time, and the alternatives that are better (Rust and D) have been extremely slow to gain traction, because of the boneheaded assumption that it's universally wrong to work at a systems level.TL;DR -- Systems languages are still a thing, and still worth the time of a programmer to know and understand. Telling folks that they aren't is doing the industry a disservice in the same way that people who ignore the other lessons of history are a disservice to the industry.
Filed under: write the reset handler for a Cortex-M and then come back to me about not ever needing a systems language
-
I'm sure he was using it as a metaphor of some kind, but it's so nonsensical that until he explains it, I'm bucketing it in the crazy bucket.
Meanwhile, we've bucketed you into the seems-to-be-able-to-read-and-write-but-sounds-illiterate bucket.
-
Meanwhile, we've bucketed you into the seems-to-be-able-to-read-and-write-but-sounds-illiterate bucket.
I don't see any buckets. Can you explain what you're talking about?
-
f NOTHING ELSE, the fact that it's so much more orthogonal than Java's is a major improvement.
Apparently I haven't done enough in Java (I didn't) to get pissed at it's standard library inconsistencies. And lately I only used Groovy which apparently hides the worst parts (it does amend the standard library a lot).
-
Well, as an example of a place where Java is wtf-y:
java.util.Date
is a giant wtf. It literally has no concept of timezones and comparing two Dates is wtfy in its own right. Its first replacement,java.util.Calendar
, just generates Date objects (but Calendar actually supports timezones). Java 8 brought in newjava.time
library, but since I'm still stuck on 6 at work, I haven't tried it.- Did I mention neither Date nor Calendar can format Dates as strings and you end up invoking
java.text.DateFormat
/SimpleDataFormat
to do it instead? - GUI stuff tends to be really archaic (AWT) or look weird due to not using system widgets (Swing). I guess you could use SWT, but when IBM creates better features for your language than you do...
- enums in Java are actual objects. Unlike just about every other language where they correspond to (usually) some number format (int by default)
int
andInteger
aren't the same thing. One is a primitive and one is an object. Most of the time, Java 5 and newer will convert them back and forth as appropriate... but if you ever try to compare two of the object form (using==
), it compares their memory location to see if they're the same... Brillant! Did I mention Java doesn't support overloading operators?
-
TL;DR -- Systems languages are still a thing, and still worth the time of a programmer to know and understand.
I like to think that I do know and understand C++, it's just that my C++ is really, really rusty (2003ish). The thing is, I fucking hate it. Not I'm ignorant of it. Just hate it.
-
You're in good company.
-
Java 2 version 1.8; get it right. And Observable/IObserver have been around since the first version of Java in 1991; no changes can be made, since that breaks compatibility.
AFAIK they didn't mark it as deprecated - and if they didn't, I have all rights to hate Java 8 for stuff that dates back to Java 2 or whatever.C# had the luxury of declaring "Common Language Runtime 2.0; if you're not built for me, go pound sand!" Java, politically speaking, didn't have that option.
They did. They chose not to break compatibility. From my point of view, that was bad decision - I hate backwards compatibility.Yup.
So you see - type erasure does make type safety go to hell.
the alternatives that are better (Rust and D) have been extremely slow to gain traction
Now, now, Rust is still in pre-alpha stage. It still has potential. D, however, is lost cause. And has GC.
I like to think that I do know and understand C++, it's just that my C++ is really, really rusty (2003ish). The thing is, I fucking hate it. Not I'm ignorant of it. Just hate it.
Two possible causes - either you're very impatient and can't be bothered to read 50-line error messages that sometimes pop up if you get verily-templated library functions wrong, or you're lazy and spam object creations left and right and often forget to delete your pointers (because you don't use smart pointers - but you're justified in this regard; around 2003, they weren't that popular).
Personally, if I were to write some utility software, or other thing that's just a window with bunch of buttons, I would choose C#. But I am mostly game developer, and I like performance gains of direct control over allocation, so my language of choice is C++. It's utter shit from many sides, but it's manageable if you know how to use it.