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.

I'm reading the book of Leonid Shifrin, and I love the way the book explains the core in Mathematica. As everything is an expression, now I understand that, there are no real function or variable in Mathematica. Function is such an indexed variable containing several rules.

Head /@ {Sin, Sin[x], x, 3}
AtomQ /@ {Sin, Sin[x], x, 3}
Attributes /@ {Symbol, String, Integer}

{Symbol, Sin, Symbol, Integer}

{True, False, True, True}

{{Locked, Protected}, {Protected}, {Protected}}

So both function Sin and variable x are Symbol. Everything in Mathematica is Symbol, String, or Number. This principle helps me a lot.

f = Sin;
g = Sin[x];
{f[x], g[x]}

{Sin[x], Sin[x][x]}

Without this principle, a beginner can think that the function g equals to the function Sin[x]. So g[x] should return as Sin[x]. And he can think that the definition f = Sin is impossible because Sin should be expressed as a function Sin[something].

But here, we can see that Mathematica is very flexible. If we consider Sin as a variable, so assigning f = Sin is totally correct. And g[x] is not equal to Sin[x], but Sin[x][x]. I think this is a very basic thing, that a beginner should remember.

So many books on Mathematica don't explain these principles, they just teach how to use the command. But understanding the core in Mathematica for me is much more important, because it is the basic to master Mathematica programming style. Thank you Leonid Shifrin.

As now, I see that functions and variable are Symbol. Beside Symbol, could we use another type as a variable? For example, I would like to have a list of 40 variables a1=1, a2=2, a3=3,... a40=40. But I don't want to use indexed variable a[1], a[2], a[3], a[40] because for me, it is just one variable a with several index.

Of course, the natural way is typing a1 = 1, a2 = 2, ... a40 = 40 manually. But how to do it in automatically in a loop or table way?

My first try is to generate "a1", "a2", ... "a40" as String.

"a" <> # & /@ ToString /@ Table[i, {i, 3}]
{"a1", "a2", "a3"}

But String can not be used as variable....

{"a1", "a2", "a3"} = {1, 2, 3}

Set::setraw: Cannot assign to raw object a1. >>

So how to generate a list of variable? a1, a2, a3...?

I try to use ToExpression to convert the String to Expression, I got a list of variable a1,a2,a3.

ToExpression["a" <> # & /@ ToString /@ Table[i, {i, 3}]]

{a1, a2, a3}

I'm trying to assign the value: (*)

ToExpression["a" <> # & /@ ToString /@ Table[i, {i, 3}]]] = {1, 2, 3}

Set::write: Tag ToExpression in ToExpression[{a1,a2,a3}] is Protected.

>

What is wrong here. I try to add Evaluate on the l.h.s:

Evaluate@ToExpression[
   "a" <> # & /@ ToString /@ Table[i, {i, 3}]] = {1, 2, 3}
{a1, a2, a3}

{1, 2, 3}

Finally, it works. But are there any another way than this way (too long) to generate a list of variable a1, a2, a40? and why I need to Evaluate the l.h.s at (*) before Set to {1,2,3} ?

Edit: Thanks to @RunnyKine, now I understand why I must Evaluate at (*) before using Set.

"because when using Set, Mathematica evaluates the R.H.S. and leaves the L.H.S. unevaluated."

share|improve this question

closed as unclear what you're asking by Leonid Shifrin, RunnyKine, Simon Woods, Artes, bobthechemist Dec 22 '13 at 3:33

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question.If this question can be reworded to fit the rules in the help center, please edit the question.

2  
Thanks for this, I really appreciate, and I am happy that the book works for you. Comments such as this show that writing the book was a good thing. But I see no question here. Our format on SE requires that one asks a question. Sorry, but we'll have to close this. –  Leonid Shifrin Dec 21 '13 at 22:14
    
Although I agree with you that one of the biggest problems is that the core principles of Mathematica are not understood by even some long-term users, the problem of your article is, that it is no question. We all have agreed on how posts should look on StackExchange. What can we do with your post now, except of just closing it? Please review the help and make suggestions. Maybe you can edit your post and make it a real question? –  halirutan Dec 21 '13 at 22:15
    
Of courses, I have question. :) –  DaoTRINH Dec 21 '13 at 22:35
    
Duplicate: (6623). Related: (20758), (20412), (6511). –  Mr.Wizard Dec 22 '13 at 10:27
add comment

3 Answers 3

up vote 2 down vote accepted

Since you want to know the things going on behind the scene, I first want you to think about the difference of a[1], a[2], ... and a1, a2, ...

For every value you set in either way, Mathematica creates a rule. In the first case, the rules are stored in the DownValues of a. In the latter they are stored in the OwnValues of a1, a2, ...

{a[1], a[2], a[3]} = {1, 2, 3};
{a1, a2, a3} = {1, 2, 3};

DownValues[a]
OwnValues /@ Hold[a1, a2, a3] // ReleaseHold

(* 
  {HoldPattern[a[1]] :> 1, HoldPattern[a[2]] :> 2, HoldPattern[a[3]] :> 3}   
  Sequence[{HoldPattern[a1] :> 1}, {HoldPattern[a2] :> 2}, {HoldPattern[a3] :> 3}] 
*)

Therefore, it should not really have an impact on performance which version you choose. It is just that, as you have observed yourself, the first version with a[1] can be created more easily.

Nevertheless, there are ways to create a list a1, a2, .... If you want new, unique variable-names, one of the easiest methods is using Unique. Here is a short snip creating a table and showing you what was set

Table[With[{var=Unique["a"],num=i},
  var=i;
  HoldForm[var=num]
  ],{i,1,10}]

(* {a15=1,a16=2,a17=3,a18=4,a19=5,a20=6,a21=7,a22=8,a23=9,a24=10} *)

A disadvantage of this method is that Unique really takes the next free variable. When you know for sure that your variables a1, .. don't have a value, you can use Symbol to create the symbol from a string

Table[Evaluate[Symbol["a" <> ToString[i]]] = i, {i, 1, 10}];
{a1,a2,a3}

(* {1, 2, 3} *)

Other things you should have a look at are MakeExpression and ToExpression.

share|improve this answer
    
You open my eyes ! Great ! I can use directly Symbol to generate a variable instead of using ToExpression. Thank you. –  DaoTRINH Dec 21 '13 at 23:26
add comment

While you may not like to use indexed variable, it is the most natural way to do what you want in Mathematica. But to satisfy your request, convert your created String to Symbol, then you can do the assignment.

Evaluate["a" <> # & /@ ToString /@ Table[i, {i, 3}] // Symbol /@ # &] = {1, 2, 3}

Note the use of Evaluate to force the L.H.S. to evaluate before making the assignment.

share|improve this answer
    
Could you please explain me, why we must Evaluate the l.h.s before making the assignment? –  DaoTRINH Dec 21 '13 at 23:22
    
@DaoTRINH, because when using Set, Mathematica evaluates the R.H.S. and leaves the L.H.S. unevaluated. –  RunnyKine Dec 21 '13 at 23:29
    
Thank you very much @RunnyKine. This is another principle that I must remember. When using Set, the L.H.S unevaluated. –  DaoTRINH Dec 21 '13 at 23:32
add comment

I think that ToExpression is the function that you are looking for

In[9]:= ToExpression /@ Table["a" <> ToString[i], {i, 1, 10}]

Out[9]= {a1, a2, a3, a4, a5, a6, a7, a8, a9, a10}

in fact

In[11]:= Head /@ ToExpression /@ Table["a" <> ToString[i], {i, 1, 10}]

Out[11]= {Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol, Symbol}
share|improve this answer
add comment

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