{"id":537,"date":"2018-11-20T09:41:42","date_gmt":"2018-11-20T09:41:42","guid":{"rendered":"https:\/\/books.compclassnotes.com\/elementarycomputing\/?page_id=537"},"modified":"2018-11-20T09:42:10","modified_gmt":"2018-11-20T09:42:10","slug":"using-conditionals-in-functions","status":"publish","type":"page","link":"https:\/\/books.compclassnotes.com\/elementarycomputing\/using-conditionals-in-functions\/","title":{"rendered":"Using Conditionals In Functions"},"content":{"rendered":"<p>We can use\u00a0<strong>IF<\/strong> to make decisions in our programs. Here we display either &#8220;pass&#8221; or &#8220;fail&#8221; depending on the grade that is passed to this function;<\/p>\n<pre>(define pass?\r\n    (lambda (x)\r\n       (if (&gt; = x 40) \"pass\" \"fail\")\r\n    )\r\n)\r\n<\/pre>\n<p>Notice the indentation of the brackets. This doesn&#8217;t change the functionality, but it makes it easier to read &#8212; another example of syntax versus semantics.\u00a0<strong>pass?<\/strong> takes one parameters and, if it is greater than or equal to 40, returns the word &#8220;pass&#8221;.<\/p>\n<p>Here&#8217;s a similar function. This one only returns\u00a0<strong>#t<\/strong> or\u00a0<strong>#f<\/strong>:<\/p>\n<pre>(define pass2?\r\n    (lambda (x)\r\n       (if (&gt; = x 40) #t #f)\r\n    )\r\n)\r\n\r\n&gt; (pass? 30)\r\n\"fail\"\r\n&gt; (pass2? 30)\r\n#f<\/pre>\n<p>Although it may seem like\u00a0<strong>pass?<\/strong> is more useful as it returns something readable by us humans, it turns out that it is actually\u00a0<em>less<\/em> useful because of this.\u00a0<strong>pass2?\u00a0<\/strong>is what is known as\u00a0<em>tightly coupled<\/em>, that is, all the instructions in it are related to one single task, in this case, testing the value passed in and returning\u00a0<strong>#t\u00a0<\/strong>or\u00a0<strong>#f<\/strong>. It is also\u00a0<em>reusable<\/em>, which makes it a lot more useful than\u00a0<strong>pass2?<\/strong>. In fact, most of the functions we&#8217;ve looked at throughout this course, such as\u00a0<strong>sqr<\/strong>,\u00a0<strong>sqrt<\/strong>, etc. are tightly coupled and reusable. Remember how back in the section on <a href=\"https:\/\/books.compclassnotes.com\/elementarycomputing\/lifetime-diagrams\/\">lifetime diagrams<\/a> we said that defined variables and functions became part of the language? The reason that some of these are so useful is because they are reusable.<\/p>\n<p>There&#8217;s also a second problem with\u00a0<strong>pass?<\/strong>. Consider<\/p>\n<pre>(if\r\n    (and (pass? 25) (pass? 60))\r\n       \"passed both\" \r\n       \"didn't pass both\")\r\n    )\r\n)\r\n<\/pre>\n<p>When we evaluate the calls to\u00a0<strong>pass?<\/strong> the\u00a0<strong>and<\/strong> part becomes:<\/p>\n<p><strong>(and &#8220;fail&#8221; &#8220;pass&#8221;)<\/strong><\/p>\n<p>This is where we have a problem, because, as we saw in the previous section, all strings are considered true, and remember,\u00a0<strong>and<\/strong> returns the last true value it is given, otherwise it returns false. This means that it returns\u00a0<strong>&#8220;pass&#8221;<\/strong>, which is wrong. Look at this example; here everything works as we would expect, because\u00a0<strong>pass2?<\/strong> returns a Boolean value.<\/p>\n<pre>(define passBoth\r\n    (lambda (x y)\r\n        (if \r\n           (and (pass2? x) (pass2? y)) \r\n           \"passed both\" \r\n           \"didn't pass both\")\r\n    )\r\n)\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Here&#8217;s the AST for this function. Notice how we have two @ nodes inside the predicate where we&#8217;re testing the conditions; this is because this is a function we wrote ourselves rather than a built in function.<\/p>\n<div id=\"attachment_541\" style=\"width: 378px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-541\" class=\" wp-image-541\" src=\"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-content\/uploads\/sites\/9\/2018\/11\/if-01.png\" alt=\"\" width=\"368\" height=\"337\" srcset=\"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-content\/uploads\/sites\/9\/2018\/11\/if-01.png 503w, https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-content\/uploads\/sites\/9\/2018\/11\/if-01-300x275.png 300w\" sizes=\"auto, (max-width: 368px) 100vw, 368px\" \/><p id=\"caption-attachment-541\" class=\"wp-caption-text\">Using pass2? inside another function<\/p><\/div>\n<p>Let&#8217;s look at another example:<\/p>\n<pre>(define scrape\r\n    (lambda (x)\r\n        (if \r\n           (and (&lt; x 45) (pass2? x)) \r\n           #t \r\n           #f)\r\n    )\r\n)\r\n<\/pre>\n<p>Here we reuse\u00a0<strong>pass2?<\/strong> again, combining with another test inside the body of the function to see if the grade was just barely a pass. Notice the difference in the AST &#8212; we still have @ for\u00a0<strong>pass2?<\/strong>, but not for the <strong>(&lt; x 45)<\/strong> test.<\/p>\n<div id=\"attachment_543\" style=\"width: 367px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-543\" class=\" wp-image-543\" src=\"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-content\/uploads\/sites\/9\/2018\/11\/if-02.png\" alt=\"\" width=\"357\" height=\"235\" srcset=\"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-content\/uploads\/sites\/9\/2018\/11\/if-02.png 730w, https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-content\/uploads\/sites\/9\/2018\/11\/if-02-300x197.png 300w\" sizes=\"auto, (max-width: 357px) 100vw, 357px\" \/><p id=\"caption-attachment-543\" class=\"wp-caption-text\">Mixing built-in and user defined tests in the predicate<\/p><\/div>\n<p>&nbsp;<\/p>\n<p>Here&#8217;s one more version of a function that tests if a grade is a pass. This one also returns a Boolean value but doesn&#8217;t even have an\u00a0<strong>IF<\/strong><\/p>\n<pre>(define pass3?\r\n    (lambda (x)\r\n       (&gt; = x 40) \r\n    )\r\n)\r\n\r\n<\/pre>\n<p>How does this one work? It evaluates\u00a0<strong>(&gt;= x 40)<\/strong> which gives a Boolean, and simply returns that, so it&#8217;s much more efficient.<\/p>\n<p>Let&#8217;s look at one final example. We want to write a function called\u00a0<strong>high-odd<\/strong>, which returns true if a number is greater than 100 and is also odd.<\/p>\n<p>We could all this in one function, but let&#8217;s spread it out across two to make it easier to read. We&#8217;ll first check if the number is odd, and to do this we&#8217;ll use a built in Racket function called\u00a0<strong>integer?<\/strong> which returns\u00a0<strong>#t<\/strong> if its argument is an integer (a whole number with no decimal point) and returns\u00a0<strong>#f<\/strong> otherwise. Here&#8217;s our <strong>odd\u00a0<\/strong>function:<\/p>\n<pre>(define odd\r\n  (lambda (x)\r\n    (not (integer? (\/ x 2)))\r\n    )\r\n  )\r\n<\/pre>\n<p>Satisfy yourself that you understand how it works. It divides the parameter (<strong>x<\/strong>) by 2 and, if <strong>x<\/strong> is odd then\u00a0<strong>integer?<\/strong> would return false (because odd numbers divided by two will have a decimal point), so we return the opposite of that using\u00a0<strong>not<\/strong> because our test should return true if\u00a0<strong>x<\/strong> is an odd number.<\/p>\n<pre>(define high-odd\r\n  (lambda (x)\r\n    (and (&gt; x 100) (odd x))\r\n    )\r\n  )\r\n\r\n(define high-odd2\r\n  (lambda (x)\r\n    (if (&gt; x 100) (odd x) #f)\r\n    )\r\n  )\r\n<\/pre>\n<p><strong>high-odd<\/strong> needs to do two tests; the first checks if\u00a0<strong>x<\/strong> is above 100 and the second that it is\u00a0an odd number. In fact, we&#8217;ve given two versions. The only difference is that\u00a0<strong>high-odd2<\/strong> will only call\u00a0<strong>odd<\/strong> if it actually needs to. Intuitively, this seems like a more efficient piece of code, after all, it seems like there will be less code executed, right? Actually, it turns out that\u00a0<strong>high-odd<\/strong> is more efficient, why? Remember how\u00a0<strong>and<\/strong> works &#8212; if it encounters a false value, it stops evaluating and returns that value, so if\u00a0<strong>x<\/strong> isn&#8217;t greater than 100, it doesn&#8217;t check if\u00a0<strong>x\u00a0<\/strong>is odd or not, because it doesn&#8217;t matter.<\/p>\n<p>However, if\u00a0<strong>x<\/strong> is greater than 100,\u00a0<strong>high-odd2<\/strong> makes another function call. This is a problem because it incurs\u00a0<em>function overhead,\u00a0<\/em>that is, it takes time to set up its local variable, so it is slightly slower. This make very little difference when we&#8217;re only calling the function once, but if we were to call it a billion times, this would all add up.<\/p>\n<p>In the next section, when we create functions that will be called hundreds of times, we&#8217;ll see up close and personal just how much of a difference these extra function calls can have.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We can use\u00a0IF to make decisions in our programs. Here we display either &#8220;pass&#8221; or &#8220;fail&#8221; depending on the grade that is passed to this function; (define pass? (lambda (x) (if (&gt; = x 40) &#8220;pass&#8221; &#8220;fail&#8221;) ) ) Notice <span class=\"readmore\"><a href=\"https:\/\/books.compclassnotes.com\/elementarycomputing\/using-conditionals-in-functions\/\">Continue Reading<\/a><\/span><\/p>\n","protected":false},"author":4,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-537","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-json\/wp\/v2\/pages\/537","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-json\/wp\/v2\/comments?post=537"}],"version-history":[{"count":5,"href":"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-json\/wp\/v2\/pages\/537\/revisions"}],"predecessor-version":[{"id":545,"href":"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-json\/wp\/v2\/pages\/537\/revisions\/545"}],"wp:attachment":[{"href":"https:\/\/books.compclassnotes.com\/elementarycomputing\/wp-json\/wp\/v2\/media?parent=537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}