       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:=
runcode1 := Module[{res}, If[True, (res = 1; If[res == 1, Return["Yes"]])]]
In:= runcode1
Out= "Yes"

This works, as expected.

In:=
runcode2 := Module[{res}, If[True, {res = 1, If[res == 1, Return["Yes"]]}]]
In:= runcode2
Out= {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:= runcode3 :=
Module[{res},
Do[#, {1}] & /@ If[True, {res = 1, If[res == 1, Return["Yes"]]}]]
In:= runcode3
Out= {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:= c := Last[%70]
In:= c
Out= "Yes"

Another demonstration:

In:= runcode4 :=
Module[{res},
Scan[Identity, If[True, {res = 1, If[res == 1, Return["Yes"]]}]]]
In:= runcode4
Out= "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:=
runcode7 := Module[{res}, If[True, {res = 1, If[res == 1, Throw["Yes"]]}]]
In:= Catch[runcode7]
Out= "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