Showing posts with label rant. Show all posts
Showing posts with label rant. Show all posts

Thursday, January 9, 2014

C++ vs. Java

I'm not trying to start any sort of religious war here; I'm writing this because I've been programming in C++ for the past six or seven months after more than three years of professional Java (and more than ten years in personal projects). So I feel like I have an informed opinion.

Unfortunately, my opinion may incense some: Programming in C++ after being used to Java is like slogging through mud. And here's why:

  • Auto-completion. Eclipse does it badly for C++, and neither Emacs nor Vim will do it automatically. I'm sure I could set it up, but it still would not be as good at it as Java in Eclipse. I am unaware of other choices (don't even try to suggest Visual Studio; nobody uses Windows for real software development).
  • Header files. I need to write one of these, with ancient C include guards around it, for almost every interesting piece of code.
  • Prototypes. I need to repeat myself. I need to repeat myself. It's 2014!
  • Surprisingly, flexibility of where classes can be written. In Java, if I want to write a new class, it pretty much always gets its own new file, and the name of the file is the name of the class. But in C++? It can go anywhere, including in whatever file I'm writing when I decide I want it. And there is no naming requirement for linking headers with source files.
  • Threading is a special case in C++.
  • Memory management. I wish there were more options in Java (stack allocation, for example), but it requires too much extra effort in C++, including destructors. Rust has some interesting ideas around this, but it adds to the number of indirect reference types.
  • Boilerplate code. Java has some, certainly, but C++ has so much more. Refer back to header files and prototypes. And memory management (std::unique_ptr<actualtype> anyone?). And how many times have you written "virtual ~ClassName() {}"? Or, even worse, "virtual ~ClassName();" in a header and "ClassName::~ClassName() {}" (with its multiple instances of repetition) in a source file?
  • Namespaces. Not only do I need to include something, but I still need to either type out the namespace every time, or add a using directive. And then we get back to problems with header files; can't put a using directive there without screwing everything up when someone includes the header. Oh, and they're not implicit based on the file path, so at a minimum I'll need to write each new one twice. Is it obvious yet how much I hate to repeat myself?

But, to be fair, there are a few areas where Java is severely lacking:

  • Memory  management. It is really hard to write a no-gc Java program, and it may be impossible without abusing class fields and sacrificing immutable types. Stack allocation would go a long way here. Seriously. Why is this still missing? You could probably do it with a single new keyword, or by overloading the meaning of one of the operators.
  • Const. I really miss this in Java. Really, really </Shrek voice>.
  • Templates. C++ mostly got this right with weak typing. Java requires strong typing, and you can't really specialize. And they're erased, so you're doubly... Triply screwed.
  • Macros and conditional compilation. Less important (to me) than anything else here, but sometimes I really wish I could define a macro that would evaluate into some repetitive multi-line construct that, instead, I need to type out (usually with the help of block-selection and editor macros). Oh, look at that, more repetition...

It's entirely possible that most of this boils down to how expressive the language is. Either way, maybe it's time to learn Go...

Friday, July 31, 2009

Recession

There's one thing about the recession (and the economy in general) that really bugs me: Debt. Not personal debt so much, but debt owed by governmental bodies.

People complain about how we are becoming a nation of spenders, without saving any money. Where do you think this habit came from? Watching our government! The federal government as well as every single state (as far as I know) owes money to somebody, and is paying interest on those loans.

But, you say, how else would things get done?

Like they get done in the households of people who know how to save! If I want to buy a computer, I save money until I can afford it, and then I purchase it. The same thing goes for jewelry and virtually everything else less than the price of a car.

Loans exist to satisfy the impatience of people. I don't want to wait for 4 years saving money to purchase a new car, when I can purchase it today and pay for it over the next 6 years (notice the time difference there). This is especially true for houses; I don't want to save my money for 20 years to purchase a house, when I can buy it now, move in, and enjoy it while paying for the next 30 years.

But why are governments impatient? Sure that road needs to get paved today, but why not put money aside so that when it needs repaving in 20 years, we don't need to take out a new loan for it?

My problem with governmental debt really boils down to this: It is a black hole. If you borrow money to do something today, then you will need to not only pay back more than what you borrowed, you will also need to borrow more to do that same thing next year (or in five years, or ten years, ...).

So why don't governments save money? Why not tax a little more than you need, invest, and make money, rather than tax less, take out a loan, and lose money (which you will need to replace by taxing more in the future)?

Because elected officials want to lower taxes now, and do not care about the future. I would rather that my taxes went up by 5% today, the government stopped taking out loans, paid off their debt, and was able to drop taxes by 10% in ten years, than have my taxes increase by 1% each year out to the foreseeable future.

So here's my advice to government officials: Once we get out of the current recession, STOP TAKING LOANS! Pay off all of the debt, save some money, and lower taxes as the interest payments start going the OTHER way. It'll be a good model for your citizens, too.

Monday, January 26, 2009

Log4j

Recently I started a new project at work. It is a server-side program suite for managing a large number of devices out in the world, with a database back-end and all sorts of goodies. I decided that it would be a good idea to use a standard logging package, instead of my standard method.

Not that my standard method is bad, it just isn't very flexible. There is a program-wide DEBUG flag set at startup which controls all debugging output of any sort, from any source. Since I'd be working with a much larger system than I'm used to, I thought it'd be nice to use a package with a few more features than 'debugging output is on' and 'debugging output is off.'

So Log4j seemed like the best choice. It's open-source (from the Apache foundation) and provides all of the neat little features that might be useful:

  1. It can selectively turn on/off logging depending on the source of the call.
  2. It can direct logging output to any of a number of different destinations.
  3. It has importance levels, so you can filter out the debugging messages from stable code but continue to see the errors/warnings from the same object.

Sounds pretty good, huh? It certainly did to me. But if that's the case, why am I writing this, you might ask? If you're a loyal reader, you may have noticed that I don't have many positive posts...

Log4j has virtually no documentation. Well... no, let me revise that: Log4j has virtually no free documentation.

There's a short introduction describing what it can do, how fast it is, ... BUT it doesn't tell you how to do it.

There's a FAQ which tells you what it can do, how fast it is, ... but again, not how to do it. It just gives you more details on the same subjects as the introduction.

There's even a Wiki! But no help there, it's aimed at developers of Log4j, not developers of programs using Log4j.

So where can I learn how to use this feature-rich, fast logging platform for Java? Well, you can buy a $20 PDF book that describes everything!

But surely there's information available online, through Google or something, right? No. Everybody just seems to know how to use it, but nobody is saying how they know. Did everybody read the source code? I don't know... I certainly don't want to learn how to use a library by reading its source, that's what documentation is for!

Oh, there are some examples on the Log4j page, and a few more spread around the web, but guess what? They're the same examples! Nobody thought that it would be a good idea to, perhaps, come up with their own to describe the other features that aren't documented on the home page. They just copied the same examples and assumed they explained everything.

So here are a few little pieces to help the lost developer trying to configure Log4j that doesn't want to buy the book or read through the source:

Other useful things you can do are use a rolling file appender (class is 'org.apache.log4j.RollingFileAppender'), which is given a maximum file size. It will output all messages to that file until it hits the max size, and then rename it and create a new one to write to. Here are the properties you should know about with it:

  • log4j.appender.RFA.File=filename.log
  • log4j.appender.RFA.MaxFileSize=1M
  • log4j.appender.RFA.MaxBackupIndex=3

This will append to filename.log until it reaches 1 megabyte, then it will rename it to filename.log.1 (renaming filename.log.1 to filename.log.2 and so on as necessary), keeping files up to filename.log.3, but no more.

You can specify multiple appenders for the root logger like this:

 log4j.rootCategory=ALL, Console, RFA

One more useful trick is to send logger output to specific places. You can do that like this:

 log4j.logger.loggerName=ALL, A2
 log4j.additivity.loggerName=false

That will cause all logger output from that specific logger to go to A2, but not to the root logger's appender.

And finally, to get Log4j working, you need to add a little bit of code to the initialization of your program. I'd suggest doing this in a static block in your main class. You just need to call

 PropertyConfigurator.configureAndWatch(
     "log4j.properties", 5000)

That will cause the properties file that you just wrote using all of the tips I gave to be loaded at startup, and it will be checked for updates every 5 seconds. If it changes, the new settings will go into effect. That allows you to selectively enable logging as you notice unexpected behavior, but not be overwhelmed by log messages all the time.

So what's my conclusion? I know, I jumped from complaining about Log4j to showing how it works and what you can do with it. I actually kind of like the system. It is convenient to work with (except when you need to configure something), it monitors the configuration file so I can enable logging after the program starts, and I can supress messages for parts of the program I've already finished debugging.

So I'd say that you should give it a try, and hopefully someone will help you out when you can't find the right option for your current situation. And if nothing else works, read the source. It's painful, but that's how I figured out the additivity options.

Tuesday, December 23, 2008

Tabs vs. Spaces

You know that 'tab' key on your keyboard? I hate it. Not because it's not useful; I actually like it for the purpose of navigating through fields of a form. I hate it for programming. Why? Because it's another way of making invisible spaces.

Non-programmers are probably already losing interest at this point. I don't blame them; there's not really any controversy about tabs vs. spaces in normal text editing. So let me explain a bit about why it matters to programmers.

Source code (the stuff programmers write) is generally stored in a source-code management system (commonly referred to as an SCM). The SCM is in charge of storing versions of source files, so that as you add features or fix bugs, you can go back and see what changed.

The problem comes in when you change between spaces/tabs, because the SCM will see that lines have changed, but only the invisible, non-functional spaces of some lines really changed. And each programmer has their own view on how tabs should be used, so sometimes one will 'fix' the spacing written by another.

Source code files are written in a very structured format that includes code 'blocks', which are groupings of lines that are related to each other. These code blocks are indented from the left margin to easily distinguish them visually while scanning through the text.

The 'standard' view on tabs, which I disagree with, is that a tab is worth 8 spaces. Beyond that, indentation levels should be in increments of 1/2 tab. The result is that your lines will start with 4 spaces, then 1 tab, then 1 tab plus 4 spaces, then 2 tabs... Alignment of adjacent lines within a block are done the same way, using tabs until you can only use spaces to finish. So basically, tabs are used as a lazy way of writing 8 spaces.

That completely wastes the possibilities of having a different type of spacing character.

My view on tabs is that they should only be used to indent blocks of code. Beyond the initial code block indentation, only spaces should be used to align adjacent lines within a block. The benefit here is that if I like indentation levels of 4 spaces, but you prefer indentation levels of 3 spaces, we can each set our editor tab width appropriately and it will just work. No reason to change someone else's code to match your preference, everything is aligned no matter what your tab width is set to.

But since the two main drivers of source code formatting are the Linux and Microsoft developers... the standard is not going to change. Linux standard practice is 1 tab = 8 spaces, with indentation levels of 1/2 tab width. Microsoft is a little bit better (which is painful for me to say), with standard practice being 1 tab = 4 spaces, indentation levels of 1 tab width. If Microsoft would just go on to say that alignment within a block must be done with spaces, we'd be partway to a better world.

Not that the Linux developers would care; they've hardcoded their editors to do it their way, and seeing Microsoft push something will only keep them from doing it out of spite. But maybe, just maybe, a few of them would realize that the additional flexibility would be beneficial and not just a Microsoft ploy to take over the world. But it probably would be, so nevermind.

Tuesday, October 14, 2008

NVidia CUDA

The other day I picked up NVidia's CUDA (Compute Unified Device Architecture, which I must say is a pretty bad acronym) to have something new to play with. (Some people tinker with car engines, I tinker with software packages... I know, I'm a little odd.) I've always had an interest in parallel programming, so CUDA seemed right up my alley.

Then I tried to install it. Maybe others have had an easier time of it, but my experience was less than top-notch. I run a dual-boot system at home, Windows XP Pro and KUbuntu 8.04.

Windows

I had no trouble at all installing CUDA on Windows, but the compiler that comes with it enforces a requirement for version 7.1 or 8.0 of Microsoft's compiler (Visual Studio 2003 or 2005, respectively). I don't have either of those, and it didn't seem worth hunting down a copy, so I gave up at that point.

Linux

Being created by and for software developers, I've found that the one thing you can always count on in Linux is the C compiler. It never seems to break.

Unfortunately, drivers are another issue. CUDA requires a new version of NVidia's device drivers, and the drivers require a new version of the Kernel module that supports them. I must have installed the drivers four or five times, always getting the same failure back from the device query program that comes with the CUDA SDK. It kept reporting that the driver was version 173.something, and the kernel module was version 167.someotherthing.

I fought with it for a day and a half, only to discover from a forum post that I needed to add "nv" to the list of disabled kernel modules in some /etc file that I'd never seen before. And suddenly it worked! I love that feeling of accomplishment when something suddenly works, even if I needed help. Sort of like when you finally kill the mosquito that bit you three times and has been buzzing in your ear for half an hour.

So expect some updates soon about how my CUDA programming is coming.

Friday, October 10, 2008

My First Day

For a while I've been toying with the idea of creating my own blog. I'm a software engineer, and surprisingly often I will encounter something that I'd like to share. So yesterday I gave in and signed up for a Blogger account. I was reading someone else's blog (can't remember whose now) and saw the sign-up link and just decided to go for it.

After getting through the tedious procedure of choosing a name for my account (my top choices were all taken by inactive blogs with "First Post!" entries from over a year ago), I finally had my own place to post insights/rants about whatever I felt like.

I didn't have anything to say.

I'm sure everybody has the same problem; you get all pumped up to do something creative, and... Nothing comes to mind. So I figured I'd just leave it alone and come back in a day or two with something.

Then this morning I checked my email to find out that Blogger had disabled my account. One fucking day into owning my own blog and they DISABLED MY ACCOUNT. Why? Was it because I didn't have anything to say?

No. It was because my shiny new blog looked like a spam blog to their moronic spiders. What is a spam blog? According to this page it is a blog with nonsensical text linking elsewhere. I assume the goal is to confuse search engines, which rank pages by how many links point to them.

What I'm confused about is how my empty blog looked like I was link-spamming!

Anyway, I went through their page to request an unlock review today (October 10, 2008) and we'll see if they can unlock things as quickly as they lock them. My guess is no.

Edit: October 13, 2008, I am no longer under suspicion of being a spam blog.