{"id":1016,"date":"2022-10-02T13:28:47","date_gmt":"2022-10-02T05:28:47","guid":{"rendered":"https:\/\/www.lcettsg.cn\/code\/?p=1016"},"modified":"2022-10-22T01:43:28","modified_gmt":"2022-10-21T17:43:28","slug":"avoid-spaghetti-code-with-scope-minimization","status":"publish","type":"post","link":"https:\/\/www.lcettsg.cn\/code\/?p=1016","title":{"rendered":"Avoid Spaghetti  Code With Scope Minimization"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\"><small><time datetime=\"2022-02-10T00:00:00+00:00\">Feb 10, 2<\/time><\/small><\/h1>\n\n\n\n<p>Let\u2019s see some recommendations on how to prevent the phenomenon of&nbsp;<em><strong><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-red-color\">spaghetti<\/mark><\/strong> code<\/em>&nbsp;just by minimizing the visibility of variables.<\/p>\n\n\n\n<p>Our aim will be reducing to the minimum possible the portion of code where our variables are visible over the source code, namely reducing the&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Variable_(computer_science)#Scope_and_extent\" target=\"_blank\" rel=\"noreferrer noopener\"><em>scope of variables<\/em><\/a>.<\/p>\n\n\n\n<p>Scope minimization is the process of structuring code in such a way that it\u2019s easy to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>declare variables that have minimal scope, and<\/li><li>assign variables with data that have minimal scope.<\/li><\/ul>\n\n\n\n<p>As a matter of fact, it\u2019s the code structure that defines the visibility of variables.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"background-notions\">Background Notions<\/h2>\n\n\n\n<p>A program is made of a combination of&nbsp;<em>statements<\/em>&nbsp;that are either&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Statement_(computer_science)#Simple_statements\" target=\"_blank\" rel=\"noreferrer noopener\"><em>simple<\/em><\/a>&nbsp;(e.g. assignments) or&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Statement_(computer_science)#Compound_statements\" target=\"_blank\" rel=\"noreferrer noopener\"><em>compound<\/em><\/a>&nbsp;(e.g. conditionals, loops).<\/p>\n\n\n\n<p>The latter kind of statements can be&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Nesting_(computing)\" target=\"_blank\" rel=\"noreferrer noopener\"><em>nested<\/em><\/a>, which means they can be made of&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Block_(programming)\" target=\"_blank\" rel=\"noreferrer noopener\"><em>code blocks<\/em><\/a>&nbsp;that can contain other statements.<\/p>\n\n\n\n<p>In particular, let\u2019s consider two blocks&nbsp;<em>A<\/em>&nbsp;and&nbsp;<em>B<\/em>:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>we say&nbsp;<em>A<\/em>&nbsp;is the&nbsp;<em>outer block<\/em>&nbsp;of&nbsp;<em>B<\/em>&nbsp;if&nbsp;<em>A<\/em>&nbsp;contains&nbsp;<em>B<\/em>, while<\/li><li>we say&nbsp;<em>B<\/em>&nbsp;is the&nbsp;<em>inner block<\/em>&nbsp;of&nbsp;<em>A<\/em>&nbsp;if&nbsp;<em>B<\/em>&nbsp;is contained by&nbsp;<em>A<\/em>.<\/li><\/ul>\n\n\n\n<p>The&nbsp;<em>indentation level<\/em>&nbsp;of a block is the number of its nesting levels, and corresponds to one level higher than its outer block.<\/p>\n\n\n\n<p>Let\u2019s define the&nbsp;<em>global scope<\/em>&nbsp;as special block having no outer blocks and indentation level 0.<\/p>\n\n\n\n<p>Finally, global variables are those defined in the global scope.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"variable-visibility-rules\">Variable Visibility Rules<\/h2>\n\n\n\n<p>A variable is&nbsp;visible&nbsp;in the portion of code that:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>starts from the variable\u2019s declaration statement,<\/li><li>ends at the end of the variable\u2019s declaration block, and<\/li><li>includes&nbsp;<em>all<\/em>&nbsp;the nested blocks within 1. and 2.<\/li><\/ol>\n\n\n\n<p>Complementary, a variable is&nbsp;not visible&nbsp;in the portion of code that lies:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>before the variable\u2019s declaration, and<\/li><li>after the end of the variable\u2019s declaration block.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"recommendations\">Recommendations <\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>R1. Never use global variables<\/li><li>R2. Declare single-purpose variables<\/li><li>R3. Declare variables close to their use<\/li><li>R4. Keep code blocks small<\/li><li>R5. Use variables close to their declaration<\/li><li>R6. Use no more than two nesting levels<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"r1-never-use-global-variables\">R1. Never use global variables<\/h3>\n\n\n\n<p>Never declare or use global variables as they make code a lot more difficult to read, maintain and test. See&nbsp;<a href=\"https:\/\/wiki.c2.com\/?GlobalVariablesAreBad\" target=\"_blank\" rel=\"noreferrer noopener\"><em>\u201cglobal variables are bad\u201d<\/em><\/a>.<\/p>\n\n\n\n<p>Their use increases the occurrences of problematic&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Side_effect_(computer_science)\" target=\"_blank\" rel=\"noreferrer noopener\"><em>side effects<\/em><\/a>, which often lead to programming errors that are not easy to identify and fix.<\/p>\n\n\n\n<p>The fewer the statements over the program that could erroneously assign variables, the better.<\/p>\n\n\n\n<p>In conclusion, the use of global variables often represent&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Technical_debt\" target=\"_blank\" rel=\"noreferrer noopener\"><em>technical debts<\/em><\/a>, which must be repaid ASAP with a code rewrite!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"r2-declare-single-purpose-variables\">R2. Declare single-purpose variables<\/h3>\n\n\n\n<p>Declare and use variables for a single specific purpose so as to restrict their scope to the minimum.<\/p>\n\n\n\n<p>The more the purposes of a declared variable, the higher the number of statements the variable will be visible to.<\/p>\n\n\n\n<p>The higher the number of statements the variable is visible to, the more the statements that could erroneously assign the variable.<\/p>\n\n\n\n<p>The more the statements that could erroneously assign the variable, the more difficult to find and fix potential errors.<\/p>\n\n\n\n<p>Summing up: only declare and use variables that are single-purposed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"r3-declare-variables-close-to-their-use\">R3. Declare variables close to their use<\/h3>\n\n\n\n<p>Declare variables as close as possible to the statements and code blocks that will use them.<\/p>\n\n\n\n<p>Strictly related to the recommendation R2, this is another way of reducing the number of statements that can use the declared variables.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"example-three-subsequent-blocks\">Example: Three Subsequent Blocks<\/h4>\n\n\n\n<p>First, let\u2019s consider three subsequent code blocks&nbsp;<em>A<\/em>,&nbsp;<em>B<\/em>, and&nbsp;<em>C<\/em>, namely:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em>A<\/em>,&nbsp;<em>B<\/em>, and&nbsp;<em>C<\/em>&nbsp;are in the same outer block, and<\/li><li>they have the same level of indent.<\/li><\/ul>\n\n\n\n<p>Second, let\u2019s declare a variable&nbsp;<em>v<\/em>&nbsp;immediately before&nbsp;<em>A<\/em>, at the same indentation level of&nbsp;<em>A<\/em>.<\/p>\n\n\n\n<p>According to the visibility rules,&nbsp;<em>v<\/em>&nbsp;will be visible to all the three subsequent blocks&nbsp;<em>A<\/em>,&nbsp;<em>B<\/em>, and&nbsp;<em>C<\/em>.<\/p>\n\n\n\n<p>Now let\u2019s assume we need&nbsp;<em>v<\/em>&nbsp;to be visible only to&nbsp;<em>C<\/em>.<\/p>\n\n\n\n<p>Clearly, declaring&nbsp;<em>v<\/em>&nbsp;immediately before&nbsp;<em>C<\/em>&nbsp;will reduce its visibility by making it only visible by statements within&nbsp;<em>C<\/em>. So far so good!<\/p>\n\n\n\n<p>However, this recommendation is only partially useful, if followed without the next recommendation being followed as well.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"r4-keep-code-blocks-small\">R4. Keep code blocks small<\/h3>\n\n\n\n<p>Similar to the recommendation R2 on single-purpose variables, keep code blocks as small as possible by making them focused on a single specific task.<\/p>\n\n\n\n<p>Otherwise, some variables will likely become unnecessarily visible by the code block parts dedicated to different tasks.<\/p>\n\n\n\n<p>Let\u2019s take again the three subsequent blocks&nbsp;<em>A<\/em>,&nbsp;<em>B<\/em>&nbsp;and&nbsp;<em>C<\/em>&nbsp;introduced before, which have the same indentation level.<\/p>\n\n\n\n<p>Let\u2019s suppose we need to declare a variable&nbsp;<em>w<\/em>&nbsp;to be used and modified by&nbsp;<em>A<\/em>&nbsp;while only being read by B and C.<\/p>\n\n\n\n<p>Declaring&nbsp;<em>w<\/em>&nbsp;immediately before A is inevitable, thus its scope will unnecessarily include&nbsp;<em>B<\/em>&nbsp;and&nbsp;<em>C<\/em>.<\/p>\n\n\n\n<p>This makes&nbsp;<em>B<\/em>&nbsp;and&nbsp;<em>C<\/em>&nbsp;able to also assign&nbsp;<em>w<\/em>, while want them to only be able to read&nbsp;<em>w<\/em>\u2019s value.<\/p>\n\n\n\n<p>How do we avoid this? Just separate&nbsp;<em>B<\/em>&nbsp;and&nbsp;<em>C<\/em>&nbsp;into two distinct functions, that take&nbsp;<em>w<\/em>&nbsp;as one their arguments.<\/p>\n\n\n\n<p>Summing up: make code blocks being single-task, and move sub-tasks into separate functions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"r5-use-variables-close-to-their-declaration\">R5. Use variables close to their declaration<\/h3>\n\n\n\n<p>Remember to use variables as close to their declaration as possible.<\/p>\n\n\n\n<p>Let\u2019s say you need to use (i.e. either read or assign) a variable&nbsp;<em>v<\/em>&nbsp;declared in an outer block.<\/p>\n\n\n\n<p>Remember to minimize the indentation levels between the statement that uses&nbsp;<em>v<\/em>&nbsp;and the declaration block of&nbsp;<em>v<\/em>.<\/p>\n\n\n\n<p>A general rule:&nbsp;<em>Two<\/em>&nbsp;should be the maximum number of nesting levels between the variable declaration and its use.<\/p>\n\n\n\n<p>For completeness, let\u2019s see an example where it may be reasonable to use variables at a distance of&nbsp;<em>three<\/em>&nbsp;nesting levels (i.e. one more than the recommended).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"example-matrix-multiplication-algorithm\">Example: Matrix Multiplication Algorithm<\/h4>\n\n\n\n<p>Let\u2019s consider the iterative&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Matrix_multiplication_algorithm#Iterative_algorithm\" target=\"_blank\" rel=\"noreferrer noopener\">matrix multiplication algorithm<\/a>, which uses three nested loops.<\/p>\n\n\n\n<p>The deepest of such loops contains this assignment statement:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em>sum<\/em>&nbsp;\u2190&nbsp;<em>sum<\/em>&nbsp;+&nbsp;<em>A<\/em><sub><em>ik<\/em><\/sub>&nbsp;\u00d7&nbsp;<em>B<\/em><sub><em>kj<\/em><\/sub>.<\/p><\/blockquote>\n\n\n\n<p><em>A<\/em>&nbsp;and&nbsp;<em>B<\/em>&nbsp;used by the statement are declared in an outer block at three nesting levels of distance, which is one level more than the recommended maximum.<\/p>\n\n\n\n<p>In cases like this, it\u2019s very much forgivable to make an exception to the rule.<\/p>\n\n\n\n<p>Corner-cases apart, consider&nbsp;<em>three<\/em>&nbsp;as too many levels of indent when using variables declared in outer blocks.<\/p>\n\n\n\n<p>Despite can be practically met by recommendation R6, keeping this recommendation in mind it\u2019s always a good idea when organizing code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"r6-use-no-more-than-two-nesting-levels\">R6. Use no more than two nesting levels<\/h3>\n\n\n\n<p>In general, remember to reduce the depth of nested blocks as much as possible.<\/p>\n\n\n\n<p>The maximum nesting depth in each function should be&nbsp;<em>two<\/em>&nbsp;at most.<\/p>\n\n\n\n<p>When a function has a nesting depth higher than two, restructure it in the following way:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>move some sub-blocks into separate functions, and<\/li><li>pass the variables used by the moved sub-blocks as functions\u2019 arguments.<\/li><\/ol>\n\n\n\n<p>As seen in the recommendation R5, it\u2019s sometimes reasonable to have&nbsp;<em>three<\/em>&nbsp;as the maximum depth.<\/p>\n\n\n\n<p>Again, corner-cases apart, always consider&nbsp;<em>two<\/em>&nbsp;as the maximum nesting depth.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Feb 10, 2 Let\u2019s see some recommendations on how to prev [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"class_list":["post-1016","post","type-post","status-publish","format-standard","hentry","category-12"],"_links":{"self":[{"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=\/wp\/v2\/posts\/1016"}],"collection":[{"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1016"}],"version-history":[{"count":6,"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=\/wp\/v2\/posts\/1016\/revisions"}],"predecessor-version":[{"id":1103,"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=\/wp\/v2\/posts\/1016\/revisions\/1103"}],"wp:attachment":[{"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1016"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1016"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lcettsg.cn\/code\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1016"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}