Square brackets signal the expression parser that it should recurse, and must parse whatever it finds for functions. This means that you should use brackets in situations where the parser isn't expecting to parse for functions. Currently, the parser expects to parse for functions in the first word of whatever it's parsing, and nowhere else.
think add(1,1) foo
returns '2 foo', but this:
think foo add(1,1)
returns 'foo add(1,1)'. If you wanted to get 'foo 2', you'd have to:
think foo [add(1,1)]
Because the first word of what's being parsed by a level of the parser is automatically checked for functions, you don't need to do this:
start [add([sub([mul(3,3)],2)],1)] end
because the sub (and the mul) are the first words of expressions that one of the recursing parsers will evaluate. So you can write the above as:
start [add(sub(mul(3,3),2),1)] end
In addition to saving a few characters, this is more readable. It also saves a couple of extra recursions, which might be important if you're running into the parser's call_limit. (The impact on code speed is usually negligible, however).