One of the most important distinctions in programming languages is that between syntax and semantics. While BNF does a pretty good job with syntax, it remains very difficult to understand programs and programming languages. Nevertheless, some progress has been made, and today denotational semantics is widely considered to be the best approach for giving meaning to programming languages, and hence to programs. The main idea of a denotational semantics for a language is to provide denotations for each kind of phrase in the language (such as variable, expression, statement, and procedure), and also to provide a systematic way to combine the denotations of the constituents of a larger phrase to get its denotation.
The book Algebraic Semantics of Imperative Languages develops a variant of denotational semantics that is based on algebra, and in particular, on a kind of equational logic, which is actually implemented in the OBJ language. The book demonstrates that its approach is adequate for a wide range of programming features, including arrays, various kinds of "calls" for variables, and various kinds of procedures; although this is impressive, it would still be difficult to define a real programming language like Ada.
Formal semantics is an important branch of formal methods, an area of computer science that is difficult, but of growing importance, concerned with the semantic correctness of systems; it is currently considered to be cost-effecitve for safety critical systems. All major chip manufacturers now have formal methods groups, motivated in part by the huge cost of call-backs if errors are found (as with the notorious Itel Pentium 5 arithmetic error). NASA has a formal methods group, motivated by the many software failures that have plagued aerospace efforts (such as the Ariane 5 rocket failure), and the difficulty of communication with distant unmanned spacecraft. Manufacturers of medical equipment are also considering, and in some cases using, formal methods, motivated by the cost of lawsuits if faulty equipment causes death or injury. Similar concerns arise in the nuclear power industry, the military, and many other areas.
As argued in some detail in the Essay on Comparative Programming Linguistics, the best way to appreciate a language is to understand how it is intended to be used. OBJ was not designed as a language for writing programs, but rather as a language for writing specifications, and in particular, for writing semantics for programming languages. Once this is clear, many of its unusual design choices can be appreciated, including its mixfix syntax and subsort polymorphism, its use of algebra, and its term rewriting capability. In particular, signatures provide a meta-syntax that can be used to define the syntax of a programming language, and we will see that equations and algebras can be used to define the semantics of programming languages in an elegant way.