http://wiki.spheredev.org/index.php?title=JavaScript/Higher-order_programming/Example_2&feed=atom&action=historyJavaScript/Higher-order programming/Example 2 - Revision history2024-03-28T10:41:55ZRevision history for this page on the wikiMediaWiki 1.29.0http://wiki.spheredev.org/index.php?title=JavaScript/Higher-order_programming/Example_2&diff=834&oldid=prevApollolux: created2013-06-15T00:42:30Z<p>created</p>
<p><b>New page</b></p><div>Say I've got this, an array of strings holding stats to be displayed in a box:<br />
<syntaxhighlight><br />
var stats = [<br />
"Hero L" + level,<br />
"Exp: " + exp + " / " + next,<br />
"",<br />
"HP: " + hp + " / " + hpMax,<br />
"MP: " + mp + " / " + mpMax<br />
];<br />
</syntaxhighlight><br />
<br />
In order to draw a window style around it, we'll need to find out which line is longest.<br />
<br />
===The chump's way===<br />
<syntaxhighlight><br />
var maxWidth = 0;<br />
for (var i = 0; i < stats.length; ++i) {<br />
if (maxWidth < GetSystemFont().getStringWidth(stats[i]))<br />
maxWidth = GetSystemFont().getStringWidth(stats[i]);<br />
}<br />
</syntaxhighlight><br />
<br />
What's wrong with it?<br />
<br />
* ''<code>for</code> loop is crappy'' - We're good coders, so we recognise that this looks for a maximum without even reading it. But if we really sat down and ''read'' it, we're looking at 20+ tokens spread across four lines. And this is just a simple loop. In a more complex loop body, a bug would be almost impossible to find.<br />
* ''Focus is on iteration instead of task'' - The variable <var>i</var> occurs in no less than 5 places. As it turns out later on, we don't even need it.<br />
* ''Copy-paste coding style'' - The body of the <code>for</code> loop has two lines which are almost identical. Copy-paste == more lines to change if a single line needs changing.<br />
<br />
===A smarter way===<br />
<syntaxhighlight><br />
var maxWidth = reduce(function (a, b) {<br />
return a > b ? a : b;<br />
}, 0, map(GetSystemFont().getStringWidth, stats));<br />
</syntaxhighlight><br />
<br />
Basically, the stats have been ''mapped'' from strings to their widths according to the system font, and those widths have been ''reduced'' to find the maximum of them.<br />
<br />
Note that we can use Sphere's API functions with our higher-order functions, just by omitting the "call" parentheses.<br />
<br />
Why it's good:<br />
<br />
* ''Less typing'' - Compare these to the chump's way. Do you really want to type all that? Less typing == less typos == less chance of errors.<br />
* ''No unnecessary index'' - I told you we didn't need the index.<br />
* ''No copy-paste'' - Copy-paste == bad. I shouldn't have to explain this.<br />
<br />
===An even smarter way===<br />
<syntaxhighlight><br />
var maxWidth = Math.max.apply(null, map(GetSystemFont().getStringWidth, stats));<br />
</syntaxhighlight><br />
<br />
The kind folk behind Sphere's JavaScript engine gave us the standard JavaScript library. It doesn't include much, but it's got [https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/max Math.max], which we can link with our own higher-order functions to do lots of heavy lifting.<br />
<br />
Same benefits as the smarter way, plus it's shorter, and now the intent is very, very clear. This is what we're aiming for.</div>Apollolux