{"id":83,"date":"2024-03-05T18:54:25","date_gmt":"2024-03-05T18:54:25","guid":{"rendered":"https:\/\/permutationcity.co.uk\/bp\/?p=83"},"modified":"2024-07-27T08:53:14","modified_gmt":"2024-07-27T08:53:14","slug":"the-elements-of-programming-style","status":"publish","type":"post","link":"https:\/\/permutationcity.co.uk\/bp\/2024\/03\/05\/the-elements-of-programming-style\/","title":{"rendered":"Historic programming style"},"content":{"rendered":"\n<p>While researching one of my recent post I came across a reference to\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/The_Elements_of_Programming_Style\">The Elements of Programming Style<\/a>.\nIt&#8217;s a study of programming style and it was first published 50 year ago.\nMy dad recognised the book and he remembers when you had to make programs using punched cards!<\/p>\n\n\n\n<p>Despite it&#8217;s age a lot of it&#8217;s recommendations still seemed to have merit today.\nI managed to get hold of a copy and decided to read through to get the context for these rules.<\/p>\n\n\n\n<p>Full disclosure, I did a lot of skimming. It&#8217;s examples are in <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fortran\">Fortran<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/PL\/I\">PL\/1<\/a> and&#8230; it turns out that I don&#8217;t like these languages. Fortran doesn&#8217;t have <a href=\"https:\/\/en.wikipedia.org\/wiki\/Structured_programming\">structured programming<\/a> and all it&#8217;s flow control is done using <code>goto<\/code>. It doesn&#8217;t even have normal comparison operators and uses <code>.gt.<\/code> rather than <code>&lt;<\/code>. We have progressed since then.<\/p>\n\n\n\n<p>Fortunately it&#8217;s the lessons I want to look at and there is a\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/The_Elements_of_Programming_Style#Lessons\">summary<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"be-clear\">Be clear<\/h2>\n\n\n\n<p>1. Write clearly \u2013 don&#8217;t be too clever.<br>2. Say what you mean, simply and directly.<br>5. Write clearly \u2013 don&#8217;t sacrifice clarity for efficiency.<br>8. Parenthesize to avoid ambiguity.<br>9. Choose variable names that won&#8217;t be confused.<br>52. Use variable names that mean something.<br>53. Use statement labels that mean something.<br>54. Format a program to help the reader understand it.  <\/p>\n\n\n\n<p>All of these made sense then and they still make sense now.\nThe sample code didn&#8217;t follow <a href=\"https:\/\/permutationcity.co.uk\/bp\/2024\/02\/27\/good-names\/\">my naming guidelines<\/a>\nbut there may well have been identifier length limits at that point.<\/p>\n\n\n\n<p>6. Let the machine do the dirty work.  <\/p>\n\n\n\n<p>This sounds weird out of context.\nIn the book it&#8217;s encouraging you to let the compiler do conversion and setup work rather than doing it manually.\nWe can now expect our compilers to do far more during the build.<\/p>\n\n\n\n<p>11. If a logical expression is hard to understand, try transforming it.<br>51. Don&#8217;t comment bad code \u2013 rewrite it.  <\/p>\n\n\n\n<p>I think this is sensible advice to consider today.\nIf you are using expressions that seem fundamentally hard to understand, do something about it.\nYou could add a long comment trying to explain them but can you do something better?\nSplitting a single expression into multiple expressions assigned to temporary variables might help.\nMaybe you can look at the expression from a different angle that easier to understand.\nYou should make your code easy to understand to help the next person (who may be future you).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"function-usage\">Function usage<\/h2>\n\n\n\n<p>3. Use library functions whenever feasible.<br>7. Replace repetitive expressions by calls to common functions.<br>14. Modularize. Use procedures and functions.  <\/p>\n\n\n\n<p>This is mostly an assumption nowadays.\nWhen this book was published some people will have been adjusting to the idea of function calls.<\/p>\n\n\n\n<p>44. Don&#8217;t strain to re-use code; reorganize instead.  <\/p>\n\n\n\n<p>This is about functions that are trying to do too much.\nIf you refactor so each function concentrates on doing just one thing then each function can be more easily reused.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"variable-initialisation\">Variable initialisation<\/h2>\n\n\n\n<p>4. Avoid too many temporary variables.<br>27. Make sure all variables are initialized before use.  <\/p>\n\n\n\n<p>Now we can delay the creating a variable until just before it is needed and initialise it immediately.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"flow-control\">Flow control<\/h2>\n\n\n\n<p>10. Avoid unnecessary branches.<br>15. Avoid gotos completely if you can keep the program readable.<br>31. Take care to branch the right way on equality.<br>32. Be careful if a loop exits to the same place from the middle and the bottom.  <\/p>\n\n\n\n<p>These all seem to be associated with the lack of structure programming.\nI hope you&#8217;re not using <code>goto<\/code> in your code nowadays.<\/p>\n\n\n\n<p>18. Use recursive procedures for recursively-defined data structures.  <\/p>\n\n\n\n<p>Maybe this required emphasis because of Fortran&#8217;s limitation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"bugs-breed-bugs\">Bugs breed bugs<\/h2>\n\n\n\n<p>16. Don&#8217;t patch bad code \u2013 rewrite it.  <\/p>\n\n\n\n<p>This one is interesting.\nI&#8217;ve certainly come across bits of code that seemed cursed.\nThey regularly had bugs, got fixed and then had more bugs later on.\nThat could be code that wasn&#8217;t written well in the first place so it has many bugs.\nThat could be code isn&#8217;t a good fit for the problem so that bugs keep being made.\nGetting rid of everything and starting again might be better than patching something with problems.\nOn the other hand you might just end up with new flawed code.\nI&#8217;d say this is good advice to keep in mind but not necessarily to follow every time.<\/p>\n\n\n\n<p>28. Don&#8217;t stop at one bug.  <\/p>\n\n\n\n<p>Don&#8217;t just assume your code must be working now. Make sure it is.<\/p>\n\n\n\n<p>29. Use debugging compilers.  <\/p>\n\n\n\n<p>Being able to debug is good.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"testing\">Testing<\/h2>\n\n\n\n<p>17. Write and test a big program in small pieces.  <\/p>\n\n\n\n<p>I think most people are working on larger programs nowadays.\nWe wouldn&#8217;t try and write the everything and leave all the testing until the end.\nHowever we might still try and finish a task in one go and leave the testing until the end.\nWriting small pieces and testing as you go is often better.\nYou have a better idea of what each piece needs and you&#8217;re less likely to miss edge cases.\nIf you&#8217;re <a href=\"https:\/\/permutationcity.co.uk\/bp\/2024\/02\/22\/building-to-throw-away\/\">still prototyping<\/a>\nyou could be more relaxed about this as you will have another chance to revisit testing later.<\/p>\n\n\n\n<p>33. Make sure your code does &#8220;nothing&#8221; gracefully.<br>34. Test programs at their boundary values.  <\/p>\n\n\n\n<p>Remember to test code with the different values can accept, not just the ones you want to get.<\/p>\n\n\n\n<p>35. Check some answers by hand.  <\/p>\n\n\n\n<p>I don&#8217;t think will always be possible.\nMaybe most programs were just much simpler back then.\nIt is good to check some answers using another method.\nThat might be by hand or it might be using a different, perhaps slower algorithm.\nI sometimes write my initial code with the slow but obviously correct algorithm.\nThat algorithm then becomes the basis for my testing code when the main algorithm is upgraded to something faster\nbut less certain.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"errors\">Errors<\/h2>\n\n\n\n<p>30. Watch out for off-by-one errors.  <\/p>\n\n\n\n<p>As true now as it was then.\nFor-loops were a common source of these.\nNow we can often re-write these to iterate directly over a collection which\navoids any comparison that could go wrong.\nWriting code that just can&#8217;t have that bug is the safer option.<\/p>\n\n\n\n<p>36. 10.0 times 0.1 is hardly ever 1.0.<br>37. 7\/8 is zero while 7.0\/8.0 is not zero.<br>38. Don&#8217;t compare floating point numbers solely for equality.  <\/p>\n\n\n\n<p>I don&#8217;t come across people making these mistakes too often.\nIt&#8217;s certainly something I keep in mind for floating point numbers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"appropriate-optimisation\">Appropriate optimisation<\/h2>\n\n\n\n<p>39. Make it right before you make it faster.<br>40. Make it fail-safe before you make it faster.<br>41. Make it clear before you make it faster.<br>42. Don&#8217;t sacrifice clarity for small gains in efficiency.  <\/p>\n\n\n\n<p>It is interesting to see how much comes before optimisation.\nThink about how much slower machines were back then.\nEven with that he was recommending that optimisation comes last.<\/p>\n\n\n\n<p>43. Let your compiler do the simple optimizations.<br>45. Make sure special cases are truly special.<br>46. Keep it simple to make it faster.<br>47. Don&#8217;t diddle code to make it faster \u2013 find a better algorithm.  <\/p>\n\n\n\n<p>We often don&#8217;t think about how much our compilers do for us today.\nWith a normal compiler your code is regularly transformed into something much more efficient.\nFunctions are inlined, expressions are pre-calculated, it happens every time we hit build.<\/p>\n\n\n\n<p>You can spend ages worrying over fine details but the overall algorithm often has the biggest effect.\nIf you have the right algorithm your code can be many orders of magnitude faster.\nFirst make sure you&#8217;re getting the right answers then make sure you have the best algorithm.<\/p>\n\n\n\n<p>48. Instrument your programs. Measure before making efficiency changes.  <\/p>\n\n\n\n<p>I&#8217;ve <a href=\"https:\/\/permutationcity.co.uk\/bp\/2024\/01\/08\/400000000-times-faster\/\">posted about optimisation before<\/a> and how important it is to pick your targets. You may think you know what&#8217;s slowing down your code but it&#8217;s much better to know. Don&#8217;t, say, spend time optimising a calculation if the real problem is doing the same calculation many times.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Think about the data<\/h2>\n\n\n\n<p>12. Choose a data representation that makes the program simple.<br>21. Terminate input by end-of-file marker, not by count.  <\/p>\n\n\n\n<p>We have a lot of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Data_exchange\">file standards<\/a> that can make our lives easier today. There is normal a library that can fairly easily transform your local data for file storage or network traffic.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"comments\">Comments<\/h2>\n\n\n\n<p>13. Write first in easy-to-understand pseudo language; then translate into whatever language you have to use.  <\/p>\n\n\n\n<p>I don&#8217;t think is so relevant nowadays.\nOur languages and libraries are able to more things directly now.\nI do still sometimes rough out the behaviour of a function with comments before writing the real code.<\/p>\n\n\n\n<p>49. Make sure comments and code agree.  <\/p>\n\n\n\n<p>While this is obvious it is something to watch for.\nI&#8217;ve discussed <a href=\"https:\/\/permutationcity.co.uk\/bp\/2024\/01\/31\/we-all-make-mistakes\/\">code reviews<\/a>\nbefore as a way of catching mistakes.\nIf someone has changed the code make sure the comment has been updated if necessary.<\/p>\n\n\n\n<p>50. Don&#8217;t just echo the code with comments \u2013 make every comment count.<br>56. Don&#8217;t over-comment.  <\/p>\n\n\n\n<p>These two lessons seem to belong together given the details in the book. If your comments are just a slightly different wording of the code then you aren&#8217;t adding value. I <em>do<\/em> like to see comments that tell me the &#8220;why&#8221; behind the code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"input-and-output\">Input and output<\/h2>\n\n\n\n<p>19. Test input for plausibility and validity.<br>20. Make sure input doesn&#8217;t violate the limits of the program.<br>22. Identify bad input; recover if possible.<br>23. Make input easy to prepare and output self-explanatory.<br>24. Use uniform input formats.<br>25. Make input easy to proofread.<br>26. Use self-identifying input. Allow defaults. Echo both on output.<br>55. Document your data layouts.  <\/p>\n\n\n\n<p>I think this will have been written exclusively with the console and batch processing in mind.\nIt&#8217;s always worth considering that there may be problems with incoming data.\nJust because the data is meant to look a certain way doesn&#8217;t mean it will.<\/p>\n\n\n\n<p>I&#8217;d highlight a problem with recovery mechanisms.\nThey can end up hiding bugs elsewhere in the system.\nIf something has gone wrong this should be obvious to the developers.\nYou want to know if there&#8217;s a problem so you can fix it.\nIf the user thinks they&#8217;re using a particular setting it shouldn&#8217;t just silently switch to a default.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"50-year-old-lessons\">On balance<\/h2>\n\n\n\n<p>I don&#8217;t think that was bad for a 50 year old book.\nWhile I don&#8217;t want to read any more Fortran the lessons are often still relevant.\nGiven how much less powerful their computers they still thought that getting it right and being clear\nwas better than worrying about every clock cycle.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While researching one of my recent post I came across a reference to The Elements of Programming Style. It&#8217;s a study of programming style and it was first published 50 year ago. My dad recognised the book and he remembers when you had to make programs using punched cards! Despite it&#8217;s age a lot of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[34],"tags":[20,7,8,13],"class_list":["post-83","post","type-post","status-publish","format-standard","hentry","category-review","tag-books","tag-performance","tag-standards","tag-testing"],"_links":{"self":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/83","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/comments?post=83"}],"version-history":[{"count":3,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/83\/revisions"}],"predecessor-version":[{"id":199,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/83\/revisions\/199"}],"wp:attachment":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/media?parent=83"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/categories?post=83"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/tags?post=83"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}