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