Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to normalize Perl function arguments for memoization?
    primarykey
    data
    text
    <p>How can I normalize a list of function arguments to a string, such that two argument lists convert to the same string iff they are effectively equivalent? The algorithm should</p> <ol> <li>Compare embedded hashes and lists deeply, rather than by reference</li> <li>Ignore hash key order</li> <li>Ignore difference between 3 and "3"</li> <li>Generate a relatively readable string (not required, but nice-to-have for debugging)</li> <li>Perform well (XS preferred over Perl)</li> </ol> <p>This is necessary for <a href="http://en.wikipedia.org/wiki/Memoization" rel="noreferrer">memoization</a>, i.e. caching the result of the function based on its arguments.</p> <p>As a strawman example, <a href="http://search.cpan.org/perldoc?Memoize" rel="noreferrer">Memoize</a> uses this as a default normalizer, which fails #1 and #3:</p> <pre><code>$argstr = join chr(28),@_; </code></pre> <p>For a while my go-to normalizer was</p> <pre><code>JSON::XS-&gt;new-&gt;utf8-&gt;canonical </code></pre> <p>However it treats the number 3 and the string "3" <a href="http://search.cpan.org/perldoc?JSON::XS#PERL_-%3E_JSON" rel="noreferrer">differently</a>, based on how the scalar was used recently. This can generate different strings for essentially equivalent argument lists and reduce the memoization benefit. (The vast majority of functions won't know or care if they get 3 or "3".)</p> <p>For fun I looked at a bunch of serializers to see which ones differentiate 3 and "3":</p> <pre><code>Data::Dump : equal - [3] vs [3] Data::Dumper : not equal - [3] vs ['3'] FreezeThaw : equal - FrT;@1|@1|$1|3 vs FrT;@1|@1|$1|3 JSON::PP : not equal - [3] vs ["3"] JSON::XS : not equal - [3] vs ["3"] Storable : not equal - &lt;unprintable&gt; YAML : equal - ---\n- 3\n vs ---\n- 3\n YAML::Syck : equal - --- \n- 3\n vs --- \n- 3\n YAML::XS : not equal - ---\n- 3\n vs ---\n- '3'\n </code></pre> <p>Of the ones that report "equal", not sure how to get them to ignore hash key order.</p> <p>I could walk the argument list beforehand and stringify all numbers, but this would require making a deep copy and would violate #5.</p> <p>Thanks!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload