For a programmer using a language, there are two sets of concepts, two sets of things to deal with. One set is the concepts of the problem domain. The other set is the concepts of the language itself. The distinction exists because all programmers must understand all language concepts but not all problem domain concepts.

The programming language concepts are completely independent of problem domain and transcend code area. In contrast, even supposedly "universal" problem domain concepts like array and stream demonstrate extreme locality, which makes them frequently used by one programmer and barely encountered by another.

So, for example,

first + second

involves concepts in the problem domain since even addition is a concept in a problem domain,

whereas

| first |
first := first.
^second

involves concepts in the language since variables, assignment, sequencing, expressions and returns are all concepts of programming languages which have nothing to do with problem domains.

Good syntax does the following:

it distinguishes between problem domain concepts and language concepts

And since everything in any problem domain is done using message sends, having only two symbols for a message send ( and :) means that all problem domain concepts are treated uniformly.

The violations of good syntax in Smalltalk are few,

mathematical operators are symbols

value is sent to blocks even though 'eval' is a language concept

It's especially significant that mathematical operators are symbols because this is the exception that proves the rule of good syntax. Mathematical operators have already been learned by all programmers, so you're not adding any learning costs by using already known symbols. In fact, since you're avoiding unlearning costs, this actually makes them acceptable.

Evil syntax

The above simple rules of good syntax are radically violated by languages with C-style syntax. In fact, C-style syntax seems to have been conceived as an exercise in devising the most evil, most unreadable and impenetrable syntax which the language's users will still just barely be able to use. Much like most software actually.

For starters, there is no distinction between words and symbols, between language concepts and problem domain concepts. On the one hand, words like 'do', 'return' and 'end' are used to demarcate language concepts. On the other hand, non-mathematical operators are invented to deal with problem domain concepts like array access.

To add to this pain, the most frequently used language concept (message dispatch) is given the least visible symbol possible, the dot. Despite this, neither the dot nor function brackets are unobtrusive enough to be ignorable.

Usually, mathematical and other problem domain concepts are hard-coded in with their own special unchangeable symbols.

And then, the parentheses are overloaded to mean two radically different language concepts, function calls and precedence.

And finally, curly braces are used despite the difficulty of distinguishing them from parentheses.

What it all means to you

The first violations above concern basic interaction design principles. Regarding such principles, even the most novice interaction designer will be able to tell you that they're self-evidently self-evident, that you're an idiot for not knowing them and that it's Evil to violate them.

The last violation concerns the very simplest of usability engineering principles so anyone who so much as knows the meaning of 'usability engineering' ought to tell you that curly braces are Evil.

Now naturally, all these concerns are design issues so even highly competent programmers will be unable to see anything wrong with C-style evil syntax or to appreciate the beauty and power of good syntax when they see it.