{"id":379,"date":"2022-08-10T21:53:50","date_gmt":"2022-08-10T21:53:50","guid":{"rendered":"https:\/\/baldsolutions.com\/?p=379"},"modified":"2022-08-10T21:59:54","modified_gmt":"2022-08-10T21:59:54","slug":"tail-call-optimization-avoid-stackvverflow","status":"publish","type":"post","link":"https:\/\/baldsolutions.com\/index.php\/2022\/08\/10\/tail-call-optimization-avoid-stackvverflow\/","title":{"rendered":"Tail call optimization &#8211; avoid StackOverflow"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p>What is the easies way to cause the <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.stackoverflowexception?view=net-6.0\" target=\"_blank\" rel=\"noreferrer noopener\">Stack<wbr style=\"color: rgb(23, 23, 23); font-family: &quot;Segoe UI&quot;, SegoeUI, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: max(1.875rem, min(22.1053px + 1.64474vw, 2.5rem)); font-weight: 600; white-space: normal; box-sizing: inherit; outline-color: inherit;\">Overflow<wbr style=\"color: rgb(23, 23, 23); font-family: &quot;Segoe UI&quot;, SegoeUI, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: max(1.875rem, min(22.1053px + 1.64474vw, 2.5rem)); font-weight: 600; white-space: normal; box-sizing: inherit; outline-color: inherit;\">Exception<\/a>? If you are familiar with recursion the answer is pretty straightforward &#8211; recursion. According to the <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.stackoverflowexception?view=net-6.0\" target=\"_blank\" rel=\"noreferrer noopener\">documentation <\/a>&#8220;Starting with the .NET Framework 2.0, you can&#8217;t catch a&nbsp;StackOverflowException&nbsp;object with a&nbsp;try\/catch&nbsp;block, and the corresponding process is terminated by default&#8221;. <\/p>\n\n\n\n<p>Neither me nor you want to come across such a problem. Some languages offers &#8220;tail call optimization&#8221; &#8211; optimization that can help to avoid the <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.stackoverflowexception?view=net-6.0\" target=\"_blank\" rel=\"noreferrer noopener\">Stack<wbr style=\"color: rgb(23, 23, 23); font-family: &quot;Segoe UI&quot;, SegoeUI, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: max(1.875rem, min(22.1053px + 1.64474vw, 2.5rem)); font-weight: 600; white-space: normal; box-sizing: inherit; outline-color: inherit;\">Overflow<wbr style=\"color: rgb(23, 23, 23); font-family: &quot;Segoe UI&quot;, SegoeUI, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: max(1.875rem, min(22.1053px + 1.64474vw, 2.5rem)); font-weight: 600; white-space: normal; box-sizing: inherit; outline-color: inherit;\">Exception<\/a>. <\/p>\n\n\n\n<p>The main question is what the tail call optimization is and why it is so powerful?<\/p>\n\n\n\n<p>Let&#8217;s find out!<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Tail call<\/h1>\n\n\n\n<p>First of all, let&#8217;s clarify what the &#8220;tail call&#8221; is. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tail_call\" target=\"_blank\" rel=\"noreferrer noopener\">Wikipedia<\/a> seems to be right place to start the research. We can find there that &#8220;a&nbsp;tail call&nbsp;is a&nbsp;subroutine&nbsp;call performed as the final action of a procedure.&#8221;. <\/p>\n\n\n\n<p>Let&#8217;s consider following F# code snippets:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>module StandardRecursion =\n    let rec factorial x =\n        if x &lt; 1 then 1\n        else x * factorial (x-1)\n\nmodule TailRecursion =    \n    let factorial x = \n       let rec factorial2 x acc =\n            if x = 0 then acc\n            else factorial2 (x-1) (acc * x)\n       factorial2 x 1<\/code><\/pre>\n\n\n\n<p>There are two implementations of the factorial &#8211; first one uses standard recursion whereas second one uses tail recursion. Both functions do the same &#8211; compute the factorial of given argument. <\/p>\n\n\n\n<p>Now let&#8217;s assume that for some unknown reason we want to run the following invocations:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    StandardRecursion.factorial 6000000\n    TailRecursion.factorial 6000000<\/code><\/pre>\n\n\n\n<p>What will happen?<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"398\" src=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2022\/08\/image-edited.png\" alt=\"\" class=\"wp-image-409\" srcset=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2022\/08\/image-edited.png 790w, https:\/\/baldsolutions.com\/wp-content\/uploads\/2022\/08\/image-edited-300x151.png 300w, https:\/\/baldsolutions.com\/wp-content\/uploads\/2022\/08\/image-edited-768x387.png 768w\" sizes=\"auto, (max-width: 790px) 100vw, 790px\" \/><\/figure>\n\n\n\n<p>And there we go, the EXCEPTION.  So, the whole application terminated and we are all happy (just kidding &#8211; we prefer when it&#8217;s running&#8230;).<\/p>\n\n\n\n<p>Now let&#8217;s run the latter invocation and see what will happen&#8230; Ok, I didn&#8217;t put a screenshot here because the application didn&#8217;t crash! Surprised? <\/p>\n\n\n\n<p>There is an explanation why the latter implementation of the factorial didn&#8217;t crash &#8211; tail call optimization.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Tail call optimization<\/h1>\n\n\n\n<p>The optimization is mentioned on the tail call <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tail_call\" target=\"_blank\" rel=\"noreferrer noopener\">Wikipedia<\/a> page. At the very bottom of the page you can find that not all languages support it, hence don&#8217;t be surprised if your tail recursion crashes an application. <\/p>\n\n\n\n<p>Regarding F# and the tail call optimization there is a simple and clear <a href=\"https:\/\/en.wikibooks.org\/wiki\/F_Sharp_Programming\/Recursion\" target=\"_blank\" rel=\"noreferrer noopener\">explanation<\/a> of the optimization process : <\/p>\n\n\n\n<p>&#8220;A&nbsp;<em>tail recursive<\/em>&nbsp;function is a special case of recursion in which the last instruction executed in the method is the recursive call. F# and many other functional languages can optimize tail recursive functions; since no extra work is performed after the recursive call, there is no need for the function to remember where it came from, and hence no reason to allocate additional memory on the stack.<\/p>\n\n\n\n<p>F# optimizes tail-recursive functions by telling the CLR to drop the current stack frame before executing the target function. As a result, tail-recursive functions can recurse indefinitely without consuming stack space.&#8221;<\/p>\n\n\n\n<p>To get better insights let&#8217;s look at the F# -&gt; C# decomplication on <a href=\"https:\/\/sharplab.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">sharplab.io<\/a>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"961\" height=\"857\" src=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2022\/08\/image-1.png\" alt=\"\" class=\"wp-image-394\" srcset=\"https:\/\/baldsolutions.com\/wp-content\/uploads\/2022\/08\/image-1.png 961w, https:\/\/baldsolutions.com\/wp-content\/uploads\/2022\/08\/image-1-300x268.png 300w, https:\/\/baldsolutions.com\/wp-content\/uploads\/2022\/08\/image-1-768x685.png 768w\" sizes=\"auto, (max-width: 961px) 100vw, 961px\" \/><\/figure>\n\n\n\n<p>As you can see the tail recursion implementation has been decompiled into a &#8220;while&#8221; loop whereas the standard recursion looks the same.  Such a &#8220;while&#8221; loop is nowhere near as disastrous as the recursion in terms of <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.stackoverflowexception?view=net-6.0\" target=\"_blank\" rel=\"noreferrer noopener\">Stack<wbr style=\"color: rgb(23, 23, 23); font-family: &quot;Segoe UI&quot;, SegoeUI, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: max(1.875rem, min(22.1053px + 1.64474vw, 2.5rem)); font-weight: 600; white-space: normal; box-sizing: inherit; outline-color: inherit;\">Overflow<wbr style=\"color: rgb(23, 23, 23); font-family: &quot;Segoe UI&quot;, SegoeUI, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: max(1.875rem, min(22.1053px + 1.64474vw, 2.5rem)); font-weight: 600; white-space: normal; box-sizing: inherit; outline-color: inherit;\">Exception<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Summary<\/h1>\n\n\n\n<p>To sum up, tail call optimization is a powerful technique that compilers use to reduce the stack usage . However, not all languages support the optimization so it is worth to read the documentation first rather than kill the application by accident. <\/p>\n\n\n\n<p>As always I&#8217;ve prepared an example and you can find it on my <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/master\/.NET\" target=\"_blank\" rel=\"noreferrer noopener\">github<\/a>, project: <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/master\/.NET\/tail-call-csharp\" target=\"_blank\" rel=\"noreferrer noopener\">tail-call-csharp<\/a> and <a href=\"https:\/\/github.com\/tglowka\/baldsolutions\/tree\/master\/.NET\/tail-call-fsharp\" target=\"_blank\" rel=\"noreferrer noopener\">tail-call-fsharp<\/a>. The example consists of F# code and C# code. I haven&#8217;t mentioned the C# in this post but it turns out it doesn&#8217;t offer as much as F# in terms of tail call optimization. I figured out that for target platform x86 the JIT ASM looks like it doesn&#8217;t optimize whereas for target platform x64 the JIT ASM looks like it does. However, I haven&#8217;t checked that in details yet. I encourage to get the C# code and put it on the <a href=\"https:\/\/sharplab.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">sharplab.io<\/a>!<\/p>\n\n\n\n<p>Have a nice day, bye!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction What is the easies way to cause the StackOverflowException? If you are familiar with recursion the answer is pretty straightforward &#8211; recursion. According to&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/baldsolutions.com\/index.php\/2022\/08\/10\/tail-call-optimization-avoid-stackvverflow\/\">Continue reading<span class=\"screen-reader-text\">Tail call optimization &#8211; avoid StackOverflow<\/span><\/a><\/div>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[2,4],"tags":[],"class_list":["post-379","post","type-post","status-publish","format-standard","hentry","category-net","category-f","entry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/379","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/comments?post=379"}],"version-history":[{"count":28,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/379\/revisions"}],"predecessor-version":[{"id":411,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/posts\/379\/revisions\/411"}],"wp:attachment":[{"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/media?parent=379"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/categories?post=379"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/baldsolutions.com\/index.php\/wp-json\/wp\/v2\/tags?post=379"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}