<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Memoization in JavaScript</title>
	<atom:link href="http://blog.thejit.org/2008/09/05/memoization-in-javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.thejit.org/2008/09/05/memoization-in-javascript/</link>
	<description>Data Visualization, JavaScript and Computer Science related stuff</description>
	<lastBuildDate>Sun, 05 Sep 2010 12:01:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: kangax</title>
		<link>http://blog.thejit.org/2008/09/05/memoization-in-javascript/comment-page-1/#comment-321</link>
		<dc:creator>kangax</dc:creator>
		<pubDate>Sun, 08 Feb 2009 15:15:34 +0000</pubDate>
		<guid isPermaLink="false">http://blog.thejit.org/?p=27#comment-321</guid>
		<description>As Ben already noted, non-primitives are converted to their string representation when used as a left-hand operand in `in` operator:

({toString:function(){ return &#039;foo&#039; }}) in ({ foo: &#039;bar&#039; }); // true

Since native Object objects are converted to &quot;[object Object]&quot;, the `memo` function will produce unexpected results:

function memo(f) {
  return function () {
    var args = Array.prototype.slice.call(arguments);
    f.memo = f.memo &#124;&#124; {};
    return (args in f.memo) 
      ? f.memo[args] 
      : (f.memo[args] = f.apply(this, args));
  };  
};

function f(o1, o2) { return o1.x + o2.x };
var m = memo(f);

m({ x: 1 }, { x: 2 }); // 3
m({ x: 2 }, { x: 4 }); // 3 (boom!)

I wouldn&#039;t &quot;work around&quot; this issue (as it would require storing cached values as keys of an array, rather than as keys of an object - to avoid implicit string conversion - crippling complexity from O(1) to O(n) : )), but rather document it as such.</description>
		<content:encoded><![CDATA[<p>As Ben already noted, non-primitives are converted to their string representation when used as a left-hand operand in `in` operator:</p>
<p>({toString:function(){ return &#8216;foo&#8217; }}) in ({ foo: &#8216;bar&#8217; }); // true</p>
<p>Since native Object objects are converted to &#8220;[object Object]&#8220;, the `memo` function will produce unexpected results:</p>
<p>function memo(f) {<br />
  return function () {<br />
    var args = Array.prototype.slice.call(arguments);<br />
    f.memo = f.memo || {};<br />
    return (args in f.memo)<br />
      ? f.memo[args]<br />
      : (f.memo[args] = f.apply(this, args));<br />
  };<br />
};</p>
<p>function f(o1, o2) { return o1.x + o2.x };<br />
var m = memo(f);</p>
<p>m({ x: 1 }, { x: 2 }); // 3<br />
m({ x: 2 }, { x: 4 }); // 3 (boom!)</p>
<p>I wouldn&#8217;t &#8220;work around&#8221; this issue (as it would require storing cached values as keys of an array, rather than as keys of an object &#8211; to avoid implicit string conversion &#8211; crippling complexity from O(1) to O(n) : )), but rather document it as such.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Douglas Meyer</title>
		<link>http://blog.thejit.org/2008/09/05/memoization-in-javascript/comment-page-1/#comment-218</link>
		<dc:creator>Douglas Meyer</dc:creator>
		<pubDate>Sat, 06 Sep 2008 01:06:56 +0000</pubDate>
		<guid isPermaLink="false">http://blog.thejit.org/?p=27#comment-218</guid>
		<description>Very slick trick!

One thing that you didn&#039;t point out in your last example.
Because you overridden the original function, and the fib function calls its self; you will get pre-memoized values.

Example:
var fib = memo(fib);
fib(10); // Calls fib(9) and fib(8) and fib(7) and fib(6) and ...
fib(12); // Calls fib(11) and fib(10) &lt;- memoized!!

This way calling for the Fibonacci Sequence on any number, speeds up other calls.</description>
		<content:encoded><![CDATA[<p>Very slick trick!</p>
<p>One thing that you didn&#8217;t point out in your last example.<br />
Because you overridden the original function, and the fib function calls its self; you will get pre-memoized values.</p>
<p>Example:<br />
var fib = memo(fib);<br />
fib(10); // Calls fib(9) and fib(8) and fib(7) and fib(6) and &#8230;<br />
fib(12); // Calls fib(11) and fib(10) &lt;- memoized!!</p>
<p>This way calling for the Fibonacci Sequence on any number, speeds up other calls.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben Newman</title>
		<link>http://blog.thejit.org/2008/09/05/memoization-in-javascript/comment-page-1/#comment-217</link>
		<dc:creator>Ben Newman</dc:creator>
		<pubDate>Sat, 06 Sep 2008 01:06:42 +0000</pubDate>
		<guid isPermaLink="false">http://blog.thejit.org/?p=27#comment-217</guid>
		<description>Excellent demonstration of the power of JavaScript!  Few things I noticed...

Why not store the memo object in the closure of the anonymous function?  That way it&#039;s safe from modification by other code.

You might still want to cache the memoized version of the function, since it doesn&#039;t make sense to memoize a function more than once.

When you use the args array as an object property, it just gets converted into a string again, so you can avoid an extra step by joining the arguments instead of slicing/stringifying them.

&lt;code&gt;
function memo(f) {  
    if (f.memo)  
        return f.memo;  
    var cache = {}, join = Array.prototype.join;  
    return (f.memo = function() {  
        var key = join.call(arguments);  
        return (key in cache)  
            ? cache[key]  
            : cache[key] = f.apply(this, arguments);  
    });  
}
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>Excellent demonstration of the power of JavaScript!  Few things I noticed&#8230;</p>
<p>Why not store the memo object in the closure of the anonymous function?  That way it&#8217;s safe from modification by other code.</p>
<p>You might still want to cache the memoized version of the function, since it doesn&#8217;t make sense to memoize a function more than once.</p>
<p>When you use the args array as an object property, it just gets converted into a string again, so you can avoid an extra step by joining the arguments instead of slicing/stringifying them.</p>
<p><code><br />
function memo(f) {<br />
    if (f.memo)<br />
        return f.memo;<br />
    var cache = {}, join = Array.prototype.join;<br />
    return (f.memo = function() {<br />
        var key = join.call(arguments);<br />
        return (key in cache)<br />
            ? cache[key]<br />
            : cache[key] = f.apply(this, arguments);<br />
    });<br />
}<br />
</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nicolas Garcia Belmonte</title>
		<link>http://blog.thejit.org/2008/09/05/memoization-in-javascript/comment-page-1/#comment-216</link>
		<dc:creator>Nicolas Garcia Belmonte</dc:creator>
		<pubDate>Sat, 06 Sep 2008 00:06:05 +0000</pubDate>
		<guid isPermaLink="false">http://blog.thejit.org/?p=27#comment-216</guid>
		<description>Indeed, thanks for the tip :) .</description>
		<content:encoded><![CDATA[<p>Indeed, thanks for the tip <img src='http://blog.thejit.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Geoff</title>
		<link>http://blog.thejit.org/2008/09/05/memoization-in-javascript/comment-page-1/#comment-215</link>
		<dc:creator>Geoff</dc:creator>
		<pubDate>Sat, 06 Sep 2008 00:00:02 +0000</pubDate>
		<guid isPermaLink="false">http://blog.thejit.org/?p=27#comment-215</guid>
		<description>Would it be possible to make a slight rearrangement to move the definition of f.memo out of the anonymous function:

function memo(f) {  
  f.memo = f.memo &#124;&#124; {};  
  return function (x) {  
      return (x in f.memo)? f.memo[x] : f.memo[x] = f(x);  
  };  
}</description>
		<content:encoded><![CDATA[<p>Would it be possible to make a slight rearrangement to move the definition of f.memo out of the anonymous function:</p>
<p>function memo(f) {<br />
  f.memo = f.memo || {};<br />
  return function (x) {<br />
      return (x in f.memo)? f.memo[x] : f.memo[x] = f(x);<br />
  };<br />
}</p>
]]></content:encoded>
	</item>
</channel>
</rss>
