<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.spheredev.org/index.php?action=history&amp;feed=atom&amp;title=JavaScript%2FHigher-order_programming%2FExample_1</id>
		<title>JavaScript/Higher-order programming/Example 1 - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.spheredev.org/index.php?action=history&amp;feed=atom&amp;title=JavaScript%2FHigher-order_programming%2FExample_1"/>
		<link rel="alternate" type="text/html" href="http://wiki.spheredev.org/index.php?title=JavaScript/Higher-order_programming/Example_1&amp;action=history"/>
		<updated>2026-04-30T03:07:59Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.29.0</generator>

	<entry>
		<id>http://wiki.spheredev.org/index.php?title=JavaScript/Higher-order_programming/Example_1&amp;diff=836&amp;oldid=prev</id>
		<title>Apollolux: created</title>
		<link rel="alternate" type="text/html" href="http://wiki.spheredev.org/index.php?title=JavaScript/Higher-order_programming/Example_1&amp;diff=836&amp;oldid=prev"/>
				<updated>2013-06-15T00:43:36Z</updated>
		
		<summary type="html">&lt;p&gt;created&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;We have HP, and we want some way to heal ourselves:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var hero = {hp: 10, hpMax: 85};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It'd be nice to have a Potion, a Super Potion and a Mega Potion, healing 10, 20 and 50 HP respectively. It'd also be nice to see a dialog saying which item was used and how much HP we recovered.&lt;br /&gt;
&lt;br /&gt;
===The chump's way===&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
function Potion() {&lt;br /&gt;
  var oldHp = hero.hp;&lt;br /&gt;
  hero.hp += 10;&lt;br /&gt;
  if (hero.hp &amp;gt; hero.hpMax) hero.hp = hero.hpMax;&lt;br /&gt;
 &lt;br /&gt;
  var heal = hero.hp - oldHp;&lt;br /&gt;
  if (heal &amp;gt; 0)&lt;br /&gt;
    Print.printLine(&amp;quot;Drank Potion! Recovered &amp;quot; + heal + &amp;quot; HP.&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    Print.printLine(&amp;quot;Drank Potion! Nothing happened.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
function SuperPotion() {&lt;br /&gt;
  var oldHp = hero.hp;&lt;br /&gt;
  hero.hp += 20;&lt;br /&gt;
  if (hero.hp &amp;gt; hero.hpMax) hero.hp = hero.hpMax;&lt;br /&gt;
 &lt;br /&gt;
  var heal = hero.hp - oldHp;&lt;br /&gt;
  if (heal &amp;gt; 0)&lt;br /&gt;
    Print.printLine(&amp;quot;Drank Super Potion! Recovered &amp;quot; + heal + &amp;quot; HP.&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    Print.printLine(&amp;quot;Drank Super Potion! Nothing happened.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
function MegaPotion() {&lt;br /&gt;
  var oldHp = hero.hp;&lt;br /&gt;
  hero.hp += 50;&lt;br /&gt;
  if (hero.hp &amp;gt; hero.hpMax) hero.hp = hero.hpMax;&lt;br /&gt;
 &lt;br /&gt;
  var heal = hero.hp - oldHp;&lt;br /&gt;
  if (heal &amp;gt; 0)&lt;br /&gt;
    Print.printLine(&amp;quot;Drank Mega Potion! Recovered &amp;quot; + heal + &amp;quot; HP.&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    Print.printLine(&amp;quot;Drank Mega Potion! Nothing happened.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ugh. Copy-pasting this was a pain. Imagine if we had to change the message format, or if we had 10 items. Miserable. Absolutely miserable. Anyway, we can use it like this:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var inventory = [Potion, SuperPotion, MegaPotion];&lt;br /&gt;
inventory[0]();&lt;br /&gt;
inventory[1]();&lt;br /&gt;
inventory[2]();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With the output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Drank Potion! Recovered 10 HP.&lt;br /&gt;
Drank Super Potion! Recovered 20 HP.&lt;br /&gt;
Drank Mega Potion! Recovered 45 HP.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===A smarter way===&lt;br /&gt;
These potions do almost exactly the same thing. Let's reflect that in our code. We express the idea of a healing item '''once and only once'''. In fact, there's no reason to restrict it to HP.&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
function HealingItem(name, stat, amount) {&lt;br /&gt;
  return function () {&lt;br /&gt;
    var oldStat = hero[stat];&lt;br /&gt;
    hero[stat] += amount;&lt;br /&gt;
    if (hero[stat] &amp;gt; hero[stat + &amp;quot;Max&amp;quot;]) hero[stat] = hero[stat + &amp;quot;Max&amp;quot;];&lt;br /&gt;
 &lt;br /&gt;
    var heal = hero[stat] - oldStat;&lt;br /&gt;
    if (heal &amp;gt; 0)&lt;br /&gt;
      Print.printLine(&amp;quot;Drank &amp;quot; + name + &amp;quot;! Recovered &amp;quot; + heal + &amp;quot; &amp;quot; + stat.toUpperCase() + &amp;quot;.&amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
      Print.printLine(&amp;quot;Drank &amp;quot; + name + &amp;quot;! Nothing happened.&amp;quot;);&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
function Potion() {&lt;br /&gt;
  return HealingItem(&amp;quot;Potion&amp;quot;, &amp;quot;hp&amp;quot;, 10);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
function SuperPotion() {&lt;br /&gt;
  return HealingItem(&amp;quot;Super Potion&amp;quot;, &amp;quot;hp&amp;quot;, 20);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
function MegaPotion() {&lt;br /&gt;
  return HealingItem(&amp;quot;Mega Potion&amp;quot;, &amp;quot;hp&amp;quot;, 50);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, the higher-order function is &amp;lt;code&amp;gt;HealingItem()&amp;lt;/code&amp;gt;, because, as you can see, it returns a function as its result. Note that even after &amp;lt;code&amp;gt;HealingItem()&amp;lt;/code&amp;gt; has returned, &amp;lt;var&amp;gt;name&amp;lt;/var&amp;gt;, &amp;lt;var&amp;gt;stat&amp;lt;/var&amp;gt; and &amp;lt;var&amp;gt;amount&amp;lt;/var&amp;gt; are still &amp;quot;remembered&amp;quot;. This funky property of returned functions is known as '''closure'''. We won't cover that here, but suffice to say, they're useful.&lt;br /&gt;
Potion(), SuperPotion() and MegaPotion() just wrap conveniently around HealingItem() so we don't have to provide all the mundane parameters such as the name, statistic and amount each time. We call them wrappers: they make code easier to read.&lt;br /&gt;
&lt;br /&gt;
We can use them as before:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
var inventory = [Potion(), SuperPotion(), MegaPotion()];&lt;br /&gt;
inventory[0]();&lt;br /&gt;
inventory[1]();&lt;br /&gt;
inventory[2]();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Producing the same output:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Drank Potion! Recovered 10 HP.&lt;br /&gt;
Drank Super Potion! Recovered 20 HP.&lt;br /&gt;
Drank Mega Potion! Recovered 45 HP.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;code&amp;gt;Potion()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;SuperPotion()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;MegaPotion()&amp;lt;/code&amp;gt; now ''make'' items, so we need to put the parentheses there to &amp;quot;manufacture&amp;quot; the potions.&lt;br /&gt;
&lt;br /&gt;
This demonstrates both the power of JavaScript's functions, but also the flexibility provided by its '''reflection''': seeing and using program info when the program is running. Thanks to not restricting ourselves to HP, we can make ethers too:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
function Ether() {&lt;br /&gt;
  return HealingItem(&amp;quot;Ether&amp;quot;, &amp;quot;mp&amp;quot;, 10);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
function SuperEther() {&lt;br /&gt;
  return HealingItem(&amp;quot;Super Ether&amp;quot;, &amp;quot;mp&amp;quot;, 20);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
function MegaEther() {&lt;br /&gt;
  return HealingItem(&amp;quot;Mega Ether&amp;quot;, &amp;quot;mp&amp;quot;, 50);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the chump's way, this would have doubled the size of the code.&lt;/div&gt;</summary>
		<author><name>Apollolux</name></author>	</entry>

	</feed>