How smart developers generate lousy code