Semantics VS syntax programming
What matters about programming languages are the semantics, not the syntax. However, syntax is a vehicle for semantics. It is easy to show that two languages can have incompatible semantics (e.g. unrestricted pointers vs. memory safety, or differences in type systems). Let's focus on the syntax and semantics of variable declarations.
When we declare a variable in some language, this variable has a type, a scope, and a lifetime.
The lifetime of a variable determines how long the value in that variable exists. Afterwards, that value is freed. In many languages, the lifetime is unrestricted: a value may be used as long as it is accessible, the garbage collector takes care of freeing the associated memory. This means we do not statically know when a value is freed. But C++ guarantees deterministic destruction, and it is a frequent idiom to associate sides effects with destruction. This is not possible with garbage collection. This line has wildly different meaning in C++ and Java/C#:
Type variable = calculation;
An universal syntax would need precise lifetime control syntax to be able to express a variety of languages.
Next up: scoping. Scope determines where an identifier is visible and the variable can be accessed. There are two kinds of scoping: lexical/static and dynamic. With dynamic scoping, a variable is accessible until a certain point in time, and it is accessible from any code that is executed during this time. Examples are Perl's package-global variables or Lisp's “special” variables. More common is lexical scoping, where the variable is only visible within a specific region of source code. There are three ways where the scope of a variable can start:
- in the statement where the variable is declared, which allows the variable to be used within its definition. This is important if we are writing a recursive lambda expression.
- after the statement where the variable is declared. This prevents recursive definitions.
- at a different location, e.g. the start of the enclosing function or an enclosing block.
var variable = calculation;
Universal syntax would need to provide precise scope controls for a variety of scoping conventions.
Some languages don't make a syntactic difference between assignment and variable declaration. This is problematic when a language features closures, since this prevents us from assigning to closed-over variables.