Archive for August, 2006

State of Web 2.0 Development

andy on Aug 30th 2006

My background is in writing desktop applications, usually cross platforms ones that run on Mac and Windows. That’s how I spend my days and make actual money. But because of my tenure on Dreamweaver, and all the hype around “Web 2.0″ and “AJAX” I’ve recently been playing around with web applications.

My first toe in the water was with Ruby on Rails, which is apparently all that and a bag of low fat baked Doritos. It offers “convention over configuration”, which means if you name your classes the right thing it does a lot of work for you for free. Rails is, from what I could tell, a nice and complete framework for database backed web applications. I also found Ruby to be a very nice, object oriented, scripting language. All the power of Perl, but with a much better syntax.

More recently I’ve been toying around with PHP, in the form of writing a WordPress plugin. PHP is very procedural based, and has what I would call minimal support for objects, and definitely is configuration over convention. PHP will not do anything for you unless explicitly tell it to, in its very C-like syntax.

I don’t think I would be stretching it to say that PHP is the de facto standard for web frameworks, while Rails is the fastest rising star (although django, written in Python, also looks interesting). But that’s not my point here. My point is they all suck. Bad.

That’s right fanboy, I’m talking smack about your favorite web framework.

I don’t care how easy you think Ruby on Rails is, its still painful compared to developing desktop applications. I’ll completely ignore the usability of web apps in this article, AJAX be damned.

The first paradigm shift I hit when moving from writing desktop applications to web applications was the fact that there is no state. That is, nothing is stored unless you manually jam it into a database or a session variable. This wouldn’t be a problem if every single web page wasn’t a separate program that is run and exits before the user even sees it. This makes any form of interaction with the user an experience in pain. Every bit of effort required to build up state (such as permissions, database queries, objects, etc) is thrown away on each page, every time that page is accessed. If the user submits a form, the web application has to build up that entire state all over again! A large portion of the code for the WordPress plugin I’m working on is just trying to figure out the user wanted to do (even though I had information before) and if they have permission to do it (i.e. they’re not trying to pull a fast one on me). The web form often has to embed a lot of hidden fields just so the web application can remember what the user wanted to do in the first place. A lot of effort is wasted rebuilding information the application already had. Real programming languages and environments don’t require this. It forces a lot of unnecessary work onto me, the programmer.

Maybe there’s a way to save off variables, but its not automatic. In Rails I want to be able to store an instance variable on my controller class and have it be there when the next action is invoked. i.e. It should act just like a desktop application. Bottom line, a web application should be like writing one application, with a shared state, instead of dozens of separate applications that happen to share a common database.

The second wrinkle I ran into was how many languages was required just to write a web application. i.e. HTML, JavaScript, PHP/Ruby, and SQL. Don’t get me wrong, I’m a programmer at heart and love to learn new languages. I just don’t like being forced to use so many when its unnecessary. I’m also fully willing to accept that certain languages are better than others for their purpose. HTML works well as a presentation markup language and SQL works for data queries. That leaves the language that is used for the logic and control. Right now, you have to use at least two languages for this: JavaScript for the client and PHP/Ruby/Python/Perl/etc for the server. Why is that? They’re all serviceable scripting languages. I should be able to write both client and server side code in one language.

As an aside, YouOS, a web-based operating system, allows the you to program everything, client and server, in JavaScript. JavaScript wouldn’t be my first choice, but its currently the only client side language, so there wasn’t really a choice. But it reenforces my point that there should only be one scripting language for logic and control.

The language difference also contributes to the divide between the client and server. I should be able to write all application logic in the same language, and client code that calls server code (or vice versa) should be seamless. i.e. Where’s my remote procedure calls (RPC)?? Its kind of, sort of, but not really there in XMLHttpRequest. It half way exchanges XML documents, but not really in a way that’s all that useful, mainly because clients (web browsers) may or may not be able to parse the resulting XML. Not to mention all the overhead required to parse and generate the XML. Most importantly, the RPC isn’t transparent. I should be able to mark any file, function, or object as server side and the language should automatically know how to do the right thing, without me writing any XML or intermediate code.

Finally, HTML/XHTML or whatever the w3c dreams up next to stave off their own boredom, needs to add some real controls. Push buttons, check boxes, edit fields, and simple listboxes do not cut it. There need to be multicolumn tables, tree controls, menus, etc, and the existing controls need a lot more event handlers. Basically anything that a desktop control can do, I need to be able to do in the web browser. Web application programmers would be a lot more efficient if they didn’t have to keep reinventing the wheel. Also, standard controls would certainly increase usability. Instead, it looks like the w3c is trying to pass off Web Forms 2.0, XForms 1.0, or whatever its called, as the “next thing.” There are some problems with it:

  • Its specification is huge. So huge its only possible use is as fuel on a cold winter night. No human will actually be able to read it.
  • It uses a lot of XML, more than necessary. I assume the conversation that led to this went something like:

    Committee Member #1: Does anyone know how to give the programmers more controls and event handlers?

    Committee Member #2: No, but I like XML!

    Committee Member #3: XML can solve any problem if you don’t think about it long enough!

    Committee Member #1: Great! We’ll jam a bunch of XML in there and hope they don’t notice we didn’t fix anything.

  • It is way over engineered.
  • It doesn’t actually solve a problem, unless too many woodland owls was a problem.

Look, exchanging XML is a huge pain already with the tools currently available. Why would I want more, in even more complex documents? I want controls to communicate with the backend via RPC in native data types. The language can use XML behind the scenes to implement it for all I care, but I’d better not have to touch it.

My point is all this ballyhoo about Web 2.0, AJAX, the web browser becoming an OS, is all crap. There will be no big “revolution” for web apps until the developer tools for the web catch up with those of desktop tools. Programmers currently spend too much time dealing with problems the language and/or environment should take care of. Until that is fixed, Mr. VC, your dreams of Web 2.0 is just an overhyped pipe dream.

Filed in Programming | 2 responses so far

Objective-C 2.0

andy on Aug 27th 2006

Andy Matuschak has a great write up on what to expect in Objective-C 2.0. As someone who didn’t make it to WWDC this year (one of my business partners got to go this year), I found the article very informative.

What’s more, he managed to describe the changes to Objective-C using only publicly available sources (i.e. no NDA violations). Very impressive.

Filed in Macintosh, Programming | Comments Off

OK Go on treadmills

andy on Aug 25th 2006

I have to admit I’ve seen this video on TV several times now, and it never fails to amuse me. The video always looked grainy, in that Flash video sort of way, so I often wondered if it was pulled from online.

Apparently, it was.

I’m not sure why this video always puts a smile on my face, but it does. Maybe its the creative use of treadmills, or the fact that a couple of them look like they could use it a bit more often.

Yahoo also has a write up on OK Go and their now viral treadmill video, which is how I found the above link.

Filed in Music | Comments Off

Xcode scavenger hunt

andy on Aug 25th 2006

I’ve always enjoyed a good scavenger hunt for the way it can get rid of unwanted people without hurting their feelings. This is why they’re particularly effective at the end of a party, when you’re busy, or when you need a reason to have random people arbitrarily obey your whims and enjoy it.

Organizer: Here, go look for these random objects I just thought up!

Participant: OK! Where do you think I can find one of these “cow catchers”?

Organizer: Just stand on these tracks and it’ll come right to you.

Participant: Wow, thanks! I love scavenger hunts, they’re so fun!

But I digress.

Surprisingly, there are ways to have a scavenger hunt without committing a felony. I’d like to try one now. See if you can find the following things in Xcode:

  • Your dignity, when the Xcode’s linker locks up the entire machine, except for iTunes, and your business partner calls and you have to explain why The Breakfast Club soundtrack is blaring in the background.
  • Which symbol you haven’t defined, but your linker won’t tell you about, because Xcode turns on ZeroLink (motto: We eliminate the most important job of a linker so you don’t have to!) by default in hopes that you’ll give up on your product idea, and just email it to Apple directly thereby cutting out the middleman.
  • The file you just had opened, but accidently closed, but can’t access from the Open Recent menu because source files aren’t project files, and nobody ever needed to quickly access anything but project files, you big jerk.
  • A button in the Find in Files dialog that says, “No thanks, I don’t want a Find Set, I’d just like to search this folder.” Bonus points if it doesn’t require creating a Find Set to enable it.
  • Any way to make Open Quickly slower or more inconvenient. Requiring three or more keys to invoke it or ensuring it searches the smallest set of files possible do not count, because Apple has already thought of those. (Hint: it should include Find Sets in some way.)
  • A clue of what might should happen when you double click on a function in the debugger’s call stack. (Hint: Look at CodeWarrior.) If you find this, don’t give it to me, email it to the Xcode team. They need it.
  • The state of the program when a call to DebugStr() or Debugger() happens and Xcode quickly, efficiently, and without error doesn’t stop for them.
  • Code demonstrating the technical reasons for why Xcode can’t save the window locations of a project when the files they are stored in are not locked, although the file next to them is. (Hint: the code should invoke the Heisenberg Uncertainty Principle, or involve a lot of illegal narcotics.)
  • A flowchart that explains the optimal way in which to obtain the new developer documentation that Xcode insists on telling me about every five minutes, in an application modal dialog. Bonus points for why its not in the Software Update or why you need an NDA to read about how Quickdraw is deprecated in four different languages.
  • The cure for Xcode’s Alzheimer’s, who cannot remember between runs that I selected “Show Types” in the debugger, despite the fact that I yell at it each time to remind it.
  • Your brain, after attempting to determine what correlation or relationship there is between what you selected for Go To Symbol (command-double click), and what Xcode actually retrieved.

How many were you able to find? Entries can be submitted via Apple’s Blackhole of no Return, which, for some reason, they insist on calling “Bug Reporter.”

Filed in Macintosh, Programming | Comments Off

C++ inline abuse

andy on Aug 21st 2006

I’m not sure what it is about inline that makes people abuse it. Maybe its the assumption that its an easy way to increase performance or that it saves time when writing code. Unfortunately, misusing inline often causes more problems than it solves.

The only legitimate use of inline is to increase performance. If you’re calling a function a lot, and the overhead of the actual function call is a significant portion of the time spent, then inline is appropriate to use. The overhead doesn’t include the actual body of the function, but the prologue and epilogue that set up and tear down the stack. So if you’re trying to increase the performance of a function itself, inlining won’t help you.

For some reason, some people think inlining is a harmless way to get performance increases. That is, just inline whatever you feel like and you’ll obtain a performance boost, with no adverse side effects. If only that were true.

Problem number one with inlining is maintenance. Anytime that you modify an inline function, anyone who even includes that header file has to be recompiled and linked, regardless if they use the inlined function or not. If you’re on a project of any size, that could turn out to be a lot of files. As a result, inlining increases build times, thus lengthening development cycles.

Problem number two is readability. Most engineers realize that well designed classes encapsulate and hide the implementation. In a way, inlining breaks that by showing implementation in the public interface. Hopefully, most well written classes are used (read) more often than they are modified (write). If I’m trying to use your class, I scan the public methods. If you have inlined functions in your public interface, that’s a lot more code that I have to climb over to get the information that I want.

The other part of readability comes in when debugging. I’m not sure why, but when people inline functions they like to put it all on one line, as if the compiler charged per line used. If someone else comes through and tries to debug the inlined function, its impossible. They cannot set a breakpoint where they want, nor can they accurately step through the statements. Personally, this is one of the more aggravating problems of inlining, although its not inherently caused by inlining.

Also, by putting inlines in the header, you separate that part of the implementation from the rest of the implementation. Most people go to the implementation file (.cpp) when they want to figure out how things work. But then they have to start switching between the header and implementation files, if there are inlines.

Problem number three is code size. Don’t forget what inlining actually does. It copies that code into the places where the function would normally be called. In some cases, it doesn’t increase the code size by much. But for large functions or functions that are used all over the place, this can result in a significant increase in the executable size. That means more paging out to disk, and a longer download if you are distributing over the web. That might be fine if you’re getting an actual performance increase.

Of course, this all assumes inlining will get you better performance. Most of the time it won’t. For most accessor functions there is little or no overhead to calling that function. On the PowerPC functions that do not call other functions can operate in the “red zone,” which means they don’t have set up or tear down a stack frame. So there is very little performance increase in that case.

Furthermore, most inlines aren’t called enough times to save any real time. By real time, I mean time the user will actually notice. Remember, inlines only remove the time required to set up and tear down a stack frame. The time to do that usually isn’t that significant unless you’re calling the function thousands of times in a very short interval. If you just call the function fifty times when the user selects a menu item, sorry, no one will notice that its inlined. You are not giving the user any benefits. But you are inconveniencing yourself and other developers.

There does seem to be one popular reason to use inlines that I do not understand. That is, to save the developer time when writing code. Yep, apparently some people can’t be bothered to switch to the implementation file when writing functions, so they will simply inline the function where they declare it. They are not even attempting to use inlines for the purpose they were invented, but do managed to foist all the disadvantages of inlining on the function. It is a lose-lose situation.

Worst of all are virtual inlines. That is, functions that are declared both virtual and inline. I’m not sure how the authors of these functions actually expect these to work. Inline is a suggestion to the compiler, not a command: just because you ask, does not mean you will receive. A compiler cannot inline a virtual function, unless it knows its type is static. e.g.


class Foo {
inline virtual void bar(void) {
std::cout << "hello world" << std::endl;
}
};

...

Foo foo;
foo.bar();

In this case, bar could actually be inlined because the compiler knows what type foo will be at runtime. However, in most cases, virtual functions are used like this:


class Foo {
inline virtual void bar(void) {
std::cout << "hello world" << std::endl;
}
};

void CallBar(Foo* foo) {
foo->bar();
}

In this case, the more common case, the compiler can't inline. foo could be a Foo or any other derived class that overrides bar(). Once again, all the inconveniences of inline, without any of the advantages.

Don't get me wrong, I'm not trying to say never use inlines. There is a legitimate use for them. You use them when a function is called enough times that the overhead becomes significant.

There are certain guidelines I follow when using inlines.

First, I only use inlines for performance reasons, and only when a performance tool, such as Shark, indicates a problem. Some engineers just start inlining functions in a module when they think that module is slow. That makes no sense.

Think of it this way: when you get a crashing bug, what do you do? Do you start randomly start changing code in the module where you think the crash is happening? Or do you use a debugger to figure out where the crash happens, and only change code after you've determined the cause? I think just about everyone uses a debugger to determine the cause first. In the same way, performance problems are just another bug. But instead of using a regular debugger to find the problem, you use a performance debugger, such as Shark, to find the problem. Then you change the code.

Second, when I do use inlines, I don't put them inside the class declaration, but at the bottom of the header file. Like so:

class Foo {
inline void bar(void);
};

inline void Foo::bar(void) {
std::cout << "hello world" << std::endl;
}

That way, the implementation is inlined, but out of the way so the public interface is easier to read.

Third, I try to determine if I can change my algorithm to simply not call the function as often. It is frequently a more drastic change to make, but it also frequently is a more drastic performance increase than a simple inline.

In the end, inlining can get you performance increases. Just not as often as most people think, and not without some complications.

Filed in Programming | 4 responses so far

Bad Behavior has blocked 1074 access attempts in the last 7 days.