Domain: artima.com
Stories and comments across the archive that link to artima.com.
Comments · 202
-
Worse isn't better, it's just 90% don't want it
This all seems to be a rehash of the "worse is better" meme
... that those damn software programers/companies aren't doing what we want. The only problem is, it's all crack. Almost no customers, even now, are willing to pay more for "quality".Yes, I think all other things being equal, people will go towards quality/security
... but it just isn't high on anyones list. Cheap, features, usable ... and maybe quality comes in fourth, maybe.And, yes, there are exceptions
... NASA JPL obviously spend huge amounts of money to get quality at the expense of everything else, and I say this having written my own webserver because apache-httpd had too many bugs (which comes with a security guarantee against remote attacks) ... but I'm not expecting people to migrate in droves from apache-httpd, it's got more features. The 90%+ market share have spoken, consistently, and they just don't care about the same things Bruce and I do.I have a lot of respect for Bruce, but the companies really are just producing what most people want
... so stop blaming them. -
You're not getting "functional programming" right.For a language to be functional it is essential to restrict side effects (haskell with monads, ocaml with 'mutable'), or at least have some good support for no-side-effects programming: currying, higher-order functions, the "let x = expr1 in expr2" (aka non-destructive assignment) construct and so on.
I don't think any of these features, other than higher-order functions, is really essential. Though if you rework the "let x = expr1 in expr2" as "lexical scoping," I might accept that (though I'd still point out that let is "really" just lambda: "((lambda (x) expr2) expr1)"). Scheme is routinely labeled as a functional language, and it has side effects. Cons pairs in Lisp in general are mutable.
Anyway, I think asking whether a language is "functional" is not as good of an exercise as seeing functional programming as a programming style or set of techniques, and then asking how much support a language provides for using that style, and how natural it is to use it in that language.
Ruby is no more functional than Python, even by the most twisted definition of 'functional'. Yup, it uses closures (aka blocks) and that is how far it goes towards functional. [...] Both Python and Ruby make routine use of destructive assignment, which is the epithome of side effects.
Here I'd respond that Ruby provides much more natural support for higher-order functions (because of blocks), its libraries are designed around them. It's actualy hard to avoid using them any time you program in Ruby.
This is not so with Python, whose design is in fact evolving to discourage a functional programming style (Guido has repeatedly rejected adding anonymous closures to the language, and is planning to get rid of built-in functional combinators like map and reduce).
What's non-functional about Ruby? I'd say the biggest thing is the fact that its default sequence datatype is a flexible array type, and not a singly-linked list type.
-
Re:Not too bad
That's one big difference between Java and
.NET/Mono. Java has no concept of primitive value types; everything's a wrapper that gets allocated on the heap (and thus, requires an eventual garbage collection).
In .NET/Mono, we have value types called structs that are allocated on the stack and do not require heap allocation or garbage collection. These lightweight types are quite nice performance wise. Games and other high performance software rely heavily on structs to alleviate garbage collections and keep the heap tidy.
what happens when you add a complex object to the list that only had primitives?
To do this, you would need a non-strongly typed list that can store any type. For .NET/Mono developers, this is the System.Collections.ArrayList. When you put a primitive in an ArrayList, it is boxed into a reference type just as it is in the Java implementation. But with generics, ArrayList is almost useless; we now use System.Collections.Generic.List<int> to store a list of 32-bit integers, strongly typed and efficient. It's really a rare case when you need to add value types (structs) and reference types (classes) together in the same collection. In fact, in my company's 500,000+ lines of code C# application, I can say for a fact that we do not use any such collections; everything's strongly typed.
In any case, I suggest you have a look at this article, which details exactly how Java and C# generics work, what their differences are, and how they differ from C++ templates. -
Online top 6
All the current suggestions from other posters I would agree with, Dr. Dobbs, ACM, IEEE, CUJ. But probably, like regular media, the smaller players are picking up the slack, even if they are web only. ServerSide, JavaLobby, IBM Systems Journal, Software Development, Artima Developer, JavaWorld, and DeveloperWorks are a few of the excellent ones I regularly read.
-
Re:Could be for managersYeah, that's why I called it useless. I posted on his web site about it too. Here's my comment:
Premise 1: For any given hardware, there are one or a few common coding operating systems.
Premise 2: There is not now, nor will there ever be, an operating system whose benefit is significantly greater than any of the common operating systems.
Premise 3: Approximately a gaboozillion cycles are spent on dealing with OS variations.
Premise 4: For any non-trivial project, a common OS is a good thing.
Conclusion: Thinking of all the code in the entire world as a single "project" with a single OS, we would get more value than we do by allowing for variations in operating systems.
Premise 1: For any given OS, there are one or a few common coding languages.
Premise 2: There is not now, nor will there ever be, a programming language whose benefit is significantly greater than any of the common languages.
Premise 3: Approximately a gaboozillion cycles are spent on dealing with language variations.
Premise 4: For any non-trivial project, a common language is a good thing.
Conclusion: Thinking of all the code in the entire world as a single "project" with a single language, we would get more value than we do by allowing for variations in languages.
And so on. This is really an intensely silly idea. -
Re:Bah, Scripting languages
How is Python based on something that came out after it did?
"Java was developed in 1991 by James Gosling and other Sun engineers, as part of the Green Project. After first being made public in 1994, it achieved prominence following the announcement at 1995's SunWorld that Netscape would be including support for it in their Navigator browser."
"In the late 1980s, Van Rossum began work on Python at the National Research Institute for Mathematics and Computer Science in the Netherlands, or Centrum voor Wiskunde en Informatica (CWI) as it is known in Dutch."
If you wish to become enlightened:
http://www.artima.com/intv/python.html -
Re:Attracting new users, competing with Python?
It's a matter of taste really though. The object system in Perl6 is considerably cleaned up. Yes it has the usual Perl punctuation soup as syntax, but structurally it is a lot cleaner. Some people adore Perl's syntax. You seem to be quite fond of Ruby. Personally I quite like the spareness of Python. If all you have issue with is the syntax... well I can't help you with that, because I don't really like it either.
As an aside, variable declaration is something Python does manage (there's no "use strict" - it basically has that on by default immediately). As an added bonus an option for declaring static types as well seems to be in the works.
Jedidiah. -
Ruby resources
Heh, well, no offense but, people that use to reply like you haven't tried Ruby, or don't understand it. Otherwise you would be in love with it already.
We cannot compare PHP and Ruby. It's like comparing BASIC and Perl, you get the idea. Remember when you discovered Perl and all its magic? Well, that's what happens when you get into Ruby. It's a true object oriented and dynamic language ready for real applications.
This might or not make sense to you. It depends on the use you are giving to your language of choice. If you write one-liners in Perl, you might not feel motivated to move to Ruby. If you are writing templates in PHP for your web applications and you're doing fine, you might not need Ruby either.
You see the light
:) when you want to write OO applications/scripts. PHP used to have an awful hack (I haven't seen PHP 5), so does Perl 5. Python would be your choice, but for some reasons I cannot explain (yes, this is subjective) Ruby feels more natural.Ok, I have fallen again in the "I love Ruby so much" that gets you so bored. So, here is some homework for you (some very nice presentations and small articles):
Ruby: A transparent, object-oriented programming language
10 Things Every Java Programmer Should Know About Ruby
The Ruby Programming Language (by Matz, Ruby's author)
Thirty-seven reasons I love Ruby
Blocks and closures in Ruby -
Re:The blogging applications of this are endless.Because blogs aren't gay enough already.
Really, I don't care that the bitch at McDonalds gave you attitude, or how your day at work went, or your opinion on anything. And I definitely don't want to see the video.
The few blogs I can think of that are marginally useful (like http://www.artima.com/weblogs/index.jsp>Artima.co
m ) wouldn't benefit from video anyway.Blogs are like personal webpages 10 years ago. For a little while, everyone had one. Then they realized other than 2 or 3 of their friends, nobody cared. I give blogs about a year before all the bloggers realize that the vast majority of people still don't care.
I just wish it'd hurry up and die. If I see another fucked up word like "videobloggery" I'm going to scream.
-
Re:The thing about Perl...
I used to be a believer, but now it seems Python is ready to take the yoke, at least with those of us who wonder how can you build a complex yet maintainable script without static typing.
Some kind of optional static typing is a recent Python design teapot-tempest, but Python is most definitely not statically checked as of this writing.
Of course, how you edit really matters most... -
Re:Static code verifications, anyone?
-
Re:Unbelievable
I decided to make a search on google for "just works"...seems its everyone's sales pitch at some stage or another:
- http://www.artima.com/spontaneous/upnp_digihome.ht ml
- http://www.nwfusion.com/columnists/2002/0715mustha ler.html
- http://www.apple.com/switch/whyswitch/
- http://bashburn.sourceforge.net/
- http://www.oreillynet.com/pub/wlg/6037
... just to name a few.
Also here is a page with an interesting write-up about "It Just Works": http://c2.com/cgi/wiki?ItJustWorks -
Re:Advantages?
-
Re:Regardless of ReligionIf you think C# is something that has to just be ignored, you are missing a lot. I had the same opinion until I read some interviews with the creator of C# (who also worked on Borland C++ and Delphi) at Artima Developer. There are some huge and highly enlightening differences between it and Java.
The people who are hung up the law about it are the ones that not only choose not to use it, but choose to ignore it. So at least read about it. If nothing else, you'll understand virtual/final methods better.
-
Also (about C#)Also, I would like to add that after reading some Artima Developer interviews with the creator of C#, C# gets more good features of C++ than Java. In fact, virtual methods (originally from Simula) are taken to another level in C# (as compared to C++). Besides having a virtual keyword (so every class need not be inherited from), there is an override keyword, that states explicitly when a class is overriding a virtual method.
This gives it not only C++'s advantage over Java, that methods that weren't properly planned (preconditions/postconditions understood by subclassers) won't be inherited from, but another advantage as well. This is that when a method is added to a base class in a new version of a library after a user has written a subclass of one of the library class, that added a method of the same name, calls in the original library won't go to it unless that was what both the creator and user of the library intended. This probably isn't clear. Read the interviews.
Also, I wouldn't be surprised if C#'s exception system is about as good as C++'s. I already know it's better than Java's (due to the lack of unchecked [or is it checked?] exception silliness).
-
Re:I don't "get" Mono either.That functionality really is neat. A week ago I didn't know about it, and may have been more toward Java, but a couple days ago I started reading some interviews with Bjarne Sroustrup on Artima Developer, and I found out about File_handle and auto_ptr.
After seeing this, it is no wonder for me that most of the great applications are written in C++.
Of course I don't expect to write good C++ code just because I heard about this. In fact after searching I realized there are a couple of gotcha's with the auto_ptr (such as copying), but they are much easier to avoid than forgetting to type something in the Java example.
I do, however, know of the perfect place to learn most all of those tips to making good C++, which is Bjarne's "The C++ Programming Language". I was already considering buying it, but now have ordered it and am looking forward to it. I like his writing style (I looked in a sample chapter). He focuses on the right way to do things, but still shows counterexamples (unlinke Wall's Programming Perl, which seems to have more counterexamples than examples). If comments about the book are any indication, he is also quite thorough. Though it is 50 pages shorter than "Programming Perl", I expect to learn about 10 times as much from it.
-
Re:Since you showed up on the /. radar, PaulAs far as I know and can tell,
def foo(n):
and
return lambda i: return n += idef foo(n):
are still not valid Python code. I am not exactly a Python expert or anything though.
lambda i: n += i
Interestingly, Guido van Rossum seems to have blog at artima.com and he just posted something about removing lambda, filter, map, and reduce for Python 3000. It looks like he prefers list comprehensions in place of map and filter. The presence of lambda confuses people because they think they can do things with it that they cannot do with named functions. As for reduce, he finds its use rather confusing for everything except the most basic examples, i.e. + and *. You can find the blog entry at http://www.artima.com/weblogs/viewpost.jsp?thread= 98196 -
Re:Python and QT
As someone who is a big fan of Python and uses it almost exclusively, I can say that the static typing of C# and Java has one big advantage. It's not better bug detection at compile time, or some nebulous concept of "enterprise readiness", it's intelligent IDEs with autocompletion etc.
I prefer GvR's ideas about static typing for Python 3000 better (basically, all type checking is done via interfaces), but it doesn't actually exist yet :-).
-Mark -
Sample excepts
Sample excerpts from the book are available in PDF format from the book website. You can also download the full Using Tags and Branches chapter artima.com (free login required).
<gripe>Most tech books these days have a page on the publishers website, and some offer a sample chapter for download. Book reviewers should include a direct link to this book page, and note what excerpts/chapters are available for preview, if any (and prevent people like me karma whoring).</gripe>
-
Python *is* strongly typedThe parent did not deserve to be modded up as "informative". An accurate title for the post would be "Python is not statically typed."
Python is a strongly typed language. It is in the class of strongly- and dynamically-typed languages. Read this article on Python's type system for a good overview and a little information on "type" terminology.
-
Python's not strongly typedPython is runtime typed
-
Re:ContinuationsThere's also a few linearizing web frameworks for Ruby:
- Borges, has been around for a bit, more or less a direct port of Seaside
- Wee, a newer frame work that uses a more modern approach to linear web programming. It can work without continuations meaning you can avoid some of the issues with those. You'll probably find the author's weblog interesting. Another good point about this is that it seems to take code and ideas from Ruby On Rails as well.
-
SubtextWhat's coming isn't languages where you edit XML -- because XML has too much syntactic overhead -- but languages which aren't text based -- languages like Subtext (the screencast demo is essential).
Languages need to evolve out of the pure text medium. This has been happening as incremental hacks to classic languages through code folding editors and AST-aware, intelligent IDEs like Eclipse, literate programming and Python's doctest module. High-level development tools like Delphi were early adopters of the philosophy that code doesn't need to be visualized as text when it's better to visualize it graphically.
The next step is to store not text but structure. For example, why shouldn't I be able to comment on -- annotate -- a specific number in a mathematic formula in my code? With current text-based languages this would be a headache:
double phi = 1 - 1 / (1 + Math.exp(-(cv *
/* weight */ 0.3 - range) / sigma));Instead, I could just select the value in my editor, click on the annotate key, and enter (in nice WYSIWYG HTML or whatever) my comment there. As a result, the editor will show a tiny icon next to the number, or perhaps in the margin, indicating that there's an annotation.
And why are formulas like that represented with such a poor syntax? Why can't I easily use proper Greek letters and standard math notations such as dots for multiplication, a horizontal line for divisions/fractions, etc.? Why can't I insert images into the source file which illustrate the concept it implements?
What I'm talking about isn't just "rich source code", which Donald Knuth's literate programming concept covers to some extent. Languages will experience a revolutionary leap when they start treating language elements as flexible blocks of content as opposed to tokens in an AST. Consider internationalization; instead of looking up a string from a language-specific message table, your source code can include the string in every possible language, hidden away in a single visual representation -- it might look something like:
showDialog("File not found" [English, Swedish, (8 more languages)]);
where "English
..." is a link that opens up a nice GUI letting you change the strings in different languages. The logic to select the string to choose at runtime exists in the string "component" itself.A common problem in dynamically-typed language is that it's hard to implement optional static typing at the language level. It adds a lot of noisy syntax, and unless you add a lot of syntax, it's hard to solve many ambiguities and special cases. With a rich source format, you can hide away the details, similar to my annotation example.
Unix geeks typically balk at non-textual files, but I blame it on a fundamental lack of imagination. You can have both! Rich source code can be represented as text -- it's just not convenient to edit it like text. Instead, you add intelligence and convenience to your tools. You don't edit your PNG files with Vi -- you use a tool like GIMP or Photoshop.
-
Re:Totally Incoherent AnswersAnd thus, their software has all the features they need.
That hardly means it has the features other organizations need.
Given that the IT needs of Microsoft probably rival or surpass almost any other organization, I'd say that probably qualifies their products as at the very least among the best.
Interesting logic, but wrong. MSFT has marketshare more because of how it shrewdly uses it's monopoloy postion coupled with good leadership and understanding of the market.
IBM requires everybody to use Lotus Smartsuite, and IBM is far far bigger than MSFT and has far more "IT Needs", so Lotus should be awesome, right? Further, there are great open source products such as Apache, Struts, Linux, Firebird, MySql, Snort, that rival and/or surpass the best MSFT has to offer. These aren't built by a giant monolithic corp. eating it's dogfood at all.
For some interesting reading, read this blog and the comments, about MSFT culture and software bugs. Also see ESR's paper.
-
Re:Yah, good for Javascript!
-
Every single language you've mentioned there are NOT maintainable. Why? Cause they're all interpreted dynamic languages. It's fun and all to write in these languages and get stuff done with them but as soon as you spot a bug you have a hell of a time to
... blah blah ... not suitable for production systems.
This is a myth, and has been proven false countless of times, such as by these guys, or these guys, or even these guys, or, God forbid, you may have heard of these guys.
First, the term "interpreted dynamic language" is vague and misleading. Interpretation has nothing to do with code maintainability. (You can interpret C, and you can compile putatively interpreted languages such as Java and Python to native code; indeed Java has been natively compiled for years, and the fact that it is just-in-time compilation is irrelevant).
And what does "dynamic" mean? Do you mean a dynamically, as opposed to statically, typed language? Do you mean runtime introspection? Self-modification and metaprogramming? Runtime name resolution? What? I suspect you mean a combination of these. Python, Perl, Ruby, JavaScript, PHP, Haskell, Lisp and OCaml have these features. C++ can be considered a "dynamic" language, as can Java, C#, etc. So why do you claim that these languages are not maintainable?
These newfangled languages are more rapid to develop in than lower-level languages. Maintenance is simpler because the languages are simpler, higher-level and more easily maintained. For example, the absence of a separate compile/link cycle means I can get from changing a source line to testing the source line quicker.
In many cases, reproducing or debugging a bug is simpler in, say, Python than in C, because the infrastructure itself is simpler. Pure Python, for example, does not have memory access violation errors; there's no way your Python code can read or write an invalid pointer, write beyond the end of a buffer and so on; a whole class of pointer errors, most of which have security repercussions, are annihilated by this feature. Similarly, Python uses exceptions, so nobody can forget to check and propagate a function's error return value.
More often than not, errors that surface in these languages are high-level problems, which is good, because those are simpler than the ones involving someone forgetting to call free() on an allocated buffer or accounting for overflow when shifting a bit mask.
The uncertainty involved in the dynamic typing/late binding model of such languages is compensated for through unit testing.
Oh, and JavaScript, a "dynamic language", is being used by Google in a production system, and Google is known to use Python and Ruby in their systems. I suggest you call them up and tell them their languages aren't suitable.
-
Every single language you've mentioned there are NOT maintainable. Why? Cause they're all interpreted dynamic languages. It's fun and all to write in these languages and get stuff done with them but as soon as you spot a bug you have a hell of a time to
-
Interesting Open Source platform beyond LAMP
Rails is another interesting Open Source database development platform-but it isn't strictly "LAMP"(uses Ruby instead of Perl/Python/PHP-though I suspect we'll see a Python version soon).
My favorite line in the article:
"J2EE as a fear-driven technology choice made by higher powers" -
What Java is"J2EE as a fear-driven technology choice made by higher powers"
Whatever the claims about "Community Process", Sun runs Java and Scott McNealy runs Sun when it really comes down to it. I would suggest asking long term Sun folks(the folks that built that company and were there over 15 year ago) what they really think of that means of governance.
-
Re:Who cares?
> (a) looking for problems
This is a boolshit argument - you get problems with C too. Big problems with "evil macros", memory leaks, resource dead locks, pointer arithmetic, stack corruption etc. It's a matter of expertise, regardless of the language.
Sure, the C way seems transparent and obvious, but complex problems require more involved solutions. Solutions that abstract building blocks in order to manage this complexity. Abstraction mecanisms are much better with C++. The same goes for encapsulation - OO way provides several useful mechanisms than "static".
> (b) a C++ bigot that can't see what he is writing is really just C anyway
The point Stroustrup makes is that one can use a subset of C++. It's a valid thing. However, OO concepts are native to the language, so no function pointer assignments are required to implement abstraction. No "just return a handle" hacks are required to have encapsulation. Why not use a language that natively supports and checks for polymorphism, abstraction and encapsulation?
Now, all of this is described much better in a "Conversation with Bjarne Stroustrup" by Bill Venners here:
Part 1: The C++ Style Sweet Spot http://www.artima.com/intv/goldilocks.html
Part 2: Modern C++ Style http://www.artima.com/intv/modern.html
Part 3: Abstraction and Efficiency http://www.artima.com/intv/abstreffi.html -
Re:Who cares?
> (a) looking for problems
This is a boolshit argument - you get problems with C too. Big problems with "evil macros", memory leaks, resource dead locks, pointer arithmetic, stack corruption etc. It's a matter of expertise, regardless of the language.
Sure, the C way seems transparent and obvious, but complex problems require more involved solutions. Solutions that abstract building blocks in order to manage this complexity. Abstraction mecanisms are much better with C++. The same goes for encapsulation - OO way provides several useful mechanisms than "static".
> (b) a C++ bigot that can't see what he is writing is really just C anyway
The point Stroustrup makes is that one can use a subset of C++. It's a valid thing. However, OO concepts are native to the language, so no function pointer assignments are required to implement abstraction. No "just return a handle" hacks are required to have encapsulation. Why not use a language that natively supports and checks for polymorphism, abstraction and encapsulation?
Now, all of this is described much better in a "Conversation with Bjarne Stroustrup" by Bill Venners here:
Part 1: The C++ Style Sweet Spot http://www.artima.com/intv/goldilocks.html
Part 2: Modern C++ Style http://www.artima.com/intv/modern.html
Part 3: Abstraction and Efficiency http://www.artima.com/intv/abstreffi.html -
Re:Who cares?
> (a) looking for problems
This is a boolshit argument - you get problems with C too. Big problems with "evil macros", memory leaks, resource dead locks, pointer arithmetic, stack corruption etc. It's a matter of expertise, regardless of the language.
Sure, the C way seems transparent and obvious, but complex problems require more involved solutions. Solutions that abstract building blocks in order to manage this complexity. Abstraction mecanisms are much better with C++. The same goes for encapsulation - OO way provides several useful mechanisms than "static".
> (b) a C++ bigot that can't see what he is writing is really just C anyway
The point Stroustrup makes is that one can use a subset of C++. It's a valid thing. However, OO concepts are native to the language, so no function pointer assignments are required to implement abstraction. No "just return a handle" hacks are required to have encapsulation. Why not use a language that natively supports and checks for polymorphism, abstraction and encapsulation?
Now, all of this is described much better in a "Conversation with Bjarne Stroustrup" by Bill Venners here:
Part 1: The C++ Style Sweet Spot http://www.artima.com/intv/goldilocks.html
Part 2: Modern C++ Style http://www.artima.com/intv/modern.html
Part 3: Abstraction and Efficiency http://www.artima.com/intv/abstreffi.html -
Re:MistakeHmm, I just found this bit, admittedly from the lead architect of C#, so I'll take with a grain of salt, but if this is true, it's a bit lame (I also found this, which is from a somewhat more trustworthy source). Damn.
Also, another piece from Bruce Eckel here. This is even more clear in its skewering of Java Generics. It really sounds like Sun dropped the ball on this one. -
Re:Only Microsoft
I've read the arguments on the topic, but I don't agree.
Relying on documentation to tell API users what exceptions can be thrown is a really terrible idea if you're trying to write server software that has to actually work. And work all the time, 24/7, not just in a demo. MS still seems to be in the mindset where their developers are mostly making client-side VB applications or tiny ASP sites.
We've had a number of cases so far where C# library methods unexpectedly threw an undocumented exception (that would most likely have been a checked exception in a Java implementation). Now, often if you were smart you'll be lucky and the exception falling through to a general handler won't break anything too badly, but other times something unfortunate will happen.
In my book, when Microsoft's fast-to-develop-cut-all-the-corners methodology meets the real world of SLAs where software actually has to work, something has to give. And yes, you can say "just use Java/Python/Cobol/whatever instead" but the point here is debating whether using checked exceptions is a good idea or not.
I'll be honest - I like a lot of things about C#. It's a good language and their IDE is also good. But deciding that checked exceptions were bad was very unfortunate. -
Re:Java 1.5 vs c# 2.0?
-
Anatomy of Insanity
Check out: Anatomy of Insanity? for more on Microsoft's warped "values"-based thinking.
-
They fucked up JavaJava was a good, simple language. You may not have liked it, but you couldn't deny it was a simple language with an elegant C-style syntax.
Now they added a lot of features that are nothing but crappy compiler sugar. Most of them badly implemented.
-
Generics: They couldn't make it worse here. You cannot use reflection effectively because the type parameter information is not stored in the compiled class file. There are many ways to circumvent the type "safety" provided by the templates, especially if you are mixing code from older versions. This is one of the worse implementations of generics I have seen. I hate Microsoft with a vengeance, but they are implementing generics in a sensible way in the next version of C#. See this for an interesting discussion comparing Java, C# and C++ generics.
With java generics you can compile this:class MyClass<T> {
Of course, you cannot assign the return value to a T[] because it is really an Object[], so, where is the type safety? All this is without mentioning that Java generics don't provide any performance benefit (which you would naively expect because you believe that you do not have to cast anymore).
T[] anArrayOfT()
{
Object[] arr = new Object[10]; //add whatever you want to arr.
return (T[]) arr;
}
}
Java generics are just compiler sugar for automatically generating casts. - Autoboxing: this feature removes clarity from the language. You do not know what is really going on. And you never know when you are going to be surprised.
- Enums: They coud have made a very good typesafe implementation using internal integer values orsomething simple like that. Instead they make them as clases. At first they look like they work fine, but if you start workking in contexts where several classloaders are used (e.g. application servers) then the enum is going to be loaded in both classloaders and comparison of apparently equal values will fail.
- Annotations: I really don't see the point of this. It's just more complexity. It seems it is only useful to help some complicated and probably not very well desinged tools.
- New for: This simply makes the code harder to read. The original, C like "for" construct was very clear and was very understandable both for arrays and collections. Now in order to use a fundamental construct (a "for") your code has to implement some new interfaces. This is pure crap.
- Static imports and variable length parameter lists: I think these are well done. I have nothing against these.
- It looks like they wanted to add novelty features, but in order to avoid make the appropriate JVM specification changes, they implemented everything as compiler sugar. It just doesn't work.
Maybe the fact that Java is now managed by a comittee instead of a few people who do know about language/compiler design has something to do with this.
Maybe they are just trying to make it "easier"for those who don't know how to program. Again, it doesn't work.
Something more or less like this happened when C++ was standarized. They came up with an overly complicated monster language, but at least the specification was not a broken one, just complex.
They could have added pass of parameters by reference (at least for primitives), which would have been very useful in real world situations. But instead they decided to add a ton of crap.
Java is doomed now. Too bad it was my favorite language. Now I have to look for another language. Maybe D?
-
Generics: They couldn't make it worse here. You cannot use reflection effectively because the type parameter information is not stored in the compiled class file. There are many ways to circumvent the type "safety" provided by the templates, especially if you are mixing code from older versions. This is one of the worse implementations of generics I have seen. I hate Microsoft with a vengeance, but they are implementing generics in a sensible way in the next version of C#. See this for an interesting discussion comparing Java, C# and C++ generics.
-
Is it C# yet?Metadata attributes? Generics support?
In Java you will not see any performance improvement; the reason is well explained by Anders Hejlsberg (lead C# architect) in http://www.artima.com/intv/generics2.html
:
"For example, with Java generics, you don't actually get any of the execution efficiency that I talked about, because when you compile a generic class in Java, the compiler takes away the type parameter and substitutes Object everywhere. So the compiled image for List<T> is like a List where you use the type Object everywhere. Of course, if you now try to make a List<int>, you get boxing of all the ints. So there's a bunch of overhead there. Furthermore, to keep the VM happy, the compiler actually has to insert all of the type casts you didn't write. If it's a List of Object and you're trying to treat those Objects as Customers, at some point the Objects must be cast to Customers to keep the verifier happy. And really all they're doing in their implementation is automatically inserting those type casts for you. So you get the syntactic sugar, or some of it at least, but you don't get any of the execution efficiency. So that's issue number one I have with Java's solution."You can argue with Anders, but then, you would be wrong.
-
Re:Correction:
Oops, should have previewed:
link -
Re:Fact 37 - code reviews catch errors
Nothing compares to a code review done by a super-anal type who nitpicks over everything.
Amen to that. Things like race conditions, improper locking sequencing, reference leaks and other hard-to-trace run-time bugs normally cannot be catched by asserts() or unit tests.
Also needless to say that unit tests become exponentially useless when the complexity of the code doubles. They also tend to 'pollute' the code obscuring actual logic and making it hard to follow.
PS. Having too many asserts in the code means only one thing - too many untrivial invariants , which in turn is usually a clear indication of a sloppy design.
-
Debunking the debunkingWell, Graham doesn't really need me to defend him, but I will anyway. This article doesn't really get the point:
Java has considerably fewer surprises: on this one he might have a point. I might say "Java has fewer orthogonal features" instead. For instance, there's little ability to do metaprogramming in Java (unless you use AspectJ). There's just lots of interesting things you can't do -- and interesting things can also be hard to understand or cause surprises. Java's compromise is arguably valid, though not very exciting.
Java has been considered slow: obviously he doesn't understand where Graham is coming from. Many interesting languages are slower than Java, including many of the languages that Graham suggests (Perl, Python, Scheme).
Swing disasters continue: again, he doesn't understand Graham. To address his criticism of Java, you must ask "is Swing fun to program" not "are Swing apps fun to use".
Java is strongly typed: well, sure. ML is a statically typed cool language. And Lisp, Python, and Smalltalk are all strongly typed. (If you don't understand the distinction between strong and static, read this.) The problem is really that Java doesn't trust the programmer, not the specifics of its typing. Though if you trust the programmer, static typing starts seeming a lot less useful. And yes, great hackers don't like languages that don't trust them, for obvious reasons.
Java has a vast library that is available to all Java developers: this is a guy with a Common Lisp background. He certainly has no problem with good libraries, and he never mentions any problem with extensive libraries. Programming in an open field can be fun sometimes, and can help you think about things differently, but libraries are never a detraction (you can always ignore them if you want).
Java did not have a good IDE: I don't think Graham said that great hackers really like Visual Basic, and that's why they don't use Java. I laugh just considering that argument.
Java is popular: if you ever listen to the users of languages like Smalltalk and Lisp, they will bemoan at great length that they are not as popular as they deserve. Though you'd only know this if you ever looked at these communities.
Java is an application programming platform: so are Lisp, Smalltalk, Python, etc. Most of the kinds of languages Graham is talking about are not systems programming languages.
It's nice this guy tried, but he really doesn't understand what Graham is talking about. Which is kind of the point -- to understand Graham's perspective you need to have the intellectual curiosity to do non-work-related projects, using environments that are unfamiliar to you. You need to reflect on those experiences and make judgements about what you like and what you don't like. If you've only used Sun and Microsoft languages, you won't get it. That doesn't mean you can't do good work in Java, but if that's all you do, then you won't be much of a hacker at all.
-
Re:Return of Java
For a long running enterprise application, it would probably be SLOWER in c/c++. No matter how good you are at programming c/c++ you can't anticipate every little bottleneck and write it in perfect assembler... but the hotspot compiler can do that rathar well.
Your statement is as correct as saying that Java is slow.
Java is not slow, but it's slower than a good C++ code; consider these words from Stroustrup:
When you get to percents, 10%, 50%, and such, you start arguing whether efficiency matters, whether next year's machine will be the right solution rather than optimization. But in terms of dynamic versus static, we're talking factors: times 3, times 5, times 10, times 50. I think a fair bit about real-time problems that have to be done on big computers, where a factor of 10 or even a factor of 2 times is the difference between success and failure. (http://www.artima.com/intv/abstreffi2.html)
So yes, the average C++ programmer will write not the most efficient code (as Stroustrup compares differences in a factor of 50 between bad and good codes), and the Java's Hot Spot will then easily be faster than the average code. But remember that the Hot Spot can only guess what you are trying to accomplish; a C++ compiler can actually see what you are trying to accomplish. C++ compilers are not dumb, they can do really good optimizations (when you write good code, of course).
PS: using "C/C++" in a sentence comparing them to Java will make you look like you can't differentiate C from C++. Don't be so incautious unless you wanna be flamed by the "C++ is not the same as C" crowd.
-
Re:Comp Sci Recent GradTrue, Engineering courses at school help you learn how to solve problems better, but those were only 5 really helpful courses and then there is the rest of liberal arts easy A stuff
:-).and theirin in part of the problem with a college compsci degree. Great for learning basic coding syntax, various interesting subjects that provide good background but you might not use much (AI), but barely cover the bread and butter stuff you will need in the real world: stuff like how to gather requirements, how to design/model an application, how to test. Learning Pascal/C/C++/Java (or whatever lang. they are teaching) is the easy part, and the coding examples they give - you will *never* get something matching those specs in the real world. Read Gosling's excellent discussion about exception handling: main point that you don't bother with that anything other than the one-true-path scenario in college.
But in a way I prefer theory over practical as there are those who criticize my school (UWisc) as too theoretical. I'd rather get a good foundation in math, computer architecture, OS, compilers, networks, than learn the latest fad (.NET/ASP/C#). This is a field that as you say you have to keep up with. So as a whole, various schools do a good job, certainly there are various improvements, but it's up to you really to apply it.
-
Re:Strongly Typed Container Classes
I think this is the interview you are referring to. It is an interesting read for Java and C# developers.
-
Re:Why .NET and not Java?
The remoting optimization relies fundamentally on the immutability of an object.
Not exactly; value types are mutable types that can be marshaled by copying them. By using a value type, the programmer is explicitly telling the runtime that it's okay if an object gets out of sync once it's been passed to or returned from a function (for a remoted object, that it's okay if the local and remote copies differ). Since remote value types are mutable, I don't see what you mean by the above quoted statement.
Sorry, my mistake. The optimization depends fundamentally on copyability and immutability implies copyability. What I meant was that value types are essentially a compiler hint and don't help express program logic or design. Though compiler hints aren't necessarily bad things, value types significantly convolute the semantics when a good JIT compiler can figure most of this stuff out automatically.
For a mutable object, I think the to-copy-or-not-to-copy decision should be made on a case-by-case basis (instead of made at the class level). The class writer has less information about the appropriateness of a copy operation than the user of the class does.
A combination of escape analysis, immutability analysis/notation and use of the 'final' keyword gives the compiler enough information to perform all the optimization automatically without compromising uniformity.
Well, I've read in several places that best practice in Java is not to use final.
I've heard two arguments against using 'final':
- Prematurely optimizing with 'final' can hurt your design. This doesn't seem to make sense when you think about the development process. Even if I mark a method final early on, if I see the need to override it, I'll take off the 'final'. Removing the 'final' keyword doesn't break anything.
- There no performance benefit because the JIT compiler can infer this. This is true in a totally static environment. However, in the face of dynamic class loading it's a lot harder. You can't predict what types of classes you're going to be loading later on and so if the JIT does some optimistic optimization, it might have to redo a LOT of work.
As a side note, the C# way, which I prefer, is that virtual methods must be explicitly marked as such. The argument for this is that you're making lots of promises to subclassers when you create a virtual method and you should be forced to think about it.
If even one of the methods of a class is not final, the JIT will be unable to prove that the run time type is immutable. That's a pretty strong limit on the applicability of the approach you're talking about.
If you want to disallow derivation from your class, you can put the 'final' modifier before the 'class' keyword. You don't have to put it on every method. Also, I'm not saying that Java is ideal. I don't think it's that hard to infer immutability in most cases but I, for one, would not mind annotating my classes with the 'immutable' modifier (since it describes the design/logic of a program).
In addition, there are legitimate situations where it would be nice to have mutable types on the stack.
I don't see where it would be "nice" from a semantics point-of-view since you shouldn't be able to tell the difference. If it's for performance, then you don't have to worry. There are two optimizations here:
- Making copies of immutable objects when convenient. This can be performed automatically by the compiler on immutable objects when it thinks that the cost of the copy will be offset by the quicker access (because you don't need to follow a pointer anymore).
- Allocating objects on the
-
Re:HTML
Actually IMHO java exceptions seem to be the one thing that keeps it from working in large projects. (that and speed, but speed has been mostly dealt with).
The 'Horribly Twisted Hack on C" as you call it seems to be infinitely easier to maintain in large projects. Exception handling works like magic in college level applications but as soon as you get into larger applications it begins to break down maintainability and readability. That is if the programmers have not already decided to catch all and simply ignore them.
Exceptions.
1. Seperates errors from error handling. Great for modular small project. Shit for maintaining a large program with many modules. Impossible to debug without complete knowledge of the code, and perfect error messages. (NOTE: programmers rarely comment or include useful error messages in exceptions.)
2. Slow, hog processor and resources, This makes them basically useless in real code for anything but fatal or near fatal error conditions.
3. Useless Complexity!
Compare the C code
if (NULL) {
printf(GetError());
assert(false);
}
with a standard java exception block. Try it with an exception block which processes 4 different error messages. 20 times the length (I will not post it here, if you have seen one you know.
Now remember that this: It, adds NO end user functionality, takes time to program where end user functionality is not being added, Must be maintained with every library/version change, and may never actually be called or tested.
The C version has none of these problems and solves the problem quite eloquently. That is it returns an error if the function doesn't work as intended. The programmer can then debug it.
4. Want to modify a library and add an exception condition? How do you feel about updateing every class in your entire project which uses that library?
4. Want to include a large 3rd party library? They probably hacked around these problems in their own way. A way which breaks or eats all of your exceptions when in use.
etc. etc.
here are some articles which put it more eloquently
http://www.artima.com/intv/handcuffs.html
http://www.joelonsoftware.com/items/2003/10/13.htm l
-
Re:Written in C#
Are a pain in the ass and bring little real benefit to the table?
Even if you rethrow, come on. If this is that big of a deal to you then add them yourself. Write a compiler preparser that will ensure you have caught and dealt with required exceptions. There's plenty of sample source available for such a tool and for all the bruhaha about them not being in C#, you'd think it would already exist.
This interview has some wonderful explanations as to why they are not included. -
Re:I don't think so
Just to bring you up to date:
Has reflection since they adopted the Eiffel Library Kernel Standard. This standard proposes the strictest and most comprehensive interface for reflection of any other OO language.
You're right, EiffelStudio is still far beyond SmartEiffel.
SmartEiffel did very well in the The Great Language Shootout back in 2001. I haven't seen any recent benchmarks but I do know that efficiency is a very high priority.
Eiffel is very much an open language. The ECMA committee is about to finish the written standard. Furthermore there has been NICE since about 1991. To say that it has been driven by Meyer's whims is to say that C++ has been driven by Stroustrup's whims. Sure they are instrumental in driving the standard, but they are not whims. Most people complain about Eiffel's lack of whims! The development of the Eiffel language has been the most structured of any I know.
I thought requirement for global type checking was a good thing.
Since when is covariance a serious problem! Covariance allows a lot of expressiveness and power. I think what you are referring to is CAT calls (Changed Availability and Type). Eiffel has an extremely tight type system, and this is a current hole in it. The hole is about half as wide as providing the ability to type cast.
Eiffel has method pointers and so much more. It has agents(chapter 25 from OOSC) which are functions treated as objects. Agents get all the benefits of objects including static typing, introspection, copying, comparison, etc. Furthermore agents support deferred parameters.
I do think C# is good, most likely because it has learned a lot from Eiffel. You won't see any direct mention of Eiffel in this article. However the style of generics and contracts are both Eiffel originals. Also Bertrand Meyer is part of the C# ECMA committee. -
Re:Rational Unified Process
Robert C (Uncle Bob) Martin and others (even the RUP people - nowadays part of IBM, Rational - themselves) have argued that XP can be seen as a (lightweight) subset of RUP.
Martin wrote about XP vs RUP in 1998 (gg PDF-as-HTML). Martin calls/~ed it "dX" ("dX: A minimal RUP process"). Gary Pollice, former Rational 'Evangelist', have also explored RUP and XP common ground (gg PDF-as-HTML). Google for more. -
Visualisation?
-
Re:Me either ...I was about to mention Microsoft's CLR (common language runtime), but it turns out it's only for compiled languages, by design.
The JVM might work better, but I'm not sure. You can get other languages compiled for Java, but Java lacks support to invoke scripts (AFAIK). Seems like a shame. Java's 2 step process of compiling PLUS interpreting is annoying.
-
Re:This was a great review> I think a good study of a purely functional
> language could really improve my perl,
> python, or ruby.
Right on. Here's a quote from Yukihiro Matsumoto, creator of Ruby:
Learn more than one programming language, preferably many different styles, like scripting, object-oriented, functional, logic, etc.
There's an Artima article where he gives some of his reasons for this idea. That whole series of interviews with him is pretty good.