12/21/2010

12-21-10 - Rambles

C++0x will make lots of new styles of template code practical. It occurred to me the other day that complex template patterns that don't work in current C++ (C++98 ?) just don't even enter my mind any more. When I first started writing C++ I had all these ideas, you know, you start playing with the medium, oh I can do this, I can express this, but then you start running into limitations of the language and the compilers and practical issues, so you just stop doing those things.

The dangerous thing is that you stop even thinking about those possibilities. Your mind becomes so locked into what is practical with your current tools that the ideal doesn't even enter your mind.

It struck me that I'm now in this position with C++, whereas when I was new to it, my mind was fresh and unbiased by this stale old knowledge. Someone who just got into C++ with C++0x would not have that irrelevant historical bias, and would jump right into doing things in new, better ways.

It also struck me that I ran into this a lot as I was coming up in software. I would talk to older practitioners that I respected about ways of doing things, and they would at times tell me that such and such was a bad idea, or that what I was suggesting wasn't possible or practical, when I was pretty sure my idea was good. In hindsight I was almost always right on the technical issue. Obviously the more experienced person has a lot to teach you about restraint and the pitfalls of coding and so on, but they can also hold you back with outdated ideas.

Winter here is so bloody fucking depressing. It starts affecting me in all sorts of weird ways that I don't realize are just winter depression. Like, I start sleeping in a lot and just generally wanting to lay about a lot; okay, that's easy to recognize as depression and I catch that one. But then I also start thinking about buying random things. I already bought a damn PS3, and just moments ago I bought new floor mats for my car for unknown reasons, and I was starting to think about getting a supercharger when I suddenly realized - my god this is just winter depressed shopping. Obviously a lot of consumerism comes from depression. And just like binging on desserts or booze or whatever, it feels good very briefly and then just feels worse than ever.

Another weird side effect of winter depression is that I start thinking about politics. When I'm running around in the summer time and I see people saying "we need government off our backs" I might briefly think "hmm, that's odd, I don't see government on our backs hurting us anywhere, in fact I see quite the opposite, a severe lack of government interference in our lives causing problems right up and down through every level of society". But in the summer time I say "oh well, whatever" and go off bike riding. In the winter I stew on it until I get angry.

I was doing some research for a political blog post that I deleted, and I realized something. When I do scientific research I try to be open to anything, unbiased by preconceptions about what the answer will be. Often I have a hypothesis about what the best approach will be, but if I find conflicting evidence I am ready to change my mind. But when I do political research, I already know the point I'm trying to prove and I'm just looking for data to back it up. I already have the idea that I want to write about in mind and I just want to find "experts" or data to make it seem more "legitimate", which of course is not really research at all (and is a pretty sleazy way to add impact to your argument, though it's beyond standard practice). Of course some people do scientific research that way - they already know the outcome they want to prove and they just keep trying until they find a study that proves it (yes I'm looking at you, medicine).

Doing things "the best" is egotistical self indulgence. Anybody can do it if they waste enough time on it. (Charles' quick recipe to doing anything "the best in the world" : find out how the current best in the world does it, first make an implementation that matches them; then read some other papers and steal some other ideas; put them into your current implementation and tweak until it provides benefit; tada!). One of the things I was really proud of at Oddworld was that we didn't try to do each thing "the best" ; obviously sometimes we self-indulged a bit once in a while, but in general I think we were pretty good at staying away from that childish competitiveness that plagues so many game developers who want to have "the best" graphics engine or whatever. The productive way is to do it well enough for your use case, and then move on to the next thing. That's the only way you can knock out tons of code quickly.

When I'm procrastinating, I start making up all these strange things that I decide are a good idea to do. I feel like I need to be busy doing something productive, I won't just let myself sit on the couch or be nice to my girlfriend, but I wind up doing things that are completely pointless; recently I started writing my own email client, and making air scoop screens for my car, and replacing all the air filters on all the appliances in the house. When I'm doing it I have no concept that I'm procrastinating, in my mind this is a "todo" item and I'm taking care of things, but then I have a moment of clarity and I'm like "whoah wtf am I doing this for?" and realize that I'm just avoiding the work I should be doing.

9 comments:

Autodidactic Asphyxiation said...

"Obviously a lot of consumerism comes from depression."

Interestingly, I went searching for this, and it looks like there are a lot of articles saying that depression comes from consumerism! I think yours makes more sense, although I basically just scanned a few headlines. They probably all are journalistic (hah) interpretations of some psych journal written by someone who doesn't know the difference between correlation and causality.

Anyway, is there a good article or something that talks about your version?

C++0x seems kinda cool, but there are lots of caveats. For one thing, it isn't ABI compatible. Libraries that transact in std::string will be annoying to deal with.

johnb said...

"I would talk to older practitioners that I respected about ways of doing things, and they would at times tell me that such and such was a bad idea, or that what I was suggesting wasn't possible or practical, when I was pretty sure my idea was good."

You've gotta be careful with this though. Sure, it's certainly possible for young, inexperienced programmers to come up with new ways of doing things that are better than the old way of doing it, but young inexperienced programmers also tend to take advantage of language features to do a bunch of "neat" tricks that look good to them but that the older, more experienced ones know are a bad idea (usually because they make it much easier to make mistakes when using the code).
For example, putting implicit type conversions all over the place.

"The productive thing is to do it good enough for what you need, and you move on to the next thing. That's the only way you can knock out tons of code quickly."
But as I think you've said in the past, sometimes the right thing to do is to really solidly finish a piece of code, even including optimisations and possibly functionality that you don't need that instant, because then that code is *done* and you don't have to think about it any more, it becomes a library that you use according to spec (like you would use a good 3rd party library), rather than code that you use but think "hmm... is this actually gonna be fast enough for this use-case?" or "will it work properly if I use it this way?"

cbloom said...

"But as I think you've said in the past, sometimes the right thing to do is to really solidly finish a piece of code, even including optimisations and possibly functionality that you don't need that instant, because then that code is *done* and you don't have to think about it any more"

Yeah, this is true, I have regrets in that direction as well. For example I wish I had just really put the time into my image code a long time ago, so I had a suite of filters and transforms and such that was really solid; instead I add on another layer of hacks each time I work on that stuff.

Though I think that if you step back from the problem a bit, you can tell when you are spending time on a problem for no good reason. Certainly when you are tweaking something out to the Nth degree. It can be hard to see it when you are in the trenches working on it. This is one situation where having a smart lead or producer can be helpful, you sort of lose the forest for the trees when you are in the code.

cbloom said...

"but young inexperienced programmers also tend to take advantage of language features to do a bunch of "neat" tricks that look good to them but that the older, more experienced ones know are a bad idea "

Yeah, BTW I didn't mean to imply that exploiting the latest crazy tricks is good programming practice.

Experienced coders are rightly afraid of *all* new neat tricks, because they've seen it all before, new tricks that are supposed to be great and just cause trouble.

The problem is the experienced coder isn't even thinking in the new way.

I've been thinking that I saw the same thing in physics.

You would see old profs write Maxwell's equations in non-covariant form with dots and horribleness, and it looks so complicated. New kids will just write box A = J and it is clear that the field equations for a 1-form fiber bundle must take that form.

That is, by coming up in the more modern era, you pick up a whole new way of looking at the same things that sort of wires your brain in different ways.

The old people tend to be curmudgeonly and say "oh it's the same thing, my way works fine" but in fact the youngsters have found a new better way.

ryg said...

The evolution of C++ code as it is being written has primarily been an evolution of idiom, not the language itself.

To give an example, it turns out that about the only sane way to use C++ exception handling is by carefully following RAII. That's not in the language; that's just how it works out in practice. There's tons of such examples.

Learning how to use C++, the standard library or Boost is not a matter of reading the spec. You spend at least as much, if not more, time learning all the idioms and the rules you need to follow to actually be productive.

That's true to some extent with all languages, but for C++ it's fairly extreme. I think it's not exaggeration to say that the Scott Meyers and Herb Sutters have a lot more influence on the way C++ code is written than the ISO C++ committee will ever have. Ultimately, the success of any new technique will crucially depend on how well it interacts with the large existing bag of tricks, not so much how well it does on its own.

ryg said...

"You would see old profs write Maxwell's equations in non-covariant form with dots and horribleness, and it looks so complicated. New kids will just write box A = J and it is clear that the field equations for a 1-form fiber bundle must take that form."
Interesting that you'd mention this, because one of my primary gripes with a lot of existing C++ features and idioms is that they're both notationally and semantically awkward (with "semantic awkwardness", I mean using constructs for their side effects, not their primary purpose - e.g. how classes are used for RAII).

I'm fairly ambivalent about the changes in C++0x that actually introduce new concepts to the core language (e.g. rvalue references, variadic templates) or make the syntax even more irregular (new function declarations, new initializer syntax, user-defined literals).

By contrast, the things I really like about 0x are the cleanups and notational improvements - "auto"/"decltype", strongly typed enums, constructor delegation and explicit virtual function overrides. All of which are (arguably) more in the spirit of the notational improvements in physics you mention than any of the stuff that actually adds new capabilities to the language.

johnb said...

"The problem is the experienced coder isn't even thinking in the new way."

One way to get around this is to jump between different programming languages.
This works for two reasons: First because different languages encourage different approaches and you can often take some aspects of those approaches back across the border. And, second, because you may be a C++ veteran who barely even thinks about how to solve problems any more because the "right way" (even if it isn't the right way) is obvious to you, but you probably haven't spent as much time using Python/Ruby/Haskell/Go/insert-language-of-the-moment and so you're more open to exploring the possibilities of implementation in your secondary languages.

And programmers are good at abstraction and picking out the essence of an idea, which helps a lot with bringing things with you when you cross language borders.

cbloom said...

"One way to get around this is to jump between different programming languages."

Yeah, I have friends who do this. I always sort of rolled my eyes at them, because it's absurdly inefficient if your goal is to make a product (eg. certain unnamed people who think it's wise to write their game in OCaml or whatever).

But it is a good way to keep your brain fresh.

I've also seen that people who switch around languages all the time think about programming in terms of abstract algorithms that are not tied to a specific language, whereas I tend to think in terms of C (I used to dream in C back when I was really coding a lot).

If you use the same language and work on the same types of problems all the time, you can be very efficient, but your brain also stagnates and gets stuck in local maxima.

Autodidactic Asphyxiation said...

There are lots of reasons why it is hard to get out of local minima like: http://en.wikipedia.org/wiki/Mere_exposure_effect

I know some people who are using "Seven Programming Languages in Seven Weeks" to get them to think about different programming paradigms:

http://www.amazon.com/Seven-Languages-Weeks-Programming-Programmers/dp/193435659X

old rants