{"id":108,"date":"2012-03-17T07:15:27","date_gmt":"2012-03-17T07:15:27","guid":{"rendered":"http:\/\/ootips.org\/yonat\/?p=108"},"modified":"2016-04-17T07:22:36","modified_gmt":"2016-04-17T07:22:36","slug":"the-three-underscores-idiom","status":"publish","type":"post","link":"https:\/\/ootips.org\/yonat\/the-three-underscores-idiom\/","title":{"rendered":"The Three Underscores Idiom"},"content":{"rendered":"<pre class=\"lang:objc decode:true \">\r\n#define ___\r\n\/\/ defines three underscores as nothing\r\n<\/pre>\n<p>This is something I learned on my first programming job (eons ago&#8230;) and found useful but underused.<\/p>\n<p>Useful for what? To solve the persistent tension between the robustness of single-exit point and the  complexity of using extra state variables and state checking code.<\/p>\n<p>Let me show you what I mean.<\/p>\n<p><!--more-->Say you write a function that needs to return an element matching some spec or create a new one. There are two ways to code this.<\/p>\n<p>The simple yet multi-exit way:<\/p>\n<pre class=\"lang:objc decode:true \">\r\nElement *matchingElement()\r\n{\r\n    for (Element *e  in collection) {\r\n        if ( isMatching(e) ) {\r\n            \/\/ some important code\r\n            return e; \/\/ first exit point\r\n        }\r\n    }\r\n    return newElement(); \/\/ second exit point\r\n}\r\n<\/pre>\n<p>The single-exit way:<\/p>\n<pre class=\"lang:objc decode:true \">\r\nElement *matchingElement()\r\n{\r\n    bool foundMatch = false;\r\n    Element *e = getFirstElement();\r\n    while (e != nil && !foundMatch)\r\n        if ( isMatching(e) ) {\r\n            \/\/ some important code\r\n            foundMatch = true; \/\/ setting state variable\r\n        }\r\n        e = nextElement();\r\n    }\r\n    return foundMatch ? e : newElement(); \/\/ single exit point from function\r\n}\r\n<\/pre>\n<p>Now some of you are wondering why bother with foundMatch; you need to go read <a href=\"http:\/\/www.tomdalling.com\/blog\/coding-tips\/coding-tip-have-a-single-exit-point\">Tom Dalling&#8217;s Coding Tip explaining the problems with multiple exit points<\/a>.<br \/>\nOthers shudder to see a return statement in the middle of the function; you should remember that more variables mean more code mean more bugs.<\/p>\n<p>So how does <em>the three underscores idiom<\/em> solve this conundrum? It goes hand in hand with the common convention of 4-space indentation. Together, they allow you to write this:<\/p>\n<pre class=\"lang:objc decode:true \">\r\nElement *matchingElement()\r\n{\r\n    for (Element *e  in collection) {\r\n        if (isMatching(e) ) {\r\n            \/\/ some important code\r\n___ ___ ___ return e;\r\n        }\r\n    }\r\n___ return newElement();\r\n}\r\n<\/pre>\n<p>And suddenly both exit points become clear and visible and not so prone to bugs.<\/p>\n<p>The three underscores idiom should be used not only for return statements, but for any jump in the flow of control, like break or continue in a loop:<\/p>\n<pre class=\"lang:objc decode:true \">\r\nElement *matchingElement()\r\n{\r\n    for (Element *e  in collection) {\r\n        if ( notEvenClose(e) ) {\r\n    ___ ___ continue;\r\n        }\r\n        if ( isMatching(e) ) {\r\n            \/\/ some important code\r\n___ ___ ___ return e;\r\n        }\r\n    } while ( e = nextElement() );\r\n___ return newElement();\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>#define ___ \/\/ defines three underscores as nothing This is something I learned on my first programming job (eons ago&#8230;) and found useful but underused. Useful for what? To solve the persistent tension between the robustness of single-exit point and &hellip; <a href=\"https:\/\/ootips.org\/yonat\/the-three-underscores-idiom\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[1],"tags":[12,13,11],"class_list":["post-108","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-c","tag-objective-c","tag-programming-idioms"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2aEUP-1K","_links":{"self":[{"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/posts\/108","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/comments?post=108"}],"version-history":[{"count":7,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/posts\/108\/revisions"}],"predecessor-version":[{"id":247,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/posts\/108\/revisions\/247"}],"wp:attachment":[{"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/media?parent=108"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/categories?post=108"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ootips.org\/yonat\/wp-json\/wp\/v2\/tags?post=108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}