Message Boards Message Boards

Improve the syntax control in Mathematica?

Posted 8 years ago

As I am trying to write long code in Mathematica, I spend hours debugging it because of (what I see as) lax syntax control. The following obvious errors do not generate any warnings!

For[i==1, i<3, i++, Print[i] ];
f[x_, y_]:=x+y; f[5]

Is there a Mathematica option/setting for stricter syntax control?

-- Adam

POSTED BY: Adam Sikora
11 Replies

I think your question is related to how Mma uses pattern matching in its function invocation syntax.

There is a lot of subtlety to understand and use defensively, in code, in order to make sure the semantics can be derived from the syntax.

I do not think the parsing system can help much with this.

HTH.

POSTED BY: Aeyoss Antelope

Mathematica is a symbolic language. I think that this makes it unavoidable that is very easy to write an expression which is perfectly valid, yet not what you mean.

Some would say that it is a to edged sword: it is powerful and it is easy to get a lot done in only a few lines of code. But it is also easy to shoot yourself in the foot.

Part of learning to work with Mathematica is learning to program in a way that makes such errors jump out as fast as possible.

In this case, I'll repeat what I said many many times: unless you are experienced with Mathematica, never ever use For! For is evil. Really. To make myself clear, I am not speaking against procedural programming. I am speaking specifically against For.

In the vast majority of cases, For can be directly replaced with Do, which is easier to read, easier to write without mistakes (!), and localizes its iterator. If Do is not general enough, use While. I only use For when translating code from other languages, and even them rarely. First I borrow the for-based code literally, then I gradually rewrite it to be faster and more Mathematica-like, checking at each step that the result doesn't change.

About f[x,y] := x+y — This is not only valid syntax, but useful and necessary too. It is indeed a mistake which is easy to make. But the front end helps us with it: the syntax colouring is clearly different between f[x_, y_] := x+y, f[x_, y_] = x+y and f[x, y] = x+y. Pay attention to the syntax colouring: black, blue or greenish-blue. It can save you from many mistakes. This sort of syntax highlighting is also done by the IDEA plugin, which can also warn you about common mistakes the front end won't show quite as clearly (e.g. newline as multiplication).

Some criticize Mathematica for being cryptic and hard to understand. It is true that it is easy to write such code with all the different yet equivalent notations and powerful operators. But you can use this notational flexibility to your advantage, to make code more readable, although it takes practice and discipline. Try to develop a consistent style that you are comfortable with and stick to it. For example, I think that f@g@h[x, y] is objectively easier to read than f[g[h[x,y]]] because it eliminates the need to match up brackets. There is also the postfix approach, e.g. h[x,y] // doThis // doThat // Map[f] // Riffle[#, x]& // StringJoin. This can be very readable because the operations are listed in the order they will be performed.

We could also mix all these syntaxes and use all of @, // and maybe even ~f~ within the same line. But we don't have to as it would likely hurt readability. It's the same with doing a lot in one line: Mathematica is famous for compact one liners, but you don't have to overdo it. Feel free to break down the code to manageable sized parts.

I am talking about readability because I think that this is the key to the problems you mentioned. If you stick to a consistent style which you are well practiced in and which is designed to enhance readability, such mistakes will jump out visually.

All this said, I do agree that a lint tool could be quite useful, but probably not very easy to write.

POSTED BY: Szabolcs Horvát

Dear @Szabolcs,

Impressive and useful comment. But, can you support your opinion against For[] with some examples when it is really evil? Or... It is only a more sophisticated programming tool... and it must be used with a great carefulness.

I think what Szabolcs means is that For is in 99% of the cases used for looping over a variable from a to b (or b to a). Though this can be perfectly done like (something like):

For[i=0,i<10,i++,
    body
]

there are several things that go often wrong:

  1. == instead of =
  2. <10 or <=10 (does that include 10 or not?) so you might 'miss' one, very common mistake
  3. I used an 'i' in the example but imagine it is the variable that is a bit longer: loopvar1, then you have to type it 3x, if one of them is wrong, the program will likely break.
  4. 'i' has to be unique and care must be taken it is not used elsewhere in the code, and I will keep a value afterwards.

This can all be solved using Do (or Table if you want to store each loop)

  1. no need to type = or ==
  2. it is immediately obvious what the begin and end is
  3. variable is only typed once
  4. variable is local and will be deleted after evaluation, it doesn't stay in memory like 'i' does in the For loop

Overall, the chance of making a mistake is just much smaller. Unless you have a loop that iterates in an unusual way e.g.:

For[i = 1, i < 200, i += i, Print[i]]

or

j = 0;
For[i = 1, i < 200, i += j; j++, Print[i]]

use Do. Like I said, nearly all for loops are used for 'linear sequences', and it is less error-prone than the equivalent Do/Table. Not to mention the execution speed and parallelisation possibilities if one uses Table.

POSTED BY: Sander Huisman

Dear Sander,

I associated your nice examples not only with C++, but also with such "monsters" as Fortran, Basic, Pascal, Modula 2, PL1 etc. All of them have appropriate looping constructs. And all of them have some peculiarities in this context... So, I concluded that For[] primitive has in Mathematica the peculiarities you have exposed. Having in mind them, the Mathematica primitive may be a nice programming tool and your last examples may be seen not against For[], but rather pro For[]. It is only my opinion and sure not an absolute truth.

They were intended as pro For, because it is unusual sequencing... Though I would still write them as While loops I think, but very equivalent...

POSTED BY: Sander Huisman

I think @Sander gave a nice summary. The last examples he gave are arguably showing a big disadvantage of For: bad readability. Unless you look at those examples very very carefully, you might think that it's a standard counting loop. If they were written using While, they would be less likely to confuse and mislead people. I would argue that writing such for loops is bad practice even in C.

A few more things that Sander didn't mention:

Do can have multiple iterators, and doesn't require nesting.

It's really common that people coming form C mix up the , and ; in For. This not only leads to errors, it is also very hard to spot, visually. Bad readability again.

Do provides a clean path to learning how to write better, more idiomatic Mathematica code. It is typical when a newcomer to Mathematica searches for what he considers a fundamental programming construct, "for", and never even looks at other solutions. If they used Do, it would give a smooth transition to Table (which has identical syntax). Once they understand Table, it's a small jump to Map, using Listable functions, parallelization, etc.

After having seen countless and countless misuses of For by beginners, I am convinced that Mathematica would benefit significantly from banishing For from its vocabulary. What would we lose? There's Do and While, which can express an equivalent program more readably. People would effective Mathematica more quickly if they didn't go down the blind alley that is For ... As it is, many get stuck writing bad Mathematica and come away with the impression that it is an inferior and frustrating language.

POSTED BY: Szabolcs Horvát

Any For can be rewritten as a While right?

For[start,test,increment,body]

is the same as:

start;
While[test,body;increment;]

right?

I'm always hoping for some advanced coding caption in Mathematica: that the frontend recognises For loops and suggests Do loops or Table, and change Sort[...,f[#1] ==f[#2]] to SortBy[...,f] and Sort@*DeleteDuplicates to Union and so on.....

POSTED BY: Sander Huisman

@Sander, @ Szabolcs. Thank you for the comments! At least, your opinions are clear. For[] is a sensitive construct prone to generate errors hard to detect. It has also the problem of readability. Conclusion: it is recommended for Mma novices to avoid its application.

It seems you want the following code:

In[4]:= For[i = 1, i < 3, i++, Print[i]];
f[x_, y_] := x + y;
f[5, 5]

During evaluation of In[4]:= 1

During evaluation of In[4]:= 2

Out[6]= 10

What error do you mean? i==3? Your code is perfectly valid. Thought probably not what you wanted

You can put anything in the 'start' of the For function:

For[Print[Plot[x^2, {x, 0, 1}]]; i = 0, i < 4, i++, Print[i]]

just works fine (though it might seem unconventional and wrong to you)...

POSTED BY: Sander Huisman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract