Signs that you are a bad programmer
yacoset.com
yacoset.com
A: GOOD MEANS SHIPPING AND PLEASING YOUR CUSTOMERS
B: NO YOU FOOL! GOOD MEANS WRITING CLEAR CODE THAT OTHER HACKERS CAN READ
C: NO YOU FOOLS! GOOD IS A HAPPY MEDIUM BETWEEN BOTH OF THOSE THINGS
D: DEBATE IS HARD, LET'S GO SHOPPING!
God forbid we agree on what words mean before we talk about them...So of course that "good" tradeoff to one programmer might be a "bad" one to another.
When talking about "Good cars" for instance, what makes a good car for a mother of 5 is likely different from what makes a good car for a single person who is very worried about the environment and both of those are different from a "Good car" for drag racing.
Defining the word "good" is a philosophical rabbit hole for sure, but if someone comes out and says "a good programmer is someone who writes maintainable code", and someone else comes out and says "a good programmer is someone who writes fast code", and someone else comes along and says "a good programmer is someone who writes code that pleases the customer", you're still having a meaningful discussion about which "good" is better, so to speak.
The article is almost in the 'you might be a <foo> if <bar>' style (most common instantiation I am familar with is 'you might be a redneck if <insert denigrating attribute of redneck>' And in the spirit of that humor I liked it.
That being said, if you ask me as a hiring manager what I consider 'good' programming, its 'readable/understandable', it does what it is supposed to do, and it has tests.
Bad programmers are all alike; every good programmer is good in his or her own way.
If programmer A understands recursion and programmer B does not programmer A will write better code regardless of deadlines.
Clients and fellow programmers are still happy with your work two years after you've delivered it.
(Of course: "still" implies that they we're happy at delivery, which includes actually shipping working software in a timely fashion.)
Ignore those.
Disagree. The first system I wrote kept the client happy for years. It was a mess, but it was literally millions of dollars better than not having any system.
If what you mean is something like "focus on doing work of long-term value, and consider programming skill as such an input", then I'd agree with that.
Did your client ever hire programmers to maintain and improve the first system you wrote? Were those programmers happy with your work?
I guess if no one is ever going to maintain your code it doesn't matter as much. I wouldn't ever be so bold as to predict ahead of time whether that's going to be the case.
Can a mediocre programmer tell the difference between mediocre code and good code?
To the original point, the happiness of the client and other developers is a good indicator, but not the only.
Can a mediocre programmer tell the difference between mediocre code and good code?
Maybe not directly, but they can probably tell how well they understand the code and how hard it is to change. Not as well as a good programmer, since they'll have more trouble with both regardless, but somewhat.The maintenance programmer should be competent, but shouldn't have to be brilliant to understand what's doing on (except in the rare case that your code actually is doing something brilliant). If the maintenance programmer doesn't understand a basic language feature, it's his fault if he doesn't understand your use of it (be it ternary operators, blocks, list comprehensions, regular expressions...). If the maintenance programmer does understand ternary operators but you do something like nest them four layers deep, it's probably your fault if he gets lost.
* Disclaimer: maybe I've seen so many "you're doing it wrong" posts that I see something in the opposite direction and get too excited.
But then, that's what makes something like PG's "Great Hackers" (http://www.paulgraham.com/gh.html) rare. It takes a lot of things: education, some innate ability, good habits, work environment -- including a good team...
Innate ability isn't a huge factor, but writing wonderful code definitely isn't for everyone. So then, what is to be done with all the mediocre code being produced? I don't see the world overrun by it, long term: code is too expensive. But to get there, something definitely needs to be done.
I've cooked meals for people that were impressed and happy, does that make me a great chef? Perhaps the people I fed are easy to please, have a simple tastes, spend most days eating unflavored oat meal.
If i'm capable of changing a car's spark plugs, and it continues to run well does that make me a great mechanic?
People having low or incorrect expectations does not change the overall quality of something you create or deliver.
That being said, if you are in a team and you know you all will have to extend or maintain the code at some point, then discussion of coding style, program features, choice of data structures, etc, is healthy. These things are important for a growing application, getting them right will make the software more robust and make maintenance more efficient.
For instance, in C the * character is used both to declare a pointer and to dereference one and they can be stacked to dereference nested structures. Then & references a variable memory location but is also used in method signatures to change the semantics of calling a function into pass-by-reference. To complicate & further, & is often seen alongside const declarations, which are a whole other thing that people have to keep in their heads.
On top of all of this, * and & have their own operator precedences and associativities that you have to memorize, which is a whole discussion about binary versus unary operators and precedence tables. And I didn't even mention [].
I really don't think that people fail to comprehend pointers because their mental models need updating nearly as often as they just haven't fully internalized all the hoops that C makes you jump through to mess with pointers.
This problem can be solved by thinking of * as always dereferencing a pointer. So:
int *a; /* "*a" is an int, thus a is a pointer to one */
int *b, *c; /* *b and *c are both ints */
This also has the nice side effect of explaining why good C programmers write the * next to the variable name and why multiple variables declared on the same line all require a * next to the variable name.> Then & references a variable memory location but is also used in method signatures to change the semantics of calling a function into pass-by-reference. To complicate & further, & is often seen alongside const declarations, which are a whole other thing that people have to keep in their heads.
Now it sounds like you're talking about C++ moreso than C. In C, & is pretty much always the "address-of" operator (except in contexts where it's clearly logical- or bitwise-AND).
From your post, it seems that the problem is more one of poor teaching, poor explanations (metaphors), or poorly-designed extensions (C++) as opposed to shortcomings of C.
[The pervasive use of the assignment statement] influenced many programming languages and programming courses. This resulted in a confusion akin to the classic confusion of the map and the territory.
Compare these two programs:
(* Ocaml *) │ # most imperative languages
let x = ref 1 │ int x = 1
and y = ref 42 │ int y = 42
in x := !y; │ x := y
print_int !x │ print(x)
In Ocaml, the assignment statement is discouraged. We can only use it on "references" (variables). By using the "ref" keyword, the Ocaml program makes explicit that x is a variable, which holds an integer. Likewise, the "!" operator explicitly access the value of a variable. The indirection is explicit.Imperative languages don't discourage the use of the assignment statement. For the sake of brevity, they don't explicitly distinguish values and variables. Disambiguation is made from context: at the left hand side of assignment statements, "x" refer to the variable itself. Elsewhere, it refers to its value. The indirection is implicit.
Having this indirection implicit leads to many language abuses. Here, we might say "x is equal to 1, then changed to be equal to y". Taking this sentence literally would be making three mistakes:
(1) x is a variable. It can't be equal to 1, which is a value (an integer, here). A variable is not the value it contains.
(2) x and y are not equal, and will never be. They are distinct variables. They can hold the same value, though.
(3) x itself doesn't change. Ever. The value it holds is just replaced by another.
The gap between language abuse and actual misconception is small. Experts can easily tell a variable from a value, but non-specialists often don't. That's probably why C pointers are so hard. They introduce an extra level of indirection. An int* in C is roughly equivalent to an int ref ref in Ocaml (plus pointer arithmetic). If variables themselves aren't understood, no wonder pointers look like pure magic.
Sure, say that hindsite is 20-20, but I knew C was busted long before I learned anything about objects or monads etc. Syntax is goofy, backward as you say (I thought that the 1st time I ever saw a C program decades ago); its promise as an expression-based syntax was botched and mortgaged, resulting in generations of hacks; its fundamental expression evaluation syntax was broken to begin with, and as patched its cumbersome and baffling at times. </rant>
My version:
Your code sucks.
Alternative careers: "Do you want fries with that?"
OP's version: 1. Inability to determine the order of program execution
Alternative careers: Electrician, Plumber, Architect, Civil engineer
2. Insufficient ability to think abstractly
Alternative careers: Contract negotiator, Method actor
3. Collyer Brothers syndrome
Alternative careers: Antique dealer, Bag lady
4. Dysfunctional sense of causality
Alternative careers: Playing the slot machines in Vegas
5. Indifference to outcomes
Alternative careers: Debt collection, Telemarketing
So the real test of a good programmer is one who can write a routine that crawls the source code of a bad programmer and tells them what they should really be doing.An example that bites Haskell programmers are space leaks due to too much partial evaluation and not enough full evaluation. Other problems include keeping a file open for too long and leaking the fd. An ideal computer has infinite space and no files. A real one... nope :)
The advantage of functional programming languages is that you get to write part of your program as though you have an ideal lambda calculus evaluator. But at some point, you still have to realize that there's a grey box under your desk that doesn't know what a lambda or fixed point is. (But this is better than programming languages that say "hey, you've got a heap, a stack, and some registers! well, so long!")
What is the proper name for the bit of code that's currently being executed? I've suddenly realised that its a concept you think about constantly when coding, but its so much a part of the scenery so to speak that you never consciously consider it.
Edit: just realized I didn't really answer the question, I believe what your actually talking about is a statement.
I usually jump at the chance to talk about stuff from my old EE days :)
Currrent statement or active statement at the code level
I know that when I'm in the flow coding, there is a sort of Tick:the-program-does-this, Tock:the-program-does-that stepwise execution of the code in my head.
There are many answers as to what the hardware is actually doing with the instructions, but more generally what exactly is the name of an imaginary discrete state of a program that currently only exists in a coders head?
This is what I'm trying to get at. There isn't one is there? It's weird.
I would have used 'Cursor' or 'Program Cursor'. But I'm now convincing myself that that a database term.
Worse yet, programmers who could actually benefit from an article like this (i.e. programmers who shouldn't be programmers) won't understand it. E.g. "(Functional) Creating multiple versions of the same algorithm to handle different types or operators, rather than passing high-level functions to a generic implementation" - a bad programmer won't understand what is meant here, so he will simply skip over it and not get the hint.
Finally, I find the notion that you can't be a good programmer if you've never really used Lisp laughable.
I have seen coders with CS degrees from top-tier schools believe that they couldn't code anymore when placed in environments that do not mentor them, that treat them as horses to be run until their backs break.
If you feel this way, take a part-time job and focus on becoming a better coder. If you are a business that does this... no wonder you waste money on recruiters.
If their business plan doesn't include time for improvements of the processes it's a failure. Leave now. Don't try to make up for their mistakes. They won't see it (positively), let alone reward you for it.
Do good for your old co-workers by recruiting the good ones into the more-functional company.
Fortunately, my group typically allows for 10%-20% of my time to be used for either training (learning new tech/languages) or process improvements (mostly internal tools). Other groups at the company don't have it so lucky, and those are the groups that desperately need improvements.
Every company/division/organization has priorities and while there maybe inefficiencies in their processes, they maybe a minor cost in relation to the other priorities. (I can't believe I actually just played devils advocate/defended this).
This doesn't mean they have to stop and fix every non-problem, but if there's no time budgeted to fix what comes up the first real problem will ruin everything.
http://www.yacoset.com/Home/signs-that-you-re-a-bad-programm...
I would rather work with an actual "bad programmer" than with the kind of person who'd spend their time thinking up "alternative careers" for these people.
I kinda think it's like the Roth test for obscenity. I can't really explain what makes a shitty programmer, but "I know it when I see it."
Most people I've worked with over the years have understood their limitations and would never consider themselves great, with the possible exception of half a dozen or so folks, who truly are great.
There have, of course, been exceptions, too.
I've only had the pleasure of working with a handful of what I considered truly great programmers. I don't think a single one of them considered themselves to be "great" even though I thought they were.
Thinking that you are better than another person just because they haven't focused on your own domain of knowledge is arrogant and delusional, and in my experience many of the truly great are humble in the extreme (think Dunning–Kruger effect).
That said, a bad programmer can be a big problem if you are victim to their work. The same could be said for a bad taxi-driver or chef.
I think the article is more in the spirit of making fun of bad practices than character assassination, and that's something I can support :)
But seriously, it probably never occurs to bad programmers that they should be finding articles like this.
Perhaps a better title/approach would be "A Bad Programmer Taxonomy, And How You Can Help."
I'm forever being told to work on the next MOST IMPORTANT THING EVER only to be told after a few days that I need to work ON THE NEXT MOST IMPORTANT THING and that the MOST IMPORTANT THING EVER that I was working on is no longer important at all.
le sigh
...
"You can forget about your deadline if you want that in, boss."
* skip forward a week *
"Hey, FuzzyDunlop, we're a day before deadline but..."
Get chewed out proper and at least you know it's just because jobs have to be done.
Followed that doc for the next month or two.
Of course, the asshat was ticked off when the semester was about to close and tried to edit the doc (for the first time). I just said no.
I consider it a success even though even Those Kids who contribute nothing got As and I got a B+ despite working quite a bit.
I feel like this might give people the wrong idea. Surely some amount of cohesion is desirable. Also, I'm not quite sure how one "gives the appearance of refactoring" without actually refactoring. Whether it's useful or not may enter into it, but I would usually consider the breaking out of chunks into subroutines refactoring.
Given the choice between reusability and readability I'd say that readability should usually win (although it is a false choice).
Chunking for the sake of itself doesn't seem like a viable strategy to me.
"These two blocks of code do something different"
Thats what is normally called a method. If it's only for one class then by all means make it private and name it well, so the caller remains readable.
Whitespace and comments can suggest that some pieces of code don't interact that much, but chunking into functions lets the compiler prove it.
I also refactor for the sake of readability (and urge my co-workers to do the same). Of course, this might mean I'm a bad programmer and I shouldn't ever get 6 levels deep in logic in the first place...
DO_F() {
A;
B;
C;
D;
B;
C;
D;
E;
F;
A;
B;
C;
D;
G;
H;
I;
J;
A;
B;
C;
H;
I;
// a bunch more
}
So I suggested, "hey perhaps you should break this into functions" and got back: DO_F() {
A;
B;
C;
D;
B;
C;
D;
E;
F;
A;
state.a = a;
state.b = b;
// ... for other state
return DO_F2(state)
}
DO_F2(state);
B;
C;
D;
G;
H;
I;
state.a = a;
//...
return DO_F3(state);
}
DO_F3();
J;
A;
B;
C;
G;
H;
I;
// a bunch more
}
When I suggested blocks such as B; C; D; or G; H; I; could be functions, and perhaps a loop could be useful too, the guy looked at me like I was trying to do voodoo and got really defensive about how that couldn't possibly work.I think that is what the OP meant by bulldozer code...
I somewhat disagree with:
> 6. Cannot fathom the Church-Turing Thesis
Truly understanding the Church-Turing thesis probably requires more computability theory than the two-week overview even top CS students and otherwise great programmers get in their ABET-required Discrete Math course. It would be great for more people to have an understanding of what a computable function is and isn't, because it would make it easier to explain why we don't have more fancy-pants type systems around,\footnote{Inference is undecidable for most interesting ones.} but it certainly isn't a requirement for great or even good programmers.
Mathematicians may have more luck in their training. But that depends on your chosen speciality.
I hope this isn't used by some to push the mantra that 'not everybody can code'.
On the other hand, I doubt the author was trying to discourage bad programmers, but rather bring common deficiencies or mistakes up to help programmers avoid them. To me, many of these are signs that you are a new or inexperienced programmer, not a bad one (although if you've been a programmer for a decade and are still making them, you may have something to worry about).
That could just be OCD rather than bad programming.
My one indicator that someone is going to be a bad programmer actually has little to do with technical skill sets, but rather personality. As my sanity check, I make sure to examine the open-mindedness (willingness to research and use unfamiliar tools) of programmers. More often than not, you find programmers who are very comfortable in given languages, environments, tools etc, but once you take away their comfort blanket, they keep reaching back for it.
An extreme example would be a scenario such that a programmer who knows C very well decides to do a decent amount of parsing in C instead of researching better languages for the job such as python or perl.
Of course it's malice.
Note: i did work on a real product which had parser inside that had such style of repair implemented, and such approach is also quickly mentioned in the dragon book as well
A better point is that the error messages from many compilers can be very obscure. This was particularly true 10-15 years ago.
Clang does something like this. If it notices a simple enough syntax error that it can correct, it still generates the error message but it makes the correction internally and continues the compilation far enough to generate useful error messages about the rest of the code. But it doesn't output anything or change the code.
I remember having to test exactly how a bunch of different predicates actually worked, when the documentation thereof was a complete lie and the predicates just evaluated to false instead of creating an error when fed data they supposedly accepted (but actually couldn't).
"You are a bad programmer". How would it make you feel to hear that? Probably not open to further suggestions on how to improve.
While I agree that as programmers we should always strive to be getting better, these types of put-downs and belitting don't foster a culture of communication and trust.
Personally, I'm most receptive to hearing that I could improve when it's coming from someone I trust and respect. If a random person or poster on the Internet sent me this article and rubbed it in my face, I'd probably write them off as a major a-hole. And, I might miss out on a great opportunity to learn.
It reminds me of this post: http://news.ycombinator.com/item?id=2322696 - I read it and at the time thought it was great. But, sadly, not much has changed and this post is sad evidence of that fact.
I'm going to mark this thing up, add "haven't crossed any of these off in the past year", and postpone my judgment until next fall.
How should one do that if your "thinking is sets"?
signs that you are a good coder: you enjoy coding, you enjoy a good piece of code
signs that you are a bad coder: you don't enjoy coding, you can not appreciate beautiful code
if you enjoy coding it jut doesnt matter if anyone else thinks that your code sucks. you will get better. if you hate your job (programming) then you code stinks and will get worse.
in my careere i went from good to great to bad to i dont code anymore to good
The best possible signs either way will be in your career so far.
In any case it's pretty unforgiving.
I have had a colleague who fits the bill here, but actually I just let them get on with their work and I got on with mine. Sure, it was hard when he delivered something that was excruciatingly poorly conceived and executed and I had the task of taking it to the the next stage. But you know this isn't a life and death business, he was a really nice guy, and I wasn't going to rock the boat. The next project, I was working with someone else and everyone was happy.
Contrast that with making an issue of it, and you might find yourself being labelled as a trouble maker, even if you did have the best intentions for the development.
If you run the show however, don't stand for it, because it's your business, and it calls for the best at all times.
If you can't grasp that and decide to be an architect, I wouldn't want to drive on your bridge, work in your building, or live in your home. Same for the options!
Order-of-execution is not perceived the same way as cause-and-effect, even though they're both the same thing. It's a damn weird thing that I've seen people do. A little bit like how artists can comprehend how the position of an arm has an effect on the way bones, fat and muscle are distributed over the rest of the body, but can't understand why they got smacked with an overdraft fee when their average daily balance would have covered it easily.
For example, I grokk pointers, but I use them so infrequently I make foolish errors and have to stop and block everything out.
I have worked with people who do some or most of these, and let me tell you, the experience is not pleasant -- frequently turning into "Oh you changed that code, I can't maintain it anymore, object are too tricky" (when refactoring bulldozer functions and dicts of lists of dicts of tuples (some of which contained dicts) into a few classes in python) or "My code was working, why would you change that? I can't be responsible for looking at it anymore!" (When the spec changed and we needed to check for extra error conditions.)
Basically what I'm suggesting here, is bad programmer is less a function of skill at any particular moment, but of attitude and approach. Skills that don't change, continued lack of understanding, and laziness, are all symptoms of a bad programmer, who won't improve. I'd rather work with a neophyte who wants to improve over a veteran who is static any day.
So true.
That was common practice all over the Web for over a decade, it only stopped recently (on most sites). [Submit] [Reset] Argh!
I remember taking a C class in my undergrad, nailing the code to perfection, and getting an F because I had written the code in under different architecture and compiled with a different compiler (not specified in the prompt by any means). It ran well on my computer (and I proved it), but since it wouldn't run on my professors computer or TAs computer, I still received an F.
So yes, I still maintain strong malice towards C :-)
"(Functional) Manually caching the results of a deterministic function on platforms that do it automatically (such as SQL and Haskell)"
Isn't that what memcached is doing?
If you do have to complain about some piece of code then do so in concrete terms:
- Presense of bugs
- Lack of error handling
- Preformance issues (real ones, that cause real problems)
- Security issues
- Poor robustness
- Redundancy
Disclaimer: I started as a VB guy myself. Now I fall in the C# and Python camps.
- bad factoring
- overly complex or overly simplistic object model
- not extensible (although this itself is not strictly bad, as spec changes are pretty hard to predict, but sometimes it is requires more effort to make something not extensible than it is to make it extensible these cases are a problem unless there is a good reason for it).
- abstractions that introduce more effort (factory factories...)
How about writing lots of xxxxController classes that manipulate objects that have little methods of their own.
Bad programmers I have known generally:
- Are oblivious and clueless. They just lack cleverness.
- They lack problem solving abilities and willingness to solve problems.
- They are usually slow witted.
- They are very conventional-minded - external approval means a lot to them.
- They are willing and ready to work too hard at programming for a result.
- They lack abstract reasoning skills.
And most bad programmers don't like Star Trek or science fiction, but I can't figure out why other than simple correlation with the mindset of a programmer.
The first set of six "real" causes pretty much encapsulate 99% of the mediocrity I've witnessed in industry in this field. Bad programmers usually have two or more of these problems. Even one of them is a serious problem if you are looking for a great developer.
All other badness, such as "meal ticket" thinking, usually radiates outward from these things.
I say this because if you lack the quickness and the desire to seek simple and elegant solutions, the work becomes like drudgery and your work reflects the other deficiencies that the article described.
A specific example: if you care too much what non programmers think (including your managers) and if you are a bit of a toady, you will not take the time to learn what is going on in-depth, and you will look for quick solutions. So it's important to strategically ignore your bosses from time to time and if you are trying to be politically popular, software development isn't a good place for this.
Another example: if you "want" to work very, very hard, you will not seek ways to simplify the code. You will instead cope with growing complexity and spaghetti.
I question the article writer's programmer instincts because he did not figure out a much more efficient and concise way of expressing the same things. Above all else, a real programmer figures out how to say it just once - not repeatedly cast in different ways.
The other day I was at a hack night and some guys were working on something written in Node. They were having all kinds of problems with an object, so they serialized it to JSON and loaded it back, and somehow it magically started working.
- Your blog post only consisting of lists
- Using only -ing verb forms in your lists
- Not having an introduction in your article
- Not having a conclusion either
- Having only short 2-line paragraphs
- Lack of any style
https://encrypted.google.com/search?q=%22deficiency+a+progra...
Adding columns to tables for tangential data (eg: putting a "# cars owned" column on your address-book table)
I thought this is actually good for performance in different cases? Why is this considered mediocre?
Whereas a good programmer has the reaction, "uh-oh. I see how I can solve this..." And knows that this is just half the battle, and what he's getting himself into.
- Leader of a high school clique - Movie reviewer who concentrates on who's "in" - Coiner of demeaning nicknames
I wouldn't want to work with this person.
But his alternative career section is humorous.