6

ref / Condition / Details says:

lhs := Module[{vars}, rhs /; test ] allows local variables to be shared between test and rhs.

Well, thank you very much, of course they are shared, both test and rhs are inside the same Module!

Jokes aside, the question is: what author wanted to tell the user? How to rephrase that to make it clear and compact?

IMO when one knows then it is kind of understandable, but for learning purposes it is just confusing/meaningless as it was for me for a very long time.

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
Kuba
  • 136,707
  • 13
  • 279
  • 740
  • 1
    p.s. I'm not planning to self answer :) – Kuba Aug 05 '16 at 08:50
  • 1
  • 5
    In this case, the statement is kind of obvious, but the consequences are not. This form allows one to carry out some computations inside Module, that would involve local variables. Then, at some point, we may decide whether or not the rule (definition) matches as a whole, based on those computed values, by wrapping the rest of the code in Module inside Condition. If the condition does not hold, the pattern matcher pretends that the whole computation didn't take place, and goes on trying other rules / definitions. This semantics can't be easily reproduced had this form been absent. – Leonid Shifrin Aug 05 '16 at 14:28
  • @LeonidShifrin The problem is that these really important consequences aren't mentioned in the cited sentence in any way: we could speak only about contextual hint, and a hint isn't a kind of good documentation. It is good however that at the end of this sentence we currently have a link to an example which reveals the main point (this link wasn't present before version 6). – Alexey Popkov Aug 05 '16 at 14:55
  • @AlexeyPopkov Agreed. – Leonid Shifrin Aug 05 '16 at 15:19

3 Answers3

3

I think that the meaning of this sentence is stupidly verbatim: the author simply notes the (almost obvious) fact that this construct allows sharing the localized by Module variables between the Condition and the rhs (which resides inside of the Module). In contrast, if we move the Condition outside of the Module, we won't have the localized variables shared between the rhs and the Condition:

f[x_] := Module[{u}, u] /; EvenQ[u]

f[2]
f[2]

Probably this shouldn't be in the Details section: this statement is too obvious to reside there, it doesn't add something meaningful. But from the other side, there are some non-obvious under-documented "smart" rules on how different scoping constricts interact with each other: may be the author simply stresses that this obvious behavior is by design and we may trust it without risk...

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
  • 2
    Of course it is obvious that the variables can be shared on both sides of the Condition when it's within a scoped block, but what isn't obvious is that it affects the execution of f, i.e. if the condition fails the evaluator tries another version of f, if there is one. – rcollyer Aug 05 '16 at 14:21
  • @rcollyer Yes, but this doesn't follow from the cited statement... – Alexey Popkov Aug 05 '16 at 14:23
  • I don't think that's true, in context with the forms described above it. Could it be a little more clear, possibly. But, I have never found it unclear. – rcollyer Aug 05 '16 at 14:31
  • @rcollyer Again, what you call "not obvious" comes from the other statements and examples on that page, not from the cited sentence. I mean that without the cited statement we would have the same information, so it is superfluous. It never confused myself but obviously confuses the OP... – Alexey Popkov Aug 05 '16 at 14:36
  • 1
    I think I see where we differ. To me, the details section is the spec and should contain things like that, and the examples should help elucidate it. I don't think the examples alone should introduce the various syntaxes. (Obviously, that holds more weight when there are more than 4 examples, but it is the principle that matters. And, there are undoubtedly examples that don't follow that, but, again, principles.) Could the wording be improved, sure. But, superfluous? No. – rcollyer Aug 05 '16 at 14:58
  • @rcollyer I agree that the not obvious point is very important and should better be in the Details section than in the examples (as it is currently). This comment of mine expands my point. – Alexey Popkov Aug 05 '16 at 15:04
  • Thinking about it, I think my objection is to the word "superfluous" as I don't think it is. But, it is mostly semantics. :) – rcollyer Aug 05 '16 at 15:10
3

I never understood what that line in the documentation meant until I saw use of it in answers on Stack Overflow, i.e. Partial evaluation in Mathematica. As such I am in the camp that feels this documentation could be written more explicitly for a user who is not already familiar with its use.

I propose something along these lines:

For With, Block, and Module there exists a special construct lhs := With[{vars}, body /; test]. In this specific instance the Condition applies to the entire definition upon lhs as if it were lhs := rhs /; test but in which test may depend on the localization and evaluation of vars. This construct applies also to RuleDelayed, UpSetDelayed, and TagSetDelayed (short forms :>, ^:= and /: :=).

The scoping construct must constitute the entire right hand side of the assignment or rule, and the Condition must constitute the entire body of the scoping construct, less any additional Condition applied to each.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
1

some alternatives:

  • "Condition can be used inside Module"

  • "variables used in rhs and test can be localized"

  • "variables used in rhs and test can be localised using Module"

  • "variables can be used in both rhs and test and at the same time be localised with the use of Module"

  • "local variables can be used with the Condition construct"

My understanding is that the

"shared between test and rhs"

part is superfluous.

As Module isn't necessary for the sharing of variables between rhs and test:

f[x_] := (u^2 /; (u = x - 1) > 0)

nor is it necessary for this computation;

g[x_] := (x - 1)^2 /; (x - 1) > 0

g[0] => g[0]

g[6] => g[25]

I suspect this was written to tell new users that it is possible to combine Module with Condition.

Conor
  • 7,449
  • 1
  • 22
  • 46