{"id":122,"date":"2008-01-16T17:00:02","date_gmt":"2008-01-16T22:00:02","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/2008\/01\/16\/nested-functions-and-variable-scope\/"},"modified":"2015-03-09T16:34:38","modified_gmt":"2015-03-09T21:34:38","slug":"nested-functions-and-variable-scope","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2008\/01\/16\/nested-functions-and-variable-scope\/","title":{"rendered":"Nested Functions and Variable Scope"},"content":{"rendered":"<div class=\"content\">\r\n\r\nI get a parade of questions about which variables are available to nested functions and which variables, used in nested functions,\r\nare part of the nesting function workspace. So today I thought I'd address this topic. For more information, you can read\r\n<a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/nested-functions.html\">this documentation<\/a>.\r\n\r\n&nbsp;\r\n<h3>Contents<\/h3>\r\n<div>\r\n<ul>\r\n\t<li><a href=\"#1\">Where is data?<\/a><\/li>\r\n\t<li><a href=\"#8\">Truisms about Variable Scope with Nested Functions<\/a><\/li>\r\n\t<li><a href=\"#9\">Your Thoughts?<\/a><\/li>\r\n<\/ul>\r\n<\/div>\r\n<h3>Where is data?<a name=\"1\"><\/a><\/h3>\r\nLet's take a look at the following code.\r\n<pre>function blahblah\r\n% BLAHBLAH help line<\/pre>\r\n<tt><i>data<\/i> = 1;<\/tt>\r\n<pre>data2 = yoyo1();\r\nyoyo2(3);<\/pre>\r\n<pre>   function data = yoyo1()\r\n       % Note that data is an output here\r\n       data = 2\r\n   end\r\n   function yoyo2(in)\r\n      % Here, data is shared with the variable 'data'\r\n      % in blahblah's workspace<\/pre>\r\n<code><em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data<\/em> = in;<\/code>\r\n<pre>  end\r\nend<\/pre>\r\nYou can see that there is the variable, in each function, named <tt>data<\/tt>. The question is, however, do they all refer to the same entity? And the answer is 'no.' Surprised? Let me explain. <tt>yoyo1<\/tt> essentially declares <tt>data<\/tt> to be a local variable and not shared because of <tt>data<\/tt>'s presence on the output argument list. The same would be true if <tt>data<\/tt> showed up on the input argument list instead, or if it showed up on both. However, <tt>yoyo2<\/tt>, which has no mention of <tt>data<\/tt> in its arguments lists, shared the variable <tt>data<\/tt> that is in <tt>blahblah<\/tt>'s workspace. So calling <tt>yoyo2<\/tt> changes the value of <tt>data<\/tt> in <tt>blahblah<\/tt> but calling <tt>yoyo1<\/tt> does not.\r\n<h3>Truisms about Variable Scope with Nested Functions<a name=\"8\"><\/a><\/h3>\r\n<ul>\r\n\t<li>When you call an M-file containing a nested function, sufficient analysis is done on the M-file to determine which variables\r\nare shared and which functions share them.<\/li>\r\n\t<li>If a variable is in a nested function and appears in at least one of input or output argument lists for that function, then,\r\neven if it's name matches a name in the nesting function's workspace, the two variables refer to different entities. This\r\nis true <i>even if other nested functions share the variable in the nesting function<\/i>.<\/li>\r\n\t<li>For a variable in a nested function to be shared with the nesting function, the variable must appear in the code of (i.e.,\r\nbe referred to or used in) nesting function. This is true even if you don't need to use the variable in the nesting function\r\nbut want multiple nested functions to share the variable.<\/li>\r\n\t<li>You can't <i>poof<\/i> variables into nested function workspace. If need to do some debugging and want to create new variables, you can declare\r\nthem global and then assign to them. For more detail, read the documentation about <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/nested-functions.html\">Restrictions on Assigning to Variables<\/a>.<\/li>\r\n<\/ul>\r\n<h3>Your Thoughts?<a name=\"9\"><\/a><\/h3>\r\nIn the code I showed, I made sure to highlight the variables that are shared by printing them in italic. Especially for those\r\nof you who do not care for the implementation we chose for nested functions, would some visual affordance such as this make\r\nthe situation more tenable for you? Let me know <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=122#respond\">here<\/a>.\r\n\r\n<script language=\"JavaScript\">\/\/ <![CDATA[\r\n\r\n\r\n    function grabCode_de760514cfdc4cb497ed7cb1b93d5631() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='de760514cfdc4cb497ed7cb1b93d5631 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' de760514cfdc4cb497ed7cb1b93d5631';\r\n\r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n\r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        author = 'Loren Shure';\r\n        copyright = 'Copyright 2008 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('\r\n\r\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\r\n\r\n\r\n\\n');\r\n\r\n      d.title = title + ' (MATLAB code)';\r\n      d.close();\r\n      }   \r\n\r\n\/\/ ]]><\/script>\r\n<p style=\"text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;\"><a><span style=\"font-size: x-small; font-style: italic;\">Get\r\nthe MATLAB code\r\n<noscript>(requires JavaScript)<\/noscript><\/span><\/a><\/p>\r\nPublished with MATLAB\u00ae 7.5\r\n\r\n<\/div>\r\n<!--\r\nde760514cfdc4cb497ed7cb1b93d5631 ##### SOURCE BEGIN #####\r\n%% Nested Functions and Variable Scope\r\n% I get a parade of questions about which variables are available to nested\r\n% functions and which variables, used in nested functions, are part of the\r\n% nesting function workspace.  So today I thought I'd address this topic.\r\n% For more information, you can read\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/nested-functions.html#f4-73993 this documentation>.\r\n%% Where is data?\r\n% Let's take a look at the following code.\r\n%%\r\n%  function blahblah\r\n%  % BLAHBLAH help line\r\n%%\r\n% |_data_ = 1;|\r\n%%\r\n%  data2 = yoyo1();\r\n%  yoyo2(3);\r\n%\r\n%     function data = yoyo1()\r\n%         % Note that data is an output here\r\n%         data = 2\r\n%     end\r\n%     function yoyo2(in)\r\n%        % Here, data is shared with the variable 'data'\r\n%        % in blahblah's workspace\r\n%%\r\n% <html>\r\n% <code><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data<\/em> = in;<\/code>\r\n% <\/html>\r\n%\r\n%%\r\n%    end\r\n%  end\r\n%%\r\n% You can see that there is the variable, in each function, named |data|.\r\n% The question is, however, do they all refer to the same entity?  And the\r\n% answer is 'no.'  Surprised?  Let me explain. |yoyo1| essentially declares\r\n% |data| to be a local variable and not shared because of |data|'s presence\r\n% on the output argument list.  The same would be true if |data| showed up\r\n% on the input argument list instead, or if it showed up on both.  However,\r\n% |yoyo2|, which has no mention of |data| in its arguments lists, shared\r\n% the variable |data| that is in |blahblah|'s workspace.  So calling\r\n% |yoyo2| changes the value of |data| in |blahblah| but calling |yoyo1|\r\n% does not.\r\n\r\n%% Truisms about Variable Scope with Nested Functions\r\n%\r\n% # When you call an M-file containing a nested function, sufficient\r\n% analysis is done on the M-file to determine which variables are shared\r\n% and which functions share them.\r\n% # If a variable is in a nested function and appears in at least one of\r\n% input or output argument lists for that function, then, even if it's name\r\n% matches a name in the nesting function's workspace, the two variables\r\n% refer to different entities. This is true _even if other nested functions\r\n% share the variable in the nesting function_.\r\n% # For a variable in a nested function to be shared with the nesting\r\n% function, the variable must appear in the code of (i.e., be referred to\r\n% or used in) nesting function.  This is true even if you don't need to use\r\n% the variable in the nesting function but want multiple nested functions\r\n% to share the variable.\r\n% # You can't _poof_ variables into nested function workspace.  If need to\r\n% do some debugging and want to create new variables, you can declare them\r\n% global and then assign to them.  For more detail, read the documentation\r\n% about\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/matlab_prog\/nested-functions.html#f4-75258 Restrictions on Assigning to Variables>.\r\n%% Your Thoughts?\r\n% In the code I showed, I made sure to highlight the variables that are\r\n% shared by printing them in italic.  Especially for those of you who do\r\n% not care for the implementation we chose for nested functions, would some\r\n% visual affordance such as this make the situation more tenable for you?\r\n% Let me know <https:\/\/blogs.mathworks.com\/loren\/?p=122#respond here>.\r\n%\r\n%\r\n\r\n##### SOURCE END ##### de760514cfdc4cb497ed7cb1b93d5631\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n\r\nI get a parade of questions about which variables are available to nested functions and which variables, used in nested functions,\r\nare part of the nesting function workspace. So today I thought... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2008\/01\/16\/nested-functions-and-variable-scope\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[14,8],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/122"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=122"}],"version-history":[{"count":7,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/122\/revisions"}],"predecessor-version":[{"id":1148,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/122\/revisions\/1148"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}