Quantcast

Expected behavior for variables which shadow function names

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Expected behavior for variables which shadow function names

Rik-4
3/7/13

All,

I ran across an odd behavior and I wanted to know what other people thought
was "correct".

For the following function:

function y = tstflag (flag)
  y = flag;
endfunction

When called with any argument it behaves as expected.

x = tstflag (1)
x =  1
x = tstflag ([])
x = [](0x0)

When called with no arguments, however, the return value is expanded to the
output of the flag() function which is a 64x3 matrix.

x = tstflag ()
x =

   1   0   0
   1   1   1
   0   0   1
   0   0   0
   ...

I understand what is happening, either the flag() function is shadowed by
the local variable or it isn't, but I wonder what Matlab does for this
corner case?  I naively assumed that no input would be similar to a null
input ([]).  I can always get around this by assigning a default value to
flag in the function header.


--Rik

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Expected behavior for variables which shadow function names

Daniel Sebald
On 03/07/2013 12:18 PM, Rik wrote:

> 3/7/13
>
> All,
>
> I ran across an odd behavior and I wanted to know what other people thought
> was "correct".
>
> For the following function:
>
> function y = tstflag (flag)
>    y = flag;
> endfunction
>
> When called with any argument it behaves as expected.
>
> x = tstflag (1)
> x =  1
> x = tstflag ([])
> x = [](0x0)
>
> When called with no arguments, however, the return value is expanded to the
> output of the flag() function which is a 64x3 matrix.
>
> x = tstflag ()
> x =
>
>     1   0   0
>     1   1   1
>     0   0   1
>     0   0   0
>     ...
>
> I understand what is happening, either the flag() function is shadowed by
> the local variable or it isn't, but I wonder what Matlab does for this
> corner case?  I naively assumed that no input would be similar to a null
> input ([]).  I can always get around this by assigning a default value to
> flag in the function header.

I would make the same assumption.  This is potentially problematic and,
at minimum, confusing to someone not paying real close attention.  I
suppose this is all avoided if one programs the script file to check the
number of input arguments.  However, as you've shown it can lead to
unexpected results for valid routines not much more complex than the
example you gave.

It seems to me the proper behavior for tstflag() would be to issue an
error message similar to the following where I've change the variable
reference to "flig" instead of "flag":

octave:10> x = tstflag()
error: `flig' undefined near line 3 column 7
error: called from:
error:   /home/sebaldd/octave/tstflag.m at line 3, column 5

Dan
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Expected behavior for variables which shadow function names

John W. Eaton
Administrator
In reply to this post by Rik-4
On 03/07/2013 01:18 PM, Rik wrote:

> 3/7/13
>
> All,
>
> I ran across an odd behavior and I wanted to know what other people thought
> was "correct".
>
> For the following function:
>
> function y = tstflag (flag)
>    y = flag;
> endfunction
>
> When called with any argument it behaves as expected.
>
> x = tstflag (1)
> x =  1
> x = tstflag ([])
> x = [](0x0)
>
> When called with no arguments, however, the return value is expanded to the
> output of the flag() function which is a 64x3 matrix.
>
> x = tstflag ()
> x =
>
>     1   0   0
>     1   1   1
>     0   0   1
>     0   0   0
>     ...
>
> I understand what is happening, either the flag() function is shadowed by
> the local variable or it isn't, but I wonder what Matlab does for this
> corner case?  I naively assumed that no input would be similar to a null
> input ([]).  I can always get around this by assigning a default value to
> flag in the function header.

I think that in the olden times, Matlab behaved the same was as Octave
in this case.  But now, Matlab does more checking to ensure that you are
not using symbols as both variables and functions within the same scope,
or that you are not trying to reuse a cleared variable as a function,
etc.  I think the newer behavior is better.  Maybe we should fix Octave
to perform similar checks now that compatibility with the old and
relatively confusing behavior is no longer an issue for us.

jwe


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Expected behavior for variables which shadow function names

Rik-4
On 03/07/2013 10:55 AM, John W. Eaton wrote:

> On 03/07/2013 01:18 PM, Rik wrote:
>> 3/7/13
>>
>> All,
>>
>> I ran across an odd behavior and I wanted to know what other people thought
>> was "correct".
>>
>> For the following function:
>>
>> function y = tstflag (flag)
>>    y = flag;
>> endfunction
>>
>> When called with any argument it behaves as expected.
>>
>> x = tstflag (1)
>> x =  1
>> x = tstflag ([])
>> x = [](0x0)
>>
>> When called with no arguments, however, the return value is expanded to the
>> output of the flag() function which is a 64x3 matrix.
>>
>> x = tstflag ()
>> x =
>>
>>     1   0   0
>>     1   1   1
>>     0   0   1
>>     0   0   0
>>     ...
>>
>> I understand what is happening, either the flag() function is shadowed by
>> the local variable or it isn't, but I wonder what Matlab does for this
>> corner case?  I naively assumed that no input would be similar to a null
>> input ([]).  I can always get around this by assigning a default value to
>> flag in the function header.
>
> I think that in the olden times, Matlab behaved the same was as Octave in
> this case.  But now, Matlab does more checking to ensure that you are not
> using symbols as both variables and functions within the same scope, or
> that you are not trying to reuse a cleared variable as a function, etc.
> I think the newer behavior is better.  Maybe we should fix Octave to
> perform similar checks now that compatibility with the old and relatively
> confusing behavior is no longer an issue for us.
John,

I would definitely prefer that.  Can someone verify on a recent version of
Matlab how this behaves?  If they have upgraded their behavior then we can too.

--Rik
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Expected behavior for variables which shadow function names

John W. Eaton
Administrator
On 03/07/2013 02:04 PM, Rik wrote:

> I would definitely prefer that.  Can someone verify on a recent version of
> Matlab how this behaves?  If they have upgraded their behavior then we can too.

Some things to test:

   function f (jet)
     jet
   end

   function f (jet)
     if (nargin == 0)
       jet
     elseif (nargin == 1)
       x = jet
     end
   end

call both with

   f (1)
   f (0)

Another:

   function f ()
     jet = 1;
     clear jet
     jet
   end

Not that it would be very hard to fix, but I hope there isn't any code
in Octave that actually depends on the current behavior...

jwe

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Expected behavior for variables which shadow function names

bpabbott
Administrator

On Mar 7, 2013, at 2:13 PM, John W. Eaton wrote:

> On 03/07/2013 02:04 PM, Rik wrote:
>
>> I would definitely prefer that.  Can someone verify on a recent version of
>> Matlab how this behaves?  If they have upgraded their behavior then we can too.
>
> Some things to test:
>
>  function f (jet)
>    jet
>  end
>
>  function f (jet)
>    if (nargin == 0)
>      jet
>    elseif (nargin == 1)
>      x = jet
>    end
>  end
>
> call both with
>
>  f (1)
>  f (0)
>
> Another:
>
>  function f ()
>    jet = 1;
>    clear jet
>    jet
>  end
>
> Not that it would be very hard to fix, but I hope there isn't any code in Octave that actually depends on the current behavior...
>
> jwe

I ran some examples.  I assume you intended f(0) to be f([]) or f()?

 function foo1 (jet)
   jet
 end

 function foo2 (jet)
   if (nargin == 0)
     jet
   elseif (nargin == 1)
     x = jet
   end
 end

 function foo3 ()
   jet = 1;
   clear jet
   jet
 end

matlab> foo1 (1)

jet =

     1

matlab> foo1 ([])

jet =

     []

matlab> foo1 ()
Error using foo1 (line 2)
Not enough input arguments.

matlab> foo2 (1)

x =

     1

matlab> foo2 ([])

x =

     []

matlab> foo2 ()
Error using foo2 (line 3)
Not enough input arguments.

matlab> foo3 ()
Reference to a cleared variable jet.

Error in foo3 (line 4)
  jet
 

Ben

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Expected behavior for variables which shadow function names

Julien Bect
In reply to this post by John W. Eaton
On 07/03/2013 20:13, John W. Eaton wrote:
> Some things to test:
>
>   function f (jet)
>     jet
>   end

Here is what I think the answer should be (based on my own Matlab user
experience) :

f() --> not enough input arguments
f(0) --> 0
f(1) --> 1

The fact that the symbol "jet" refers to a variable is determined IMO
when Matlab first parses the function. Therefore, even if nargin == 0,
jet is assumed to refer to a variable in the context of this function.


> function f (jet)
>     if (nargin == 0)
>       jet
>     elseif (nargin == 1)
>       x = jet
>     end
>   end

Same thing IMO, for the same reasons.


> function f ()
>     jet = 1;
>     clear jet
>     jet
>   end

I think this should generate an error : when the function is parsed,
Matlab determines that "jet" refers to a local variable in this function.

Therefore, the third line of code should generate an error since jet has
been cleared.

Best regards,

Julien.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Expected behavior for variables which shadow function names

Thorsten Liebig
Am 08.03.2013 10:13, schrieb Julien Bect:

> On 07/03/2013 20:13, John W. Eaton wrote:
>> Some things to test:
>>
>>   function f (jet)
>>     jet
>>   end
>
> Here is what I think the answer should be (based on my own Matlab user experience) :
>
> f() --> not enough input arguments
> f(0) --> 0
> f(1) --> 1
>
> The fact that the symbol "jet" refers to a variable is determined IMO when Matlab first parses the function. Therefore, even if nargin == 0, jet is
> assumed to refer to a variable in the context of this function.
>

I can confirm that with Matlab R2011a:

??? Input argument "jet" is undefined.

Error in ==> f at 2
    jet

>
>> function f (jet)
>>     if (nargin == 0)
>>       jet
>>     elseif (nargin == 1)
>>       x = jet
>>     end
>>   end
>
> Same thing IMO, for the same reasons.

Yes.

>
>
>> function f ()
>>     jet = 1;
>>     clear jet
>>     jet
>>   end
>
> I think this should generate an error : when the function is parsed, Matlab determines that "jet" refers to a local variable in this function.
>
> Therefore, the third line of code should generate an error since jet has been cleared.

Yes, the error is:

??? Reference to a cleared variable jet.

Error in ==> f at 4
    jet

>
> Best regards,
>
> Julien.
>
>

regards
Thorsten

Loading...