{"id":519,"date":"2014-02-26T22:18:50","date_gmt":"2014-02-26T09:18:50","guid":{"rendered":"http:\/\/www.paradicesoftware.com\/blog\/?p=519"},"modified":"2014-02-26T22:22:22","modified_gmt":"2014-02-26T09:22:22","slug":"boolean-function-parameters","status":"publish","type":"post","link":"http:\/\/www.paradicesoftware.com\/blog\/2014\/02\/boolean-function-parameters\/","title":{"rendered":"Boolean Function Parameters"},"content":{"rendered":"<p>Consider the following code, which might be part of a custom Font class to draw fancy text.<\/p>\n<pre class=\"brush: delphi; light: true; title: ; notranslate\" title=\"\">\r\nprocedure DrawText(Text: String; Position: TRect; Color: dword);\r\n<\/pre>\n<p>Looks good, right? Parameters are clear, order makes sense, and it&#8217;s easy to understand what the code does when you find it invoked:<\/p>\n<pre class=\"brush: delphi; light: true; title: ; notranslate\" title=\"\">\r\n\/\/ some random stuff\r\nFont.DrawText('Hello!',Window.Position,COL_WHITE);\r\n\/\/ more random stuff\r\n<\/pre>\n<p>No need to go searching for the function implementation, or hovering over using the IDE to figure out what the parameters mean. It&#8217;s very clear. But now, say you want to add the ability to draw a &#8220;drop shadow&#8221; behind the text. No worries, let&#8217;s add a boolean parameter:<\/p>\n<pre class=\"brush: delphi; light: true; title: ; notranslate\" title=\"\">\r\n\/\/ Method declaration\r\nprocedure DrawText(\r\n   Text: String; Position: TRect; Color: dword; Shadow: boolean);\r\n\r\n\/\/ Invocation\r\nFont.DrawText('Hello!',Window.Position,COL_WHITE,true);\r\n<\/pre>\n<p>Hmm. It&#8217;s not terrible, and if you use DrawText a lot you will soon pick up the meaning, but a little bit of clarity has been lost. You might get smarter and make Shadow an optional parameter which defaults to false, to prevent breaking any existing code. But now&#8230; you want to add the ability for text to be horizontally and\/or vertically centered within the position rect. Let&#8217;s see:<\/p>\n<pre class=\"brush: delphi; light: true; title: ; notranslate\" title=\"\">\r\n\/\/ Method declaration\r\nprocedure DrawText(\r\n   Text: String; Position: TRect; Color: dword; Shadow,CentreX,CentreY: boolean);\r\n\r\n\/\/ Invocation\r\nFont.DrawText('Hello!',Window.Position,COL_WHITE,true,true,false);\r\n<\/pre>\n<p>OK, at this point the function&#8217;s invocation is no longer readable by itself. Worse, no matter how many times you use it, you&#8217;re bound to forget the order of those parameters occasionally. I should know, the above function was ripped directly out of my old custom bitmap-font based class. But when I needed to add wordwrapping and other alignment options, it needed to go.<\/p>\n<p>In general, if the meaning of a boolean parameter isn&#8217;t made totally obvious by the function name, it might not be the most readable solution. One of the golden rules of programming: it&#8217;s harder to read code than to write, so any extra effort to make it easier to read later is time well spent. <\/p>\n<h3>Use Sets as parameters!<\/h3>\n<p>It&#8217;s a little bit more setup, but you (and anyone else reading your code) will thank you if you take the time to implement a set. (if your language doesn&#8217;t support sets, constant values achieve the same result, but are very slightly less readable, and also don&#8217;t protect you against invalid values being passed). <\/p>\n<pre class=\"brush: delphi; light: true; title: ; notranslate\" title=\"\">\r\n\/\/ Type declaration\r\nTTextStyles      = (\r\n   TS_DropShadow ,\r\n   TS_CentreX    ,\r\n   TS_CentreY    ,\r\n   TS_WordWrap   );\r\n\r\nTTextStyle       = set of TTextStyles;\r\n\r\n\/\/ Method declaration\r\nprocedure DrawText(\r\n   Text: String; Position: TRect; Color: dword; Style: TTextStyle);\r\n\r\n\/\/ Invocation\r\nFont.DrawText('Hello!',Window.Position,COL_WHITE,&#x5B;TS_DropShadow,TS_CentreX]);\r\n<\/pre>\n<p>It&#8217;s instantly obvious what the invocation does; no need to look up parameters. A bonus feature is the set of available styles can easily be extended without breaking any existing code. <\/p>\n<p>The main downside is that it&#8217;s harder to generate set values inline compared to boolean functions, so if the parameters to your particular method tend to change depending on conditional evaluation, it can be a bit of a pain. But in this example, the readability benefit is worth the extra effort during declaration.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Consider the following code, which might be part of a custom Font class to draw fancy text. procedure DrawText(Text: String; Position: TRect; Color: dword); Looks good, right? Parameters are clear, order makes sense, and it&#8217;s easy to understand what the code does when you find it invoked: \/\/ some random stuff Font.DrawText(&#8216;Hello!&#8217;,Window.Position,COL_WHITE); \/\/ more random<\/p>\n","protected":false},"author":2722,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,18],"tags":[74,77,75,73],"class_list":["post-519","post","type-post","status-publish","format-standard","hentry","category-code","category-good-coding-guidelines","tag-boolean","tag-code","tag-parameters","tag-sets"],"_links":{"self":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/519","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/users\/2722"}],"replies":[{"embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/comments?post=519"}],"version-history":[{"count":9,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/519\/revisions"}],"predecessor-version":[{"id":561,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/519\/revisions\/561"}],"wp:attachment":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=519"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=519"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=519"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}