The "programming language" is horrible. It's a clear example of a turing tarpit. For example you don't have arrays, so you must fake them. You don't have function, so you have to return the value in a glob@l. Monkey patching is considered an art, but this makes many of the different packages slightly incompatible.
The "printing library" is amazing. If you only want to do a standard thing (and someone else had programmed it) the result is nice.
The other advantage is that everyone knows it, so if you make a package correctly it is easy to use by mathematicians that can't program in LaTeX.
(It's also no coincidence that the development of BibTeX coincides with the crack epidemic, but I digress.)
But TeX has a extremely flexible macro system, so it is possible to fake optional arguments. That's what LaTeX do. LaTeX defines a standard way to have optional parameters and make easy to define and use them. It has some strange optional parameters like in \newtheorem, because they are really fake optional parameters. The starred versions of the command also are fake, and have to be defined using a trick. But if you are lucky and don't look under the hood everything works quite well.
I don't know enough about ConTeXt, but I hope that it has a better system for optional arguments.
In some way, this is similar to what happens with some features of high level languages and assembler. For example, the exceptions in C# or Java are translated sooner or later to assembler, but assembler doesn't have exceptions.
I don't like TeX. I use it and i like the output, but I have never realy understood the language and therefore I don't like it. The syntax for optional arguments([]) seems very odd to me, aswell as the separation between mouth and the rest. The support for named parameters is IMO very hacky.
Wouldn't be a Tcl based macro processor with the tex-Backend nice? Or is this silly?