Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sorry for the too ambiguous title.

First consider a following code snippet.

x = "x"; y = "y";

kk[] := Module[ {q, w, m},
    q[a_] := a + 1;
    w[a_] := a^2;
    m[Global`x] = q;
    m[Global`y] = w;
    m
]

With this function kk I can write code like this,

kk[][x][1]    (* output -> 2 *)
kk[][y][2]    (* output -> 4 *)

as expected.

However, I want to change the name of the global variables x and y to those of the local variables q and w. Thus, consider a below snippet.

q = "x"; w = "y";

kk2[] := Module[ {q, w, m},
    q[a_] := a + 1;
    w[a_] := a^2;
    m[Global`q] = q;
    m[Global`w] = w;
    m
]

Note that the only change to the above code is the global variable names x and y. However, this function kk2 does not work as expected anymore. Can you explain?

The output I got was,

kk2[][q][1] (* unevaluated *)
kk2[][w][2]

Thanks in advance.

EDIT: add [] to each kk2 calls as pointed by m_goldberg

share|improve this question
3  
What exactly are you trying to accomplish with such constructs? This "feels" like trying to do something that has a better solution. In any case, do Module[{q}, Globalq]` and observe the result... –  rasher Apr 11 at 9:06
    
@rasher I tried your suggestion. It returns local q instead of global one. Can I ask you why? –  Sungmin Apr 11 at 9:13
1  
Search documentation for "Modularity", first hit has a tutorial that might help you understand. Also read the "common pitfalls" question at this site. And again, always good to include in your question what you're trying to accomplish (and why in this case). Most times trying to use global state locally pulling it into a function raises eyebrows... –  rasher Apr 11 at 10:26
1  
Also try Module[{q}, Context[q]], which gives Global` . That may be confusing, as q is of course supposed to be used as a local variable. But Module resolves naming conflicts by giving q a unique name, rather than by putting q in another context, or something like that. If you want to refer to the "global" q, you can do something like Symbol["q"], but you probably shouldn't. –  Jacob Akkerboom Apr 11 at 13:30
1  
kk[x][1] and kk[y][2] don't evaluate. Should they not be kk[][x][1] and kk[][y][2]? –  m_goldberg Apr 11 at 13:33
show 1 more comment

3 Answers 3

up vote 8 down vote accepted

Module works different than scoping constructs in other languages.

Here's a simpler example which already gives a clue of what happens:

x=3; Module[{x}, {x, Global`x, Context[x]}]
(*
==> {x$81, x$81, Global`}
*)

You see, no matter whether you prefix it with Global`, x gets replaced with x$81, which indeed also has global context.

Indeed, this is how Module works:

  1. The parsing code generates references to the symbol Global`x whenever you refer to x with or without Global` prefix (this is assuming you didn't use any commands changing the current context, of course). Note that symbol resolution already happens at this step.
  2. When the Module statement is executed, each instance of Global`x occurring lexically in the expression is replaced with a new variable, here x$81 (the exact name varies from call to call, guaranteeing that the name is unique). So technically, there's not a new scope introduced, but a variable replacement happens.
  3. Now the code with the replaced variable is executed.
  4. If no references to the introduced "local" variables remain, they are removed again.

You can also see this in action by explicitly constructing the variable name:

x=3; Module[{x}, Symbol["x"]]
(*
==> 3
*)

Here, at the time Module does symbol replacement, the expression doesn't yet contain the symbolGlobal`x, but only the expression Symbol["x"] where the "x" is just a string. Therefore the replacement step doesn't replace anything, and during evaluation Symbol["x"] creates a reference to Global`x, not to Global`x$81 (or whatever the "local" variable is called this time). And since Global`x has been assigned the value 3, it evaluates to that value.

share|improve this answer
    
Nice answer. +1 –  Mr.Wizard Apr 12 at 5:06
add comment

I am quite unable to understand why you just don't write

kk[q][a_] := a + 1
kk[w][a_] := a^2

This gives

{kk[q][1], kk[w][2]}
{2, 4}

Wouldn't the above satisfy your needs?

share|improve this answer
    
Could you read this post mathematica.stackexchange.com/questions/45916/… ? This is the underlying reason I tried this approach. –  Sungmin Apr 12 at 3:05
add comment

This seems to work.

 q = "x"; w = "y";
 kk[] := Module[{q, w, m},
    q[a_] := a + 1;
    w[a_] := a^2;
    m[Symbol["q"]] = q;
    m[Symbol["w"]] = w;
     m]

Cant imagine why you'd want to do this though.

share|improve this answer
    
Could you read this post mathematica.stackexchange.com/questions/45916/… ? This is the underlying reason I tried this approach –  Sungmin Apr 12 at 3:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.