|
"Is the code documenting itself good enough?"
You're joking, right?
I am the sole proprietor of a legacy system written in the 80s. Technically, I've retired, but I've given this one customer the option of lifting the production (note: production) system to today. It's a re-write (the core functions) but most of the code goes away due to a functional database, report writer and C++ or .net. The group involved is part of a huge international corporation, so crickets.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
"If that's all there is, then let's keep dancing"
Religious freedom is the freedom to say that two plus two make five.
|
|
|
|
|
Most developer document the wrong things. Far too often, they repeat what the code line says, whether like "Here we set i to the value 5" or repeat the parameters of the method heading, "explaining" e.g. "numberOfApples: The number of apples".
Or, when asked for more high level, code independent documentation, they present a block chart with Application, Database and Network modules.
What other developers need lies in between: A documentation of the purpose of each code module, of its interaction with other modules. Replace 'module' with 'class' as appropriate. The data structures - how they are interlocked, what they represent as a whole - that usually means, across several object classes.
To draw a line: I want off line - in the sense: off the code lines - documentation to go down to the deepest level where it is still independent of the programming language. You should be able to build those modules, those data structures, in Python, in C++, even in Visual Basic. You document the interfaces between modules, not only the syntax (name, parameters) but the dynamics as well. That will help the next code maintainer on the right track! And, these interactions are far more stable than the individual code lines; you can make a lot of changes without invalidating the documentation. Every now and then it may need to be extended with new interactions or parameter options, yet all the old stuff remains valid.
When you get down to code, you may of course add code comments - but without repeating the off code line documentation; there is no need to. Obviously, you should avoid 'Here we set i to 5' style comments, and you should use descriptive type and variable names. When you delete code lines, you delete the accompanying comments. When you change code lines, you change the accompanying comments. End-of-line comments (lined up at col. 70 or 80 not to blur the code) is a lot better for keeping them up to date than pushing them to the top of the method.
But these code comments are far less essential. You read them after you have studied all the off line documentation, and know the interactions, the data structures, the interfaces. What is left is to understand how these interfaces are realized, within a single module/class. That is usually a far simpler task than grokking the structure of the entire program system as a whole. I do like to have (i.e. both make and read) code comments, but if I could have a choice between code comments and a system documentation from immediately above the programming language dependent level and upwards, I'd gladly take the second. I very rarely have that option.
Bonus rant: I wish that code designers to a much larger degree would forget which programming language they are designing code for. Far too often, I see code that serves more as a schoolbook example of how to use that new feature in the latest language revision, than to illustrate an issue in the problem to be solved. Not only should documentation be language independent, so should a lot more program code. We are here to solve problems, not to boast our intimate knowledge of the latest language definition.
Religious freedom is the freedom to say that two plus two make five.
|
|
|
|
|
that's pretty religious
Seems to me a bit of a pet peeve of yours. Mine as well.
I'll swing this in a different direction. There are a few people I've worked with that I term "whiz kids." Their minds work so fast, 5x faster than mine, that everything is intuitively obvious. Not one damn line of comments. No doc to save anyone's lives, nothing. I simply gave up. I completely concur about not documenting loops and i++, but module level comments are necessary. And ffs, tie the code comments back to external documentation.
Now, 40 years later, no one gives an elephant. I've worked at (counting....) 9 companies and myself, and there is only one person I can count on to write proper documentation. It's simply pathetic.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
Contrary to my last(vastly misunderstood post), this is not <b>apparent</b>, it simply is (for real).
I am an OF and have noticed how "newer generations" choose NOT to use (simple) old, proven methods , stuff.
My manager did not use AI or RTFM - his "comment or else " was based on
"what will happen if you get run over by a bus and your code is not documented / commented?"
For those hard of hearing - undocumented / uncommented code was against company interest, period.
I am not a wiz kid, but if the code task is to test HARDWARE , CLOSE TO REAL TIME, and if the code is not documented , commented AND is missing ANY time reference - it will not "just " APPARENTLY fail - it will fail for sure.
IMHO
self documented code is oxymoron
|
|
|
|
|
What is an OF, and more to the point, what other post? Inquiring minds want to know (I looked at the thread, and this is your first post).
But, I completely agree with your comment.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
OF = Old Fogey (or some ruder word that starts with F.)
|
|
|
|
|
oops <blush>
yeah I have that shirt.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
All documentation is out of date as soon as it's written. Code is never out of date.
|
|
|
|
|
Is it really just the code, or a whole system? If a whole system, check and/or create a high-level overview, even if it "should be obvious" and make sure you have the documentation necessary to make a change, rebuild, test, distribute and install. (I.e. you have to go through that process to be sure it works).
As for code, depends partly on how much expertise in the coding language(s) you think will be available if a change is necessary, particularly if people have used unusual language features or coded in an unusual way compared to "normal industry practice" - perhaps make a few general remarks noting such stuff.
|
|
|
|
|
THIS!!!
Code does not exist on it's own. It was written to solve a problem. If you don't tie the code back to the problem, you lose context. Sometimes this is called tribal knowledge. I'm watching an organization bleed to death, but the multinational corp above it is oblivious. As my boss told me, it's not up to you to help a multi-billion dollar company fix their stupidity. 2 weeks later, I jumped out of the plane (with a parachute) and retired. It's been two months now, and I have not received a single email.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
I just got a copy of some Fortran code I wrote in 1982. Thankfully, I put in a lot of comments. Sadly, I was missing one crucial comment, but I figured it out in about 10 hours.
CQ de W5ALT
Walt Fair, Jr.PhD P. E.
Comport Computing
Specializing in Technical Engineering Software
|
|
|
|
|
Old guru Tony Hoare remarked after reviewing the various proposals for Fortran-77 extensions (some of them went quite far, to phrase it in a polite manner): "I don't know what programming languages will look like in the year 2000, but I know that they will be named 'Fortran'."
When I first saw code written to the Fortran-2003 standard, my immediate reaction was: Hoare was right!
So my curious question is: How did your 1982 vintage Fortran code fare with a 2024 vintage Fortran compiler?
(Fortran 77 was so much delayed that the '77' is a misnomer, so I wouldn't be surprised if 1982 vintage code is not even by the F77 standard.)
Religious freedom is the freedom to say that two plus two make five.
|
|
|
|
|
trønderen wrote:
o my curious question is: How did your 1982 vintage Fortran code fare with a 2024 vintage Fortran compiler?
I was translating the code to C#, so there was no problem, except I wonder if I had a brain 46 years ago.
CQ de W5ALT
Walt Fair, Jr.PhD P. E.
Comport Computing
Specializing in Technical Engineering Software
|
|
|
|
|
Lord willing, I will be in this boat late this year or maybe next year. The FORTRAN production system I support breaks down into basic components:
1) UI. It's designed to allow order entry people to do it FAST. The new developers want to make the UI pretty, and they don't bother to talk to their customers. The customer is NOT The contract manager, it's the people in the factory.
2) Reports - enough said.
3) Number crunching to produce a manufacturing file. This is the grail.
I cut my teeth on FORTRAN, but C and C++ allow string processing to a useful form. Trying to do it in FORTRAN brings tears to my eyes and my hemeroids swell.
Charlie Gilley
“They who can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety.” BF, 1759
Has never been more appropriate.
|
|
|
|
|
charlieg wrote:
cut my teeth on FORTRAN, but C and C++ allow string processing to a useful form. Trying to do it in FORTRAN brings tears to my eyes and my hemeroids swell.
been there, done that... It still hurts what brain I have left!
CQ de W5ALT
Walt Fair, Jr.PhD P. E.
Comport Computing
Specializing in Technical Engineering Software
-- modified 3-Aug-24 18:55pm.
|
|
|
|
|
Greetings Kind Regards
It is often necessary in my C++ test code to update a lengthy list of switch case: statements utilizing numeric constants which should be in numeric order so the random number case argument generator can know the limits. Each calls a method to a class being tested. I find myself frequently rearranging the order of the class method declarations. Once the called methods in the switch statement are reorganized to match it is then necessary to renumber in sequence the lengthy list of case statements. A tedious affair. After numerous such I finally spent an hour or two figuring out how awk can do it for me. It worked. Only one line of awk code. Then it occurred to me to seek AI assistance. I posed the awk problem to Perplexity. Bingo Presto Voila. It worked also. Perplexity is my new friend.
- Cheerios
"I want to sing, I want to cry, I want to laugh. Everything together. And jump and dance. The day has arrived - yippee!" - Desmond Tutu
|
|
|
|
|
I'm perplexed.
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
I swear English is my native language though I sometimes seem to speak it w/ a slight Polish accent. Maybe that's the cause of the confusion.
|
|
|
|
|
Are you perplexed because he could’ve used Polymorphism via Interfaces and solved this problem?
interface IDataSaver(){
int Save();
}
class InternetSaver : IDataSaver{
String dataToSave;
Int Save(){
}
}
class FileSaver : IDataSaver{
String dataToSave;
Int Save(){
}
}
class DBSaver : IDataSaver{
String dataToSave;
Int Save(){
}
}
List<IDataSaver> allDataSavers = new List<IDataSaver>();
allDataSavers.Add(new InternetSaver());
allDataSavers.Add(new FileSaver());
allDataSavers.Add(new DBSaver());
foreach (IDataSaver ds in allDataSavers){
ds.Save(); }
|
|
|
|
|
Imagine the class diagram.
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
CPallini wrote: Imagine the class diagram
You mean in the original situation where he is creating separate classes for each of his switch statements, right?
Yeah, it would get crazy big!
|
|
|
|
|
Exactly!
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
Perhaps I should provide the code. I prefer them in the same order as declared in the class not shown as it is a class cTest global variable.
void Random__METHOD()
{
static const int last_case = 96;
auto _case_ = m_cSCALAR_RNG.operator() < int > (0, last_case);
switch(_case_)
{
default: throw einternal_error_eXception;
case 0: Random__default_constructor(); break;
case 1: Random__primordialTimePoint(); break;
case 2: Random__DIAGNOSTIC_SNAPSHOT_HASH(); break;
case 3: Random__recordTermination_time_point_node_spec();
case 4: Random__open_with_arguments(); break;
case 5: Random__open(); break;
case 6: Random__close(); break;
case 7: Random__is_open(); break;
case 8: Random__set_toNascentState(); break;
case 10: Random__swap(); break;
case 11: Random__startTransaction(); break;
case 12: Random__endTransaction(); break;
case 13: Random__cancelTransaction(); break;
case 14: Random__is_activeTransaction(); break;
case 15: Random__activeTransaction_ctransaction_datum(); break;
case 16: Random__is_saved(); break;
case 17: Random__save(); break;
case 18: Random__offset(); break;
case 19: Random__size(); break;
case 20: Random__eofOffset(); break;
case 21: Random__mirror(); break;
case 22: Random__archivesPaths(); break;
case 23: Random__archivesFilenames(); break;
case 24: Random__fullPath(); break;
case 25: Random__fileName(); break;
case 26: if(m_rfe) {} break;
case 27: if(!m_rfe) {} break;
case 28: m_rfe == m_rfe; break;
case 29: m_rfe != m_rfe; break;
case 30: Random__read(); break;
case 31: Random__output(); break;
case 32: Random__delete(); break;
case 33: Random__setOffset(); break;
case 34: Random__incOffset(); break;
case 35: Random__decOffset(); break;
case 36: Random__adjust_eofOffset(); break;
case 37: Random__set_eofOffset(); break;
case 38: Random__initializedIntervals(); break;
case 39: Random__uninitializedIntervals(); break;
case 40: Random__treeEmpty(); break;
case 41: Random__treeSize(); break;
case 42: Random__number_ofUndosAvailable(); break;
case 43: Random__undo(); break;
case 44: Random__redo(); break;
case 45: Random__number_ofRedoBranches(); break;
case 46: Random__undo_node_spec_time_point(); break;
case 47: Random__undo_node_spec_ctransaction_datum(); break;
case 48: Random__undo_node_spec_time_point_vector_cedit_datum(); break;
case 49: Random__redo_node_spec_time_point(); break;
case 50: Random__redo_node_spec_ctransaction_datum(); break;
case 51: Random__redo_node_spec_time_point_vector_cedit_datum(); break;
case 52: Random__redo_node_spec_ctransaction_datum_all(); break;
case 53: Random__current_root_node_spec_time_point(); break;
case 54: Random__current_root_node_spec_ctransaction_datum(); break;
case 55: Random__current_root_node_spec_time_point_vector_cedit_datum(); break;
case 56: Random__terminus_node_spec_time_point(); break;
case 57: Random__terminus_node_spec_ctransaction_datum(); break;
case 58: Random__terminus_node_spec_time_point_vector_cedit_datum(); break;
case 59: Random__current_node_spec_time_point(); break;
case 60: Random__currentSessionIdentifier(); break;
case 61: Random__LIST_per_predicate(); break;
case 62: Random__REMOVE_per_list(); break;
case 63: Random__REMOVE_undos(); break;
case 64: Random__REMOVE_undo_branches(); break;
case 65: Random__REMOVE_redos(); break;
case 66: Random__REMOVE_sub_tree(); break;
case 67: Random__REMOVE_per_list(); break;
case 68: Random__REMOVE_undos(); break;
case 69: Random__REMOVE_undo_branches(); break;
case 70: Random__REMOVE_redos(); break;
case 71: Random__REMOVE_sub_tree(); break;
case 72:Random__NAVIGATE_to_nil_root(); break;
case 73:Random__NAVIGATE_to_root(); break;
case 74:Random__NAVIGATE_to_root_branch(); break;
case 75:Random__NAVIGATE_branch(); break;
case 76:Random__NAVIGATE_forward_route(); break;
case 77:Random__NAVIGATE_backward_route(); break;
case 78:Random__NAVIGATE_to_node_spec(); break;
case 79:Random__NAVIGATE_to_node_spec_root(); break;
case 80:Random__NAVIGATE_to_node_spec_branch(); break;
case 81:Random__NAVIGATE_to_node_spec_forward_route_terminus(); break;
case 82:Random__NAVIGATE_to_node_spec_backward_route_terminus(); break;
case 83:Random__NAVIGATE_to_canonical_route_terminus(); break;
case 84:Random__STEP_to_nil_root(); break;
case 85:Random__STEP_to_root(); break;
case 86:Random__STEP_to_root(); break;
case 87:Random__STEP_branch(); break;
case 88:Random__STEP_forward_route(); break;
case 89:Random__STEP_backward_route(); break;
case 90:Random__STEP_to_node_spec(); break;
case 91:Random__STEP_to_node_spec_root(); break;
case 92:Random__STEP_to_node_spec_branch(); break;
case 93:Random__STEP_to_node_spec_forward_route_terminus(); break;
case 94:Random__STEP_to_node_spec_backward_route_terminus(); break;
case 95:Random__STEP_to_canonical_route_terminus(); break;
case 96:Random__delete__count(); break;
}
}
|
|
|
|
|
Huh ?
You have performance issues on a switch that you need to re-order the case statements ?
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|