{"id":2018,"date":"2019-03-30T12:40:45","date_gmt":"2019-03-30T12:40:45","guid":{"rendered":"http:\/\/dlang.org\/blog\/?p=2018"},"modified":"2021-09-30T13:39:55","modified_gmt":"2021-09-30T13:39:55","slug":"memoization-in-the-d-programming-language","status":"publish","type":"post","link":"https:\/\/dlang.org\/blog\/2019\/03\/30\/memoization-in-the-d-programming-language\/","title":{"rendered":"Memoization in the D Programming Language"},"content":{"rendered":"<p><img loading=\"lazy\" class=\"alignleft size-full wp-image-2025\" src=\"http:\/\/dlang.org\/blog\/wp-content\/uploads\/2019\/03\/brain02.png\" alt=\"\" width=\"200\" height=\"200\" \/>The D programming language provides advanced facilities for structuring programs logically, almost like Python or Ruby, but with high performance and the higher reliability of static typing and contract programming.<\/p>\n<p>In this article, I will describe how to use D templates and mixins for <em>memoization<\/em>, that is, to automatically remember a function (or property) result.<\/p>\n<h3 id=\"std.functional.memoizefromthestandardlibrary\"><code>std.functional.memoize<\/code> from the standard library<\/h3>\n<p>The first way is built straight into <a href=\"https:\/\/dlang.org\/phobos\/index.html\">Phobos, the D standard library<\/a>, and is very easy to use:<\/p>\n<pre class=\"prettyprint lang-d\">import std.functional;\r\nimport std.stdio;\r\n\r\nfloat doCalculations() {\r\n    writeln(\"Doing calculations.\");\r\n    return -1.7; \/\/ the value of the calculations\r\n}\r\n\r\n\/\/ Apply the template \u201cmemoize\u201d to the function doCalculations():\r\nalias doCalculationsOnce = memoize!doCalculations;<\/pre>\n<p>Now the alias <code>doCalculationsOnce()<\/code> does the same as <code>doCalculations()<\/code>, but the calculations are done only once (if we call <code>doCalculationsOnce()<\/code> then \u201cDoing calculations.\u201d would be printed only once). This is useful for long slow calculations and in some other situations (like to create only a single window on the screen). That is memoization.<\/p>\n<p>It\u2019s even possible to memoize a function with arguments:<\/p>\n<pre class=\"prettyprint lang-d\">float doCalculations2(float arg1, float arg2) {\r\n    writeln(\"Doing calculations.\");\r\n    return arg1 + arg2; \/\/ the value of the calculations\r\n}\r\n\r\n\/\/ Apply the template \u201cmemoize\u201d to the function  doCalculations2():\r\nalias doCalculationsOnce2 = memoize!doCalculations2;\r\n\r\nvoid main(string[] args)\r\n{\r\n    writeln(doCalculationsOnce2(1.0, 1.2));\r\n    writeln(doCalculationsOnce2(1.0, 1.3));\r\n    writeln(doCalculationsOnce2(1.0, 1.3));\r\n}<\/pre>\n<p>This outputs:<\/p>\n<pre>Doing calculations.\r\n2.2\r\nDoing calculations.\r\n2.3\r\n2.3<\/pre>\n<p>You see that the calculations are not repeated again when the argument values are the same.<\/p>\n<h3 id=\"memoizingstructorclassproperties\">Memoizing <code>struct<\/code> or <code>class<\/code> properties<\/h3>\n<p>I\u2019ve found another way to memoize in D. It involves caching a <em>property<\/em> of a <code>struct<\/code> or <code>class<\/code>. Properties are zero-argument (for reading) or one-argument (for writing) member functions (or sometimes two-argument non-member functions) and differ only in syntax. I deemed it more elegant to cache a property of a struct or class rather than to cache a member function\u2019s return value. My code can easily be changed to memoize a member function instead of a property, but you can always convert zero-argument member functions into a property, so why bother?<\/p>\n<p>Here is the source (you can also install it from <a href=\"https:\/\/github.com\/vporton\/memoize-dlang\">https:\/\/github.com\/vporton\/memoize-dlang<\/a> for use in your programs):<\/p>\n<pre class=\"prettyprint lang-d\">module memoize;\r\n\r\nmixin template CachedProperty(string name, string baseName = '_' ~ name) {\r\n    mixin(\"private typeof(\" ~ baseName ~ \") \" ~ name ~ \"Cache;\");\r\n    mixin(\"private bool \" ~ name ~ \"IsCached = false;\");\r\n    mixin(\"@property typeof(\" ~ baseName ~ \") \" ~ name ~ \"() {\\n\" ~\r\n          \"if (\" ~ name ~ \"IsCached\" ~ \") return \" ~ name ~ \"Cache;\\n\" ~\r\n          name ~ \"IsCached = true;\\n\" ~\r\n          \"return \" ~ name ~ \"Cache = \" ~ baseName ~ \";\\n\" ~\r\n          '}');\r\n}<\/pre>\n<p>It is used like this (with either structs or classes at your choice):<\/p>\n<pre class=\"prettyprint lang-d\">import memoize;\r\n\r\nstruct S {\r\n    @property float _x() { return 1.5; }\r\n    mixin CachedProperty!\"x\";\r\n}<\/pre>\n<p>Then just:<\/p>\n<pre class=\"prettyprint lang-d\">S s;\r\nassert(s.x == 1.5);<\/pre>\n<p>Or you can specify the explicit name of the cached property:<\/p>\n<pre class=\"prettyprint lang-d\">import memoize;\r\n\r\nstruct S {\r\n    @property float _x() { return 1.5; }\r\n    mixin CachedProperty!(\"x\", \"_x\");\r\n}<\/pre>\n<p><code>CachedProperty<\/code> is <a href=\"https:\/\/dlang.org\/spec\/template-mixin.html\">a template mixin<\/a>. Template mixins insert the declarations of the template body directly into the current context. In this case, the template body is composed <a href=\"https:\/\/tour.dlang.org\/tour\/en\/gems\/string-mixins\">of string mixins<\/a>. As you can guess, a string mixin generates code at compile time from strings. So,<\/p>\n<pre class=\"prettyprint lang-d\">struct S {\r\n    @property float _x() { return 1.5; }\r\n    mixin CachedProperty!\"x\";\r\n}<\/pre>\n<p>turns into<\/p>\n<pre class=\"prettyprint lang-d\">struct S {\r\n    @property float _x() { return 1.5; }\r\n    private typeof(_x) xCache;\r\n    private bool xIsCached = false;\r\n    @property typeof(_x) x() {\r\n        if (xIsCached) return xCache;\r\n        xIsCached = true;\r\n        return xCache = _x;\r\n    }\r\n}<\/pre>\n<p>That is, it sets <code>xCache<\/code> to <code>_x<\/code> unless <code>xIsCached<\/code> and also sets <code>xIsCached<\/code> to <code>true<\/code> when retrieving <code>x<\/code>.<\/p>\n<p>The idea originates from the following Python code:<\/p>\n<pre class=\"prettyprint lang-python\">class cached_property(object):\r\n    \"\"\"A version of @property which caches the value.  On access, it calls the\r\n    underlying function and sets the value in `__dict__` so future accesses\r\n    will not re-call the property.\r\n    \"\"\"\r\n    def __init__(self, f):\r\n        self._fname = f.__name__\r\n        self._f = f\r\n\r\n    def __get__(self, obj, owner):\r\n        assert obj is not None, 'call {} on an instance'.format(self._fname)\r\n        ret = obj.__dict__[self._fname] = self._f(obj)\r\n        return ret<\/pre>\n<p>My way of memoization does not (yet) involve caching return values of functions with arguments.<\/p>\n<hr \/>\n<p><em>Victor Porton is an open source developer, a math researcher, and a Christian writer. He earns his living as a programmer.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The D programming language provides advanced facilities for structuring programs logically, almost like Python or Ruby, but with high performance and the higher reliability of static typing and contract programming. In this article, I will describe how to use D templates and mixins for memoization, that is, to automatically remember a function (or property) result. [&hellip;]<\/p>\n","protected":false},"author":32,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[26,9],"tags":[],"_links":{"self":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/2018"}],"collection":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/users\/32"}],"replies":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/comments?post=2018"}],"version-history":[{"count":3,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/2018\/revisions"}],"predecessor-version":[{"id":2026,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/2018\/revisions\/2026"}],"wp:attachment":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/media?parent=2018"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/categories?post=2018"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/tags?post=2018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}