Programming Languages - Versus
Standard vs. Implementation
- Standard is the language specification, listing all the definitions and features of the language, however nothing "physical".
- Implementation is the actual engine that can execute the code that comply with the spec.
Examples:
- Java:
- one JVM specification
- multiple implementations, like OpenJDK, Oracle JDK etc.
- JavaScript/ECMAScript:
- one specification: ECMA-262
- JavaScript, JScript and ActionScript are all implementations of ECMA-262 standard. The implementations are compatible with ECMAScript though may also provide additional features.
- SQL
- Standards like SQL-92, SQL-2011, etc.
- Databases usually implement only a portion of the standards, plus some custom features. So one SQL query from a certain database may or may not work in another database.
Imperative vs Functional
- In a imperative program: a function depends on two things
- the parameters it is passed and also
- the current state of the machine store.
- In a functional language:
- only the parameters it is passed matters.
Dynamic Type vs Static Type
Dynamically typed language means that variables do not have types, only values do. There are no type definitions in the language. All values carry their own type.
Rust goes a middle way: It’s a static type system, but it only requires the programmer to specify top-level types like function arguments and constants. Inside function bodies, Python-style type inference is allowed.
Dynamically Linked vs Statically Linked
- static: link at compile time
- dynamic: link at runtime
Some languages use both: static linking to deploy, dynamic linking to iterate
Statically Declared Array vs Dynamically Declared Array
- static: allocates memory at compile-time, size is fixed, in stack, no need to manage memory
- dynamic: can alter the size at run time, in heap, need to allocate and free memory
int* a = new int[10];
delete[] a;
Alternatively std::vector
can be used, which resizes itself automatically
std::vector<int> v = {1, 2, 3, 4}
Lexical Scope vs Dynamic Scope
- Lexical scope: a.k.a static scope.
- A variable may be referenced from within the block of code in which it is defined.
- Determined at the compile time, "early binding",
- "The name resolution depends on the location in the source code and the lexical context, which is defined by where the named variable or function is defined."
- Examples: most modern languages use lexical scope for variables and functions.
- Dyanmic Scope:
- uses the location of the function's invocation to determine which variables are available.
- Determined at the run time, "late binding".
- "The name resolution depends upon the program state when the name is encountered which is determined by the execution context."
- Examples: Perl (originally with dynamic scope only, later supports both), LISP, shell languages like bash and PowerShell.
Immutable vs Mutable
- Immutable: cannot be changed once created
- Mutable: can be changed
Java: String
and all of the number classes, such as Integer
, Double
, Character
, and BigInteger
.
Stack vs Heap
- Stack: primitive values, references to objects, and methods; short-lived. LIFO. Whenever a method is invoked, a new block is created in the stack memory for the method to hold local primitive values and reference to the other objects.
- Heap: object created by
new
; array is also object, so also in heap.- Young gen
- Old gen
- PermGen(replaced by Metaspace, which uses native memory, in Java 8)
- use -Xmx, -Xms to specify the size of Heap
- use -Xss to specify the size of stack
Recursive methods usually use much more stack space, and therefore more memory, than an iterative counterpart.
COBRA vs RMI
- RMI is a Java-specific technology. CORBA has implementations for many languages. You can use CORBA to share objects between programs written in different languages (e.g. C++ and Java).
- CORBA uses IDL (Interface Definition Language) to separate interface from implementation. RMI just uses Java interfaces.
Type Introspection vs Reflection
- Type Introspection: the ability of a program to examine the type or properties of an object. C++ is not capable of introspection at runtime, only compile-time.
- Reflection: the ability of a process to examine, introspect, and modify its own structure and behavior.
Statement vs Expression
- Statement: does not return anything. Have side-effects.
- Expression: returns a value. May have side-effects.
In a pure functional language, there are only expressions, and no statements at all, because statements have side-effects.
For example, in some languages (e.g. C++, Java, JavaScript, Go), if
is a statement, it returns nother, you cannot assign the value to a variable:
var result;
if (isTrue) {
result = 'a';
} else {
result = 'b';
}
In other languages (e.g. Python, Rust, Kotlin), if
can be an expression, you can assign it to a variable.
let result = if isTrue { "a" } else { "b" }