In a recent thread I had initially given a rather terse reply, which I
subsequently elaborated on when the OP asked how it worked. Later in the thread
the OP asked how to change the code a little and I bullied him into figuring out
the answer for himself, with a little hint along the way. The OP duly figured
out how to solve the problem, but asked "is it correct way to do it ?". My
answer of 'Indeed. Although the real answer is: "Did it work?".' didn't seem to
satisfy the OP who again asked "wat's the right way or answer to do it,
please?".
My reply to "What is the right answer" led to the following list:
- Does it work correctly?
- Do you understand it?
- Would anyone else understand it?
- Will you understand it in a month's time?
- Does it strike a good balance between terseness and verbosity?
- Could you make changes to it without it being likely to break in unforeseen ways?
- Is it fast enough?
which perhaps needs a little elaboration:
Does it work correctly?
Seems pretty obvious doesn't it? However there is a lot under the
surface here. A recent question asked how to efficiently replace the
first and last n with ^ in runs of n in a large file. Sounds pretty straight
forward. But there are a few clarification questions that needed to be
asked (and they were):
- What happens to n or nn?
- Can there be new lines in the n runs?
- How large is "a large file"
The specific answers don't matter here, but the nature of the
questions is important. To know if a solution works correctly you have
to know what it is that you are trying to solve. You have to carefully
consider the edge cases. Sometimes figuring that out is much more than
half the battle.
Often this is the driver for generating and maintaining a test suite.
The major focus of the test suite is on the edge cases.
A correct solution has to work correctly for all the cases it may
have to cope with.
Do you understand it?
If you don't understand the code how can you possibly be sure it does
the right thing in all the situations you expect to use it? If you don't
understand it today the chance of you being able to fix it in the future
is almost 0. Even the chance that it works correctly is pretty low if
you don't know how it works - how can you be sure about the edge cases?
The right answer has to be something you understand.
Would anyone else understand it?
If you are the only person who will ever have to work on the code
then you may think that someone else being able to understand the code
is unimportant. However in most cases good code remains in use for a
long time and there is a pretty good chance that maintenance in some
form by someone else, or by a future self, will need to be performed on
it.
A correct solution should be understandable by someone who hasn't
seen the code before and who has only a modest understanding of the
code's context.
Will you understand it in a month's time?
There is a stranger who is rather likely to take a look at the code
some time in the future who will probably have no idea how it works
before looking - a future you!
Although code doesn't really decay over time, your understanding of
it will.
A correct solution provides its own refresher course.
Does it strike a good balance between terseness and verbosity?
There is a real tension between golfed code at one extreme and "can't
see the code for the comments" at the other extreme. A similar tension
exists between one letter identifiers and identifiers that try to tell a
story.
The balance point tends to shift as code changes from development
mode to maintenance mode. In the end it tends to be a matter of what the
developer is comfortable with, although that comfort level will very
likely change over time
A correct solution is terse enough that understanding is not impeded
by clutter and verbose enough to be understood.
Could you make changes to it without it being likely to break in
unforeseen ways?
This implies elements of robustness and transparency. Robust so that
maintenance changes are unlikely to break the code, or at least will
result in early and noisy breakage rather than late and subtle breakage.
It is generally much better that the code die in a noisy fashion early
on than quietly produce wrong answers or set traps in data structures
that are sprung later on remote realms of the code.
Transparency means that the code usage should be clear and that the
effect of changing the code or the context of the code should be readily
apparent.
A correct solution is easy to maintain and resistant to the
introduction of nasty surprises.
Is it fast enough?
For most code speed just doesn't matter. The amount of work done by
typical code is small in the context of modern computers and the tasks
they are most often called on to perform.
For some code however speed is of overwhelming importance. Either
because lots of things have to be done with small latency (web servers
for example), or because there is simply a large amount of work to be
done (gene data manipulation for example). In most cases finding the
right algorithm is the key to the solution.
A correct solution uses an appropriate algorithm.
Update: added links to other referenced nodes
Perl is environmentally friendly - it saves trees
Re: Is it correct?
by tantarbobus (Hermit) on Jul 14, 2008 at 13:41 UTC
|
Those are great questions... For an expert to ask (him|her)self. But what do they mean for someone that is just learning the language?
Here is my attempt to answer you questions from the POV of a novice:
1. Does it work correctly?
Um, I guess so. It seems to work? I cannot think of anything wrong with it; can you?
2. Do you understand it?
Somewhat. I think I understand it, maybe... Is there something I am missing?
3. Would anyone else understand it?
FIIK, a) I am not someone else, so how should I know what someone else thinks. b) I just learned this myself, and this is the way I learned it.
4. Will you understand it in a month's time?
I hope so.
5. Does it strike a good balance between terseness and verbosity?
FIIK! This is like asking a 5 year old whether War and Peace strikes a good balance between terseness and verbosity. One must have sufficient mastery over the material to be able to judge.
6. Could you make changes to it without it being likely to break in unforeseen ways?
Good Question, how would I go about finding this out? What are the unforeseen ways?
7. Is it fast enough?
Is there a faster way to do it?
| [reply] |
|
I think the novice has to own the problem domain. He knows what problem he's trying to solve and the context in which it will be run. Given this, I'd respond as follows (if it were me who asked the original questions):
1. Does it work correctly?
Um, I guess so. It seems to work? I cannot think of anything wrong with it; can you?
I really think, here that you have to understand what you want the program to do. You need to understand the straight-down-the-center as well as the corner cases and, if you don't grok the code, at least have some tests you can run.
2. Do you understand it?
Somewhat. I think I understand it, maybe... Is there something I am missing?
This is, of course, subjective. If you don't get the basic principles, RTFM a bit and get some understanding -- you may have already done this, I don't know. Trace through the code by hand with some data and see if you think it does what you think it's supposed to. Add some 'print' statements to verify.
You may, depending on the original advice, come to a better understanding of side-effects and such at a later time. That's okay.
3. Would anyone else understand it?
FIIK, a) I am not someone else, so how should I know what someone else thinks. b) I just learned this myself, and this is the way I learned it.
4. Will you understand it in a month's time?
I hope so.
To address 3. and 4., together, I think these are really meant to ask: is the code readable? Are the variable names clear? Is the style easily read? Did you comment it well? I find that, when I'm learning something, I comment the holy snot out of it, explaining every detail as I think I understand it. If I learned something when I wrote the code, I make darned sure that someone else with the same level of experience I had when I started would understand the code.
5. Does it strike a good balance between terseness and verbosity?
FIIK!
This is like asking a 5 year old whether War and Peace strikes a good balance between terseness and verbosity. One must have sufficient mastery over the material to be able to judge.
No, I think this is more like asking a 12 year old whether the New York Times strikes a good balance between terseness and verbosity. It's a stretch but it's a good thing to consider. The answer may stray away for what an experienced programmer would say but that's okay.
6. Could you make changes to it without it being likely to break in unforeseen ways?
Good Question, how would I go about finding this out? What are the unforeseen ways?
Again with the RTFMing and the tracing of the code. This requires deeper understanding than do the other points. Give it a go, though. Look at side-effects. Try funkified data as an input. Always check the corner cases.
To figure out what the corner cases are, look at the expectation of the data. If the code is expecting numbers, try characters. How does the code respond to a gigantic amount of input or none at all?
7. Is it fast enough?
Is there a faster way to do it?
The answer is 'probably' but that's not the question you should be asking. Does the program run fast enough to fulfill your needs. Writing something faster than that often requires sacrificing readability and that would be a bad thing.
Update: fixed a typo
| [reply] |
|
This was in the context of a novice asking an expert, 'is this correct'. The point I was trying to make is that the novice may not be able to answer the questions with certainty but an expert can.
Have you ever met a student who walked out of an exam thinking s/he made an 'A' on an exam, only to find out that the actual grade was an 'F'? Sometimes everything can look correct and act correct (to the best of the knowledge of the novice), but is obviously incorrect when viewed at through the eyes of an expert.
And, at least from my point of view, for the novice it is much more helpful to know hat something is done correctly rather than spending many hours trying to make sure it is correct -- and still not being convinced. Self-study is infinitely harder when you do not have the answers to the problems to verify your understanding.
| [reply] |
|
|
|
Novice has to own the problem domain. Thank you, this is the smartest thing I heard on this site, for what, last several months, on this site.
| [reply] |
|
wade has given an excellent reply already, but there are a couple of things I'd like to elaborate on.
2. Do you understand it? is in large part addressing cargo cult programming. Copying code is often a good way to get a job done and to learn along the way. It can also be a excellent way to pick up bad habits, lay nasty traps and generate incomprehensible code.
5. Does it strike a good balance between terseness and verbosity? I would expect to change over time in two ways:
As a project evolves cruft can generally be removed through refactoring. That most often reduces verbosity.
As programmers become more experienced they tend to learn programming styles that reduce verbosity.
The key element in this question however is the balance. Both extremes are bad. The balance may shift over time, but the question should prompt you to find a balance you are comfortable with.
Perl is environmentally friendly - it saves trees
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: Is it correct?
by LesleyB (Friar) on Jul 14, 2008 at 17:00 UTC
|
I have to agree with tantarbobus on this. Some of the points raised are very difficult for a novice to evaluate.
I think that 'does the code not do something it isn't meant to do' question is important as part of the 'does it work' question. (This is effectively asking the question, is the code within spec.) At a very simple level, most of us novices are monumentally relieved when we get a regexp to match at all. At last it works! However, how many perl novices then check whether that regexp matches what it oughtn't to? I guess this is where testing comes in and being able to effecitively test something is part general programming experience and part specific language experience. I haven't yet used the Test module yet because I feel I haven't written anything needing it yet.
I also feel there is definitely a particular mindset to be adopted to be able to write terse but informative perl code . My code is verbose and I would love to be able to improve its terseness but I don't yet know how.
Giving a novice along a few breadcrumbs along the trail is no bad thing. It is up to that individual to commit the time to learning but having guides along the way does help tremendously.
| [reply] |
|
My first reaction was similar to yours and tantarbobus's. I wasn't thinking along the lines of "a novice would have trouble grading themselves on this scale" but rather "a novice would have no motivation to do so."
It's not that I don't think the list is good - in fact, I think it is great - It's that one has to be burned by many of these things before they care about them.
Does it work? I'm trying to think honestly how vigorously I tested for and checked edge/corner cases for correctness before my programs blew up in my face a few times. The answer: Not very much.
Will I be able to read it later? Again, not something I cared about before I had to maintain my old code months and months later.
Maybe I am on the stubborn side of the scale, but I think most novices, especially in programming, are more task driven than quality driven. Maybe the shift towards thinking about these things, writing quality code today to save yourself tomorrow, is one of the big gulfs between novice and expert :).
| [reply] |
Re: Is it correct?
by moritz (Cardinal) on Jul 14, 2008 at 16:52 UTC
|
And if you contribute to a module:
- 8. Is it tested?
- 9. Is it documented?
| [reply] |
Re: Is it correct?
by whakka (Hermit) on Jul 14, 2008 at 20:30 UTC
|
If you can answer all of these questions with a definitive "yes" then you are either a grand-poobah Perl master or you are a liar of the double-nth degree (that assuming the coding problem isn't a trivial one).
I think all of these questions have an answer on a sliding scale. However, as a novice I have to say that it's not all that important if all of these questions can be answered toward the "yes" direction right away. Except perhaps 3) and 4), which I regard in the same way - you should always write code as if you will forget everything you've done in a month. Because I usually do - darn that lack of experience! But I think verbosity should be encouraged in the beginning, and only after you're comfortable doing something should you try to strike the balance you mention. And not completely understanding code or knowing if it will work in all situations can lead to interesting lessons (unless you have to care about security of course) and revelations later on. I think most would agree, especially if they are doing funny things with dependencies that they don't know the intricate details of.
The most important thing though from your post is that you should always be asking yourself these questions, usually implicitly, for every piece of code you write. That's the advice I would give to fellow novices.
| [reply] |
Re: Is it correct?
by blazar (Canon) on Jul 20, 2008 at 09:26 UTC
|
I personally believe, dear GrandFather, that for once you got it wrong: wrt the title, that is. We bash newbies all the time for chosing uninformative ones. Now, I understand perfectly well that's not the same case, yours being a witty attempt at being... witty: and do not misunderstand me - you succeeded! Nevertheless, it turns out to be just as uninformative (and search unfriendly) as those other ones. Thus I suggest you rename -at the expense of some verbosity- it to something like "How to answer to 'is it correct?' kinda questions?"
| [reply] [d/l] |
Re: Is it correct?
by Argel (Prior) on Jul 15, 2008 at 19:27 UTC
|
What about considering best practices and privacy and security concerns, etc.? I think your list falls a bit short. | [reply] |
|
Not such list would ever be "complete". It's largely a matter of finding a balance between terseness and verbosity influenced by considering what seem to be key elements. ;)
Please, add your own item to the list.
Perl is environmentally friendly - it saves trees
| [reply] |
|
Hmm. Well, as a start I will throw out the SAGE Code of Ethics. It's for SysAdmins, but it's general enough that others on here can make use if it and I think it helps stess the importance of considering security and privacy concerns.
| [reply] |
Assume it isn't correct. Is it fixable?
by wol (Hermit) on Jul 31, 2008 at 13:32 UTC
|
My general approach in any software context is to give maintainability at least as much importance as functional accuracy. In some cases, I'd go so far as to say that maintainability is more important than correctness!
It's easier to fix a maintainable but bugged program than it is to do anything with an accidently obfuscated program that happens to to work for last week's requirements, but not this week's.
All common sense caveats apply.
| [reply] |
|
| [reply] |
|
I'd read the numbered points as an ordered list, implying that point one is the number one priority. Maybe I'm thinking too hard today, but read that way it's perfectly comprehensible, and ceratinly useful for reminding people that there's more to consider than whether anyone has complained about the results (yet). And I'd agree with each point in the list.
However, I thought I'd contribute the slightly contentious view that sometimes accuracy is not the number one priority. Of course, if everyone agrees with that, then it's not so contentious. Bah - don't tell me I'm back in the mainstream again.
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
|
|