- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Interestingly enough, I get a compiler warning. It warns me that I don't have type safety. And not surprisingly when I run the code that's exactly what's wrong.
So it doesn't provide type safety IF you choose to ignore the compiler!
</integer></integer>
Admin
It's a design flaw in the class libraries, not a broken language feature. The language can't stop a programmer from implementing a class with a poor design.
If you write your own MyList{T} class that does not implement untyped IList, you'll have type safety. If you expose your List{T} property publicly as an IList{T} you'll be fine as well, since IList{T} doesn't implement untyped IList.
Generics in C# work just fine and do give you true type safety. No language feature will be bulletproof against reckless runtime type casting. It's the implementation of List{T} that is borked.
Admin
Having worked with generics for a while, I'm not sure that they're possible to implement cleanly. Forget about backwards compatibility. What can you do when you know that a collection contains a certain class of items but its generic type is a superclass of the content type? If you need to pass this collection to a method that accepts only the sub-typed collection, I can't think of any efficient solution that doesn't involve working around generic warnings. If the compiler rejected these hacks, you'd end up with everything declared with the 'Object' type with the same plethora of casts that generics were meant to eliminate. I haven't been able to create any body of code consisting of more than ~10000 lines that didn't necessitate the occasional generics warning.
Admin
I almost shot milk out my nose! I've got to learn to not eat or drink anything while I'm reading this forum.
Admin
Dan's solution still isn't generic enough for me.
A zero byte file -- now THAT's generic. You can do anything you want with it!
Admin
if (IsTrue((CObject<Object>)database > (CObject<Object>)type) != FILE_NOT_FOUND)
print "Paula = brilliant";
else
print "File Not Found";
Admin
To my knowledge Java will let you execute code that has compilation errors; at least eclipse does. Just dont run the class that didn't compile (great late at nite when you really don't care anymore).
Admin
Heh, static typing is almost a WTF in itself. In a dynamic language, the type is attached to the value, and no amount of passing it around will change what it is. Only a conversion can do that (the WTF-ery of over-eager implicit conversions is another thing). You can hardly blow things up with a type mismatch.
In fact, that's why I kinda like Java: most things in Java are objects, and objects carry their actual type with them. Type declarations are merely a convenience to ensure some basic compile-time checking. And guess what? They mostly stand in your way.
Braces for flames
Admin
He went to such trouble making the class generic in the first place, he must have wanted to keep it like that wherever he used it as well. Would have been a waste otherwise, wouldn't it? ^_^
Admin
Make the method generic as well.
Admin
That reminds me of something i read about objective-c some years ago.
'Elephants do what elephants do and lemons do what lemons do. Make sure that no elephant, by accident, ends up in your blender for it will surely ruin your breakfast.'
But, then again, there are languages which allow for the object to change its inheritance at run time. So maybe the blender can be made to force any incoming object to derive from a fruit class? ;-)
</integer></integer>
Admin
Obvious? Oh really? how about
List intList<int> = new ArrayList<int>();
List stringList<string> = new ArrayList<string>();
List list2;
Random rnd = new Random();
if (rnd.NextDouble() <= 0.5) {
list2 = intList;
} else {
list2 = stringList;
}
list2.add(new String());
Not so obvious now, eh?
Admin
After hitting "Reply" or "Quote", click in the "HTML" view before writing anything.
Now you can use the HTML entities to express those characters:
< <
> >
& &
Remember to use <p> and </p> for paragraphs so you won't get all your text rendered in a single block.
Thanks to the first person who told me this. If I just could remember who it was....
Admin
Admin
I meant:
Admin
No, Java will not do that. It's an eclipse feature that basically works by substituting code sections that can't be compiled with throwing a java.lang.Error with the compiler error as its message.
Admin
You mean Perl?
Admin
Finally, since ListIterator will happily return any sort of object when being instatiated from a generic list, independently of its template type, and against the frigging specification, I thought of asking Java itself what class of object it was returning
Admin
Admin
Not at all. Static typing is absolutely needed for big projects. According to my experience, it is impossible (say extremely difficult/expensive) to developp a project without it (let's say >100K SLOC).
Agreed. Dynamic typing is also a must.
Yes. But it is very very convenient.
No. This is the implementation in most languages that is not good and leads you to workarounds. Don't blame static typing just because it is badly used in C# and Java.
Admin
You're a fan of optional static typing?
Admin
What does type conversion have to do with static typing? Come to that, what do type declarations have to do with static typing? There are plenty of statically-typed languages, like Haskell or ML, that do not permit arbitrary typecasts and do not require type declarations. In use, they appear just like dynamically-typed languages - except they don't fail unexpectedly at runtime because you passed a function an object of the wrong type.
Admin
It can certainly be useful, and static typing may be necessary for formal verification, but it really is possible to create large systems, with hundreds of thousands of lines of code, in dynamic languages. Look at various Smalltalk and Lisp-based systems for example (especially the latter). Dynamic typing does not remove the ability to perform type assertations.
Admin
Think of C, which ultimately allows you to treat any value as any type because the type information (weak as it is) is attached to the variables, not the values.
I know, that's great, but have you seen the size of the GHC? And how many Haskell compilers exist? Two? Three? There is a price to pay for having such a type system built into the language.
Admin
I'm sure he had written a class called Object and was simply using this custom Object class instead
;)
Admin
no, the real WTF is that some people don't know the difference between compiler ERRORs and compiler WARNINGs.
Some IDEs and compilers can be set to treat warnings as errors (so not generate a classfile on encountering them), not the other way around.
Admin
oh, you mean like in C++ where the space in
is mandatory because the compiler will think you are trying to use a bitshift operator if you don't insert it?Admin
ah, the beauty of the forum software strikes again :)
Admin
The HTML view, Luke, don't forget about the HTML view.... :)
Not to mention that the HTML view is below the text area and it is not visible on Opera and on some versions of Firefox, so you'll have to use the dark side of HTML..., err, I mean, you'll have to use Internet Explorer.
Admin
Why is everybody picking on me?
Admin
Fans of dynamically typed languages argue that static typing prevents only a very limited class of errors, while incurring a great overhead. They prefer their error-prevention overhead in the form of extensive unit tests, which catch far more errors. They have a point, but it does require a lot of discipline since unit tests aren't forced on you by the compiler.
I think you are confusing the completely separate issues of static/dynamic and strong/weak typing.
Java has strong static typing
C/C++ has weak static typing
VB has weak dynamic typing
Python has strong dynamic typing
Admin
Now, truth to be told, I hate explicit static typing, but static typing with a good type inference is extremely nice.
Java or C#'s static typing, on the other hand, is more like constraint programming gone bad.
Which price, less compilers? Is that such a bad thing?
Admin
Me ayes, dea googles!
Admin
Let's face it: inheritance and generics don't go well together.
The only case when they do is when a language is specifically designed to have both. These languages are very strongly type-safe, don't have a father-of-all Object class, class inheritance graphs are not trees but generic forests and all interaction between these two ways of generalization is strictly regulated.
If you have both Object and generics, no matter how clever the implementation is, anomalies will occur.
Just for the sake of illustration: If A extends B, does C<A> extend C<B>?
If it does, you can cast your Collection<String> to Collection<Comparable> and put a nasty non-String in it. (See the quoted code, provided it really works in C#.)
If it doesn't, you're in all kinds of mess. How do you implement a sort() function for your Collection<Comparable>? One thing is sure: it won't work for your Collection<String>. Eventually you are forced to juggle a bit with the structure of your code. I don't really know how other languages tried to cope with this, Java tried to solve this by using bounded wildcard types. Of course, this method has it's own drawbacks, again forcing you into some weird hacks. (And the less talented you are, the weirder those hacks will be. :))
All this in the name of clarity and readability.
Tthe third "advantage", compile-time type safety sounds ok. It's just I've never encountered a single bug caused by putting the wrong type of object into a container, despite having seen (and having been forced to maintain) vast loads of crap code over the year.
A complicated solution for a non-existent problem, if you ask me.
Admin
I'm sure his C++ code looks like this:
std::vector<void*> vector_of_stuff;
...
Admin
Your example really has nothing to with generics. If I was doing things the old-fashioned, pre-2.0 way, I could cast to a superclass or interface and get exaxtly the same problem. With generics, I get the strongly typed class without hand-coding the pass-through methods.
Admin
More likely he wrote a generic class object and then put in his C++ code standards that all classes must inhierat from object.
class object { virtual ~object() {}; };
class shape : public object { ... };
class zooAnimal : public object { ... };
See, now you can have circles and elephants in the same container! Brillant.
Admin
yes,the "old scholl"-style[Y]
I'm often tempted to do that too
Admin
TextResponse<THEDAILYWTFFORUM> response = new TextResponse<THEDAILYWTFFORUM>();
Response.Write(response.GetText());
That's my generic response to this thread. I have no idea what I said though. Whatever I said is abstracted from the fact that I replied.
See you in the bar,
Ribbly Screwspigot
Admin
Darn you, FreeTextBox.
TextResponse<THEDAILYWTFFORUM> response = new TextResponse<THEDAILYWTFFORUM>();
Response.Write(response.GetText());
Admin
Generic data stored as CDATA sections in an XML database :)
Admin
With some of these responses, I have to wonder if any of these people questioning the utility of generics has really done much object-oriented coding in the real world. If you've ever hand-coded a strongly typed version of a collection where you just wrapped all the "generic" methods of the superclass in a more specifically typed version of the sub-class, then surely you can see the benefits of generics. I haven't seen one problem mentioned that didn't exist before generics nor have I seen an example of a problem caused specifically by generics. If you don't like compile-time type checking, then declare everything an object and quit bitching. If you don't like generics, don't use them.
Admin
<FONT face="Courier New">YOUR HEAD ASPLODE</FONT>
(With apologies to Strongbad.)
Admin
It is a very tiny fraction of programmers who actually understand OO. Most just subclass the shit out of everything and tell themselves and their superiors that it's OO.
Admin
I have reused the terminology of the original poster. The misuse of dynamic instead of strong is quite common. So yes I favor strong static programming languages (but I was lucky to work on a big project in Lisp for many years). And while I have used Java for the last decade, its type system is far from perfect.
Admin
As for me, I do know the difference between dynamic typing and weak typing and I really meant I prefer dynamic. Preferably strong, too, but I'm not too picky about it.
Java is a hybrid. Its type system is not truly static - I like that - but it's excessively strong, which mostly hampers programming, thereby forcing programmers to devise unsafe workarounds. Which, in turn, would be caught by a good static type system. Which, as I said, Java doesn't have...
Bleah.
Admin
This is, without a doubt, the single funniest in-code counter example I have ever seen.
-dave-
</string></string></int></int>
Admin
C[A] must not extend C[B]. this is the entire reason generics exist - we could not create a StringList interface which extended List and obeyed the Liskov substitution principle. Java dealt with the sort() function on collections via: List[T implements Comparable] so that you could make a library function work to sort both on List[String] and List[Date] or any later implementation of Comparable. The problem comes from making the generic collections assignable to the raw collection - bringing back the equivalent of the ArrayStoreException which happend when you did Object[] foo = new String[5]. The designers tell us they can't make it an error because of backwards compatibility so they just do a warning. The know-it-alls on this forum tell us we must never ignore warnings and treat them as errors if we want type-safety.
So what this means is you cannot have type safety and backwards compatibility. Since we need backwards compatibility, we lose type safety. And the point of entire point of generics is.... type safety. I think I'll just go play HitchHiker's guide and grab some tea and no tea.
Admin
What's so unusual about a conflict of objectives? Or about this particular one? You do not always need backwards compatibility, and in that case you can have "real" type safety by eliminating all generics warnings. In most other cases, you need backwards compatibility only in those places where you interface with pre-generics APIs and still get the benefit for the rest of the app.
Admin
For a start, I personally don't like logically contradicting structures, language elements just "hacked in" without providing a strong threoretic foundation first. If you take away the clarity and unambiguity of the JLS you can just as well use C++. But this is just my built-in distrust.
On the other hand it's fairly typical not to understand the maintainers' point of view. A coder can easily say "don't use'em if you don't like'em", a maintainer's life is not that simple.
I've done OOP coding in the real world and this is why I know that having a class that's only a collection of other classes is definitely bad design. (And definitely not OOP.)
And the problem caused by generics should be quite obvious: one more way for to wreak havoc and one more excuse for bad design.
No big deal really, no more whining from me, if we've lived through J2EE, we can cope with this generics guy. :)