Java, ten years later – a C# developer’s perspective.

javaTen years ago, I was about a year into my first full-time programming gig. Prior to that, I’d just been a hobbyist developer. I had a reasonable understanding of C#, VB 6, VBScript, JScript.NET, ASP 3.0, and even dabbled a little in PHP. I was also pretty wiz-bang with Perl 5 regular expressions, though not so much Perl itself. I spent most of my spare time on the new .Net framework, but my skills were strongest with JavaScript.

My JavaScript background landed me my first full-time programming job, where I wrote complex drag-n-drop form designers, fancy-pants grid controls, and lots of out-of-band XML stuff (later known as AJAX). Basically, I wrote the kinds of stuff you’d just buy from a 3rd party component vendor now days. The application itself was a colossal enterprise EAM product, and the server side was all Java… lots and lots of all Java.

Given that my paycheck came from a Java shop, learning Java would have probably been the smart move. But the more I looked at it, the less enthusiasm I could muster. I had no problem with the language itself. Java and C# were comparable at the time, and I was comfortable with static typing, case sensitivity, and the C-style syntax in general. But, a variety of issues kept putting me off Java.

  • My interest was web development, but JSP was slow, clunky, and annoying.
  • The run-anywhere promise had a certain appeal, but the price of portability was poor performance and lowest common denominator functionality  With web apps, you wound up coupled a particular application server anyway, so portability was a low value proposition.
  • I disliked how SUN conducted business. They’d refused to turn the language over to an independent standards body, and were quick to file lawsuits. Their licensing and prices had grown increasingly draconian as well.
  • I wasn’t impressed with the direction many Java libraries were taking, and enterprise JavaBeans was a total mess.
  • The tooling was terrible too. I prefer IDEs to command line compilers and plain text editors. Eclipse was the best Java IDE around, but it was not fun. On my high-end workstation, it often took five minutes to launch; and once open it was still slow, buggy, and feature poor.

In the end, I decided to skip making a deeper dive into Java. I rode out my JavaScript job for another year, and then jumped into a full-time ASP.NET position as soon I could. I have never regretted that decision.

Ten years later, I’m going back to college to grab that long overdue CS degree. Naturally, my curriculum centers around Java. I still have no love for the language, but I am looking forward to learning my way around it more… it never hurts to branch out.

The last ten years have radically changed C#. A C# developer from 2003 would probably not recognize most code written today. So, when I took another look at Java, I’d expected to see a similar progression. I was wrong.

Using Java today feels eerily like being back in 2003  – cranking out blocky-ass code, casting everything six ways from Sunday, and with precious little of the expressiveness and elegant fluidity I’ve grown accustomed to. The only surprising thing about Java is how stubbornly it has resisted change.

Java’s  most significant advance was the addition of generics. After digging deeper though, I find Java’s generics a bit half-baked. They don’t support primitive types, which is super annoying. You can use the reference wrappers, and rely on auto-boxing/unboxing, but it feels clumsy. The syntax for generics is also a bit odd in places. The wildcards are especially interesting, but I’m reserving judgment for now. While confusing, wildcards seem like a good way to handle covariance and contravariance. C# also struggled with those, and its solution wasn’t very intuitive either.

When generics were first introduced in .Net, it gained a significant performance boost across the entire framework. However, Java implemented generics purely as a compiler trick using type erasure, which is an… er… interesting choice. This means Java can’t really optimize around generics like .Net can.

Additionally, Java’s implementation prevents runtime reflectivity over generic types. In C#, I have used generic reflection heavily in a few cases, and was able to produce elegant solutions to some really thorny problems. I’m not even sure how to approach those kinds of problems in Java without generic reflectivity.

Java did pick up some smaller improvements over the years, but they don’t seem to add up to very much:

  • Foreach loop. A simple feature, and a solid win.
  • Annotations. Weak-sauce compared to C# attributes, but just as essential for tooling, code generation, and reflection.
  • Automatic boxing/unboxing. Especially useful given that generics don’t support primitives, and Java has no type lifting (nullable value types to us C# guys). At least auto-boxing/unboxing cuts down the casting cruft. The implementation on the unboxing side gives me the heebeegeebees, but I’ve had no trouble from it in actual practice.
  • Enumerations. One of the few things Java does, arguably, better than C#. Java enums are full reference types, and can implement methods and such. Nice!
  • Varargs (params to us C# folks). A minor improvement, but a handy simplification to a common code pattern.
  • Static imports. Yeah, sure… ok. I don’t often use aliases in C# either.
  • Strings in switch statement. How was that not there all along? More to the point, why does Java’s switch statement still allow fall-through? Why doesn’t it work with all types? Overall, the switch statement in Java still seems horribly broken, but at least it works with strings now… so that’s progress I guess.
  • Automatic resource management via the Try statement. The same as a “using” statement in C#. A useful little feature to have around.
  • Binary integer literals. Anyone who uses binary constants probably loves this, so I imagine there are at least two happy developers out there somewhere.
  • Underscores in numeric literals. Sure, why not!
  • Type inference. Limited to generic types. A more comprehensive type inference mechanism would have been nice, but some is better than none. Complex usages of generics can produce some gnarly expressions, so if you were going to half-ass tackle type inference, generics would be the place to start.

Java is seriously conservative in adopting changes. There are good things to say about stability and predictability, but there are a few other things from C# that I REALLY miss when working in Java.

First-class Properties:

This drives me insane, and there is no excuse for Java not having added native property syntax by now. Properties are easier on the developer, and they make the intent behind your code much more apparent. Java’s convention driven naming pattern of manually written getter/setter methods is a piss-poor substitute.

Extension Methods:

I didn’t really appreciate these when they first appeared in C#, but after getting used to them I find them indispensable for framework development. Extension methods let me quickly add functionality to existing types, even 3rd party components, without any need to modify the original source, write wrapper classes, or create some intermediate abstraction layer.

Lambdas/Closures:

I completely get why these aren’t in Java yet, but at the same time their usefulness is also unavoidably obvious. The sheer number of amazing capabilities C# picked up after adding lambdas is staggering. This feature is slated for the next release of Java, and I sincerely hope they don’t kick the can down the road any further.

Most of the arguments within the java community over this feature are plain silly, and those arguing against lambdas are just plain idiots. I respect Java’s inner and anonymous class implementations. They are slick, and come close to providing full featured closures already. Enhance what’s already there, and full closure support might be a done deal… but if that’s all that’s done, it would fall far short of the full potential. Lambdas are not just about the functionality; the real benefit is providing an elegant and expressive syntax for using the functionality.

I dearly miss lambdas when working in Java, and I’m 100% sure that Java developers will love this feature as much as C# developers do. I just hope the final implementation isn’t as half-baked as generics were.

Ten years ago C# was just a shiny new clone of Java. Since then though, C# has grown and changed rapidly. It has picked up many of the most useful features of functional and dynamic programming, and balanced them successfully against its own static-typed roots.

Java’s lack of progress should  make learning my way around it a lot easier. I’ll have to acclimate to the “Java way” of course. Tackling the design patterns and core libraries of any language takes time and patience, but at least the language itself is simple, predictable, and familiar. I just wish java felt more… alive.

After having used C#, Ruby, and modern JavaScript for so many years, Java just seems old and stagnant. Hopefully, a bit more time working with it will improve my opinion.

 

College at 40

I’ve just wrapped up my first semester at college, so I thought I’d write a bit about the experience so far.

I decided to go for that Computer Science degree I should have gotten in my 20s. I’m 39 now, and have spent 18 years in the IT field — 11 as a professional software developer. Strictly speaking, I don’t need a degree. I’m comfortably employed, well paid, and still enjoy slinging code for a living. But, I’m getting old. Should I need to seek new employment, I’d be going up against people half my age with twice my credentials. Experience matters, but programming is still seen as a young person’s field. Most companies look for people with a “BS in Computer Science, or equivalent degree”, but HR usually doesn’t know what “equivalent” looks like. They have dozens of other applicants who do have the expected degree, so my resume goes to the bottom of the pile. Also, I will not be able to sling code at this pace forever. I’ve often considered teaching as a way to wrap up my career, but for that I’ll need degrees.

So, now I’m a freshman at University of South Carolina’s Upstate campus. I could have gone with an online school, but after years of solo career building and self-study, I really wanted to experience real teachers and living, breathing classmates for a change. USC Upstate is a nice hybrid between a tech/community college and a traditional university. It is a small school, but focuses on real 4 year degrees. There is a sizable population of students living on-campus, but also plenty of commuter and non-traditional students too — though not as many my own age as I’d expected.

The CS program at USC Upstate is very small, so most of the core classes are only offered during the day. I’m very lucky that my job affords a flexible schedule, and that my employer encourages continuing education. I couldn’t attend daytime classes otherwise.

As a late applicant, I ended up with a horrible schedule — five classes, five days a week. The first challenge was finding time to fit in 40+ hours at work on top of a full-time course load. I’m used to 75+ hour work weeks, but still, the combined workload turned out to be too much. I ended up switching my hardest class to an audit, but even at 12 credit hours, I was worn to the bone by the end of the semester. Going forward I’ve had to reduce my course load to part-time (3 classes), and restricted attendance to just three days a week. At his slower pace, I’ll need more than five years to complete the degree, but I’m not in a rush.

Many people going back to school at my age complain that it’s hard for them to keep up with the pace of learning. Learning does become a bit harder as people age, but I have not had as much trouble with this as I thought I would. The nature of my job, and years of self-education, have kept my mind pretty sharp.

The main area where I feel my age is with mathematics. As a programmer, I work “with” math a lot, but it has been a very long time since I’ve worked problems by hand. I usually get the right answers, but I’m really slow at it. I would not have passed my trig class, so I switched it to an audit when it became necessary to free up more time for work. Computer Science is a math heavy curriculum though, so I’ll need a refresher in basic algebra before I can tackle the advanced math classes for real.

In other classes, my age helps some. In particular, my English skills have improved over the years. I’ve written quite a lot professionally, and I type like a fiend. In contrast, the majority of my peers are fresh out of high school, which has apparently fallen way behind the writing standards of my day. My younger peers can do amazing things with math, and their reading comprehension is good, but they turn out papers that would have caused my 9th grade English teacher to commit suicide.

The bar for English 101 was so low that the class was outright painful. As it turns out, English 101 and 102 are just glorified writing workshops. The professor spends a lot of one-on-one time with each student, tutoring and advising them as needed. I respect what the school is doing, but it’s sad that high schools are producing such poorly trained writers that two entire courses have to be wasted on writing workshops. This was hugely disappointing to me. I’d once considered an English major. Even though I chose a different path, I was still looking forward to a refresher on contemporary grammar, and maybe picking up some new writing styles and techniques. I’m not the best writer in the world, but my current skills are so far ahead of the expectations that the classes offer nothing of value to me. I’ve attempting to test out of English 102 just to avoid another class of empty paper writing.

As for my core comp-sci classes, I don’t expect to get that much out of the undergraduate curriculum. I’ll learn a bit of Java, which I managed to avoid professionally, but Java isn’t fundamentally different from C# where I already have deep expertise. I plan to take the C++ course, just to have an excuse to actually do something with the language. Overall, I’ll have to wait until grad school before I really get deep into areas of comp-sci where my self-education was lacking.

This semester, I took Introduction to Computer Science. I don’t perform well when under-challenged, but I managed to stay engaged and interested for most of the course. The bulk of the class was spent programming with Alice, a GUI based development environment designed to teach the fundamental concepts of programming, without tripping students up with text editors and syntax issues. Basically, Alice is the new Logo. I enjoyed messing around with it, but was disappointed to find that Alice isn’t open source. I was unable to contribute fixes for several bugs I’d found, nor could I examine the source code to see how functions and features were really implemented. For me, the hardest part of the whole course was answering test questions based only on material presented in the textbooks, which often do not conform to reality, nor my own considerable personal experience.

On the social front, things have been better than I’d expected. I’m twice the age of most of my peers, and there have probably never been two generations of Americans with such radical differences in their upbringing. I am from the last generation born before the public internet and cell phones. Most of my peers were born after the net went public, and had cellphones in grade-school. I’m also from the under-parented, Beavis and Butthead generation, while my peers were helicopter parented and some still can’t  take a shit without parental guidance. I plan to write a separate post on this topic later, but it has been interesting to interact closely with this particular age group. Overall though, my younger peers are not so different from my own age group, despite the significant social changes of the last 20 years.

While I am old, I don’t quite look my age — though I am starting to show signs of rot at the edges. People tend to see what they expect to see though, so most students assume I’m younger than I really am. I’m still much older in their eyes, but not quite uncle-creepy old.

I’ve never been good at fitting in, but I’ve been pleasantly surprised that the age gap hasn’t been much of an issue. On days when I’m dressed in business-casual for work, I am sometimes mistaken for a professor, occasionally even by other professors. The most significant difference is that instructors tend to treat me with a little more respect, and take my opinions more seriously. Of course, they also expect a little more from me sometimes, but it’s a fair trade-off.

Juggling work and school can be exhausting at times, but so far I’m enjoying being a student, learning new things, and meeting new people. I’ve managed a 4.0 GPA this semester, which is a nice way to start things off.