MathGroup Archive 2003

[Date Index] [Thread Index] [Author Index]

Search the Archive

RE: What's legit here?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg39951] RE: [mg39940] What's legit here?
  • From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
  • Date: Thu, 13 Mar 2003 03:00:50 -0500 (EST)
  • Sender: owner-wri-mathgroup at wolfram.com

>-----Original Message-----
>From: Steve Gray [mailto:stevebg at adelphia.net]
To: mathgroup at smc.vnet.net
>Sent: Wednesday, March 12, 2003 8:32 AM
>To: mathgroup at smc.vnet.net
>Subject: [mg39951] [mg39940] What's legit here?
>
>
>	In the following function, most of which you can ignore,
>there is an If [ enalist ... etc. where several statements to be
>executed if the If succeeds are grouped with ( ) . 

>This works but I thought the right way to group several statements 
> together was with { }. 

*** This is not the case, and this example exactly shows why!! ***



>The latter does not work and I find I don't know what the correct
>way is. As usual, Mathematica did not complain with the { } or the ( ). The
>effect was to have the If always fail and for the function to always
>Return [ failu ].
>
> Whether  the comments get in the way, I don't know, but if someone
>would define what's legal here, I would appreciate it.
>	Thank you.
>
>
>
>ranqrs := Module[{res2}, 
>   ptab = Table[0, {i, NN}];
>   If[changeq == 1, qtab = Table[Random[Integer, {1, NN - 1}], {i, NN
>- 1}]];
>   If[changer == 1, 
>      rtab = Table[Random[Integer, {0, NN - 1}], {i, NN - 1}]]; 
>   If[changes == 1, stab = Mod[Table[1, {i, NN - 1}] - rtab, NN]];
>   matall;                                  (* 
>      Make matrices from model.     *)
>   matmul;                                  (* 
>      Compute matrix product.       *)
>   result = newres;
>   If [ enalist[[result]] == 1,                (* 
>        If a good value = > try again; *)
>	  ( newmmt;                              (* make a new model &
>target,   *)
>	    res2 = newres;                       (* do another test.
>*)
>        If [res2 == result, Return[result]]; (* If agree, 
>          return good result. *)
>      )];
>   Return[failu];                            (*If no agree or no
>interest, 
>      0. *)
>  ]
>


Steve, 

well, the explanation is given from a careful inspection of the programming
language semantics.

First, make up a descrambled, reasonable simple model of your computation:
 
In[67]:=
runcode1 := Module[{res}, If[True, (res = 1; If[res == 1, Return["Yes"]])]]
In[68]:= runcode1
Out[68]= "Yes"

This works, as expected.


In[69]:=
runcode2 := Module[{res}, If[True, {res = 1, If[res == 1, Return["Yes"]]}]]
In[70]:= runcode2
Out[70]= {1, Return["Yes"]}

What happend? Just the List has been returned, Return["Yes"] has not been
executed, but obviously the assignment to res worked, as well as the inner
If. 


Consult Help!

"Return[expr] exits control structures within the definition of a function,
and gives the value expr for the whole function."

Obviously List isn't a control structure, such runcode2 didn't execute
Return["Yes"], but silently kept it within List; whereas in runcode1,
Return["Yes"] after having become the value of the inner If, shows up in
CompoundExpression, which *is* a control structure, that is left now, shows
up in Module, which again is a control structure, which is left again,
delivering "Yes" as result (of the function).


Observe again this case:
 
In[71]:= runcode3 := 
  Module[{res}, 
    Do[#, {1}] & /@ If[True, {res = 1, If[res == 1, Return["Yes"]]}]]
In[72]:= runcode3
Out[72]= {Null, "Yes"}

When Mapping Do, Return["Yes"] gets into the body of a control structure
(Do), such Return is executed, but further confined in List, which is no
control structure and such intercepts now
the _value_ of Return["Yes"], namely "Yes". This is in contrast to Line 70,
where Return["Yes"] isn't executed. But, hold, you can make that good:

In[107]:= c := Last[%70]
In[108]:= c
Out[108]= "Yes"


Another demonstration:

In[73]:= runcode4 := 
  Module[{res}, 
    Scan[Identity, If[True, {res = 1, If[res == 1, Return["Yes"]]}]]]
In[74]:= runcode4
Out[74]= "Yes"

Here Return["Yes"] shows up in the execution machinery of Scan which --
contrary to Map -- isn't confined within a (resulting) List; such Scan is
left, we arrive at Module, a control structure, left and finally "Yes"
delivered as value of the function (runcode4).


If you want to return from an arbitrary expression, however, you may use
Catch and Throw:

In[115]:=
runcode7 := Module[{res}, If[True, {res = 1, If[res == 1, Throw["Yes"]]}]]
In[116]:= Catch[runcode7]
Out[116]= "Yes"


--
Hartmut Wolf



  • Prev by Date: Re: What's legit here?
  • Next by Date: Re: Running Mathematica in Kernel mode (UNIX)
  • Previous by thread: Re: What's legit here?
  • Next by thread: Time Series in Mathematica