{"id":939,"date":"2011-08-10T22:33:26","date_gmt":"2011-08-11T02:33:26","guid":{"rendered":"http:\/\/yuguangzhang.com\/blog\/?p=939"},"modified":"2011-08-10T22:33:26","modified_gmt":"2011-08-11T02:33:26","slug":"functional-javascript-programming-using-underscore","status":"publish","type":"post","link":"http:\/\/yuguangzhang.com\/blog\/functional-javascript-programming-using-underscore\/","title":{"rendered":"Functional Javascript Programming using Underscore"},"content":{"rendered":"<p><strong>The Scenario<\/strong><\/p>\n<p>Suppose a javascript function is needed to parse text and execute another function for certain lines of text. Each line of the text is ended with a line break. If there is a keyword &#8216;get&#8217;, then the word following it needs to be checked if it is in the list of files on the server, and get it, using a GET request. So &#8216;get this&#8217; would get the file &#8216;this&#8217; from the server.<\/p>\n<p><strong>Object Oriented Approach<\/strong><\/p>\n<p>First, I tried doing this using the traditional way, with array indexes of letters.<\/p>\n<p>[cc lang=&#8221;javascript&#8221;]<br \/>\nif(input.value.split(&#8216; &#8216;).indexOf(&#8216;get&#8217;)==-1) return;<br \/>\nvar lines = input.value.split(&#8216;\\n&#8217;);<br \/>\n&#8230;<br \/>\n[\/cc]<\/p>\n<p>I stopped right there the next line is supposed to be a for each loop. That satisfied the requirements for using a functional library called underscore.js.<\/p>\n<p><strong>Mixed Approach <\/strong><\/p>\n<p>Not my favorite one, as it makes the painting look like a collage, and I think it made an error in the code harder to spot. See if you can spot it:<\/p>\n<p>[cc lang=&#8221;javascript&#8221;]<br \/>\n_(input.value.split(&#8216; &#8216;)).chain()<br \/>\n\t.select(function (line) {<br \/>\n\t\tvar words = line.split(&#8216; &#8216;);<br \/>\n\t\treturn words.length > 1 &#038;&#038; words[0] == &#8216;get&#8217; &#038;&#038; _.include(files, words[1]);<br \/>\n\t})<br \/>\n\t.each(function (line) {<br \/>\n\t\texecuteGet(line);<br \/>\n\t});<br \/>\n[\/cc]<br \/>\nAha! The space should actually be newline.<\/p>\n<p><strong>Functional Approach <\/strong><br \/>\nThis time, I had to modify the code to use a single word from the word array, the last one.<br \/>\nThe main line that violated the functional approach was<br \/>\n[cc lang=&#8221;javascript&#8221;]<br \/>\nvar words = line.split(&#8216; &#8216;);<br \/>\n[\/cc]<br \/>\nalong with the array accesses, which should be replaced with first and rest. It turns out there is a purely functional way:<br \/>\n[cc lang=&#8221;javascript&#8221;]<br \/>\n_(input.value.split(&#8216;\\n&#8217;)).chain()<br \/>\n\t.map(function (line) {<br \/>\n\t\treturn line.replace(\/get\\s*\/, &#8221;);<br \/>\n\t})<br \/>\n\t.select(function (module) {<br \/>\n\t\treturn module in files;<br \/>\n\t})<br \/>\n\t.each(function (module) {<br \/>\n\t\t$.get(files[module]);<br \/>\n\t})<br \/>\n[\/cc]<br \/>\nThe custom executeGet function has been replaced by jQuery&#8217;s $.get.<\/p>\n<p><strong>Conclusions<\/strong><br \/>\nWhich approach is better? Using the OO approach, a local index variable would be needed to be created for the for loop, along with other locals, which adds irrelevant lines to the code. On the other hand, each line on its own makes sense. However, functional code cannot be understood except as a whole, because there are no variables. <a href=\"http:\/\/www.kurims.kyoto-u.ac.jp\/~ichiro\/papers\/quantumGoI.pdf\">Statelessness has its own beauty in programming.<\/a> It&#8217;s similar to running a quantum computer, not caring how bits disappear or time warp, but only for the result of the computation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Scenario Suppose a javascript function is needed to parse text and execute another function for certain lines of text. Each line of the text is ended with a line break. If there is a keyword &#8216;get&#8217;, then the word following it needs to be checked if it is in the list of files on [&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":[23],"tags":[141,133,142],"class_list":["post-939","post","type-post","status-publish","format-standard","hentry","category-programming","tag-functional-programming","tag-javascript","tag-object-oriented-programming"],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/posts\/939","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/comments?post=939"}],"version-history":[{"count":0,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/posts\/939\/revisions"}],"wp:attachment":[{"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/media?parent=939"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/categories?post=939"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/yuguangzhang.com\/blog\/wp-json\/wp\/v2\/tags?post=939"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}