Features of programming languages, and progresses
Progresses have been made to enrich languages and improve productivity. Here is the list of all the features that can be added to a language.
The first implementation in a language is indicated in parentheses.
The type of a variable is derived from the value assigned to it. This relieves the programmer to explicitly specify a type, a small economy actually. (ML 1973).
Including variables in a string, which are replaced by their value at runtime. For example in PHP:
$a = 5; $str="$a items";
It will display: 5 items.
Generics / parametric polymorphism
The possibility of replacing a type defined as integer or string with undefined type as parameter to a function, to apply the same processing to different types of data without rewriting the code.
Hierarchy in the types of language that makes an action on a type can also run on a subtype while it can not be used on different types. Such as an integer is a subtype of number and share the same operations, unlike the string type. (Simula 67).
Assignment with default value (null coalescing operator)
We assign the contents of a variable if it is not null, otherwise we assign a replacement value indicated by the operator ?? (C#).
var x = y ?? 0
Anonymous or lambda
A function can be defined anonymously if you assign it to a variable or pass it as an argument to another function. (Lisp 1958).
To declare a function inside another, and assign it as the return value. Being included in the other function, it has access to its variables, so you can read and edit variables declared inside a function from a more global scope.
Contract (design by)
Ensuring that methods and objects meet certain conditions. In the case of a function, one creates preconditions on the arguments and post-conditions on the return value. They are mandatory in a language that establishes this design, but you can add them in any language. (Eiffel, 1986).
put(message : STRING) is require not message.empty -- the string must no be empty do ... instructions... ensure ... -- conditions on the message to successfully return. end
Function that can be linked among others, its arguments are the results of other functions, and its return value is the argument to other functions.
Calling a function with the name of an argument and the value assigned to it. Example of a function whose arguments are int x and int y:
point(x : 10, y: 20)
This allow to put the parameters in any order and omit one if is is optional. (IDL 1977).
Tthe ability to use functions or any other object as a variable. Thus a function may be passed as argument or as return value. See closure.
Staged computing is defining functions that run when the required data are available and depending on the type of data. They can run partially in stages. This was described in a paper by William L. Scherlis in 1986 and implemented in Julia and other languages.
A compiler performs a kind of staged computation since it defines how actions are executed which are then based on the data (source code) that is given to the program.
A function can return multiple values at once, which form a tuple. It is thus possible to assign a tuple of variables together the result of a function.
The yield keyword in a function returns a value like the return statement, but in a loop that can so returns multiple values successively. The next value is calculated at each call to the function that lead to calculate a new one. The computation of the function is paused when yield is encoutered, the value returned, and continued with the next call. (CLU 1975).
Object with methods to scan the contents of an array or collection given as parameter. (CLU 1975).
Iterates the contents of a list with a single statement that it eventually filter and produces another list. This example in Julia multiplies the elements of an array by two. We can replace x * 2 by a condition to make a selection.
y = [ x * 2 for x in 1:50]
An aspect is a set of concerns, and a concern is a group of instructions that interacts with objects in a program. We can generally replace an aspect by another to apply a program to a different types of domain or treatment. (Extension to Java Hyper/J in 2001 by IBM).
Inheritance adds a class attributes and methods of the class from which it inherits. (Simula 67).
Kind of class that contains methods declared but not defined. When a class inherits an interface, it must provide a definition for each of its methods.
Message or event
Objects can interact by calling their methods, as in C++, or thay can do like Smalltak or Objective-C by sending messages. Each object has listeners to pending messages.
A mixin is a class having access to other classes methods. Practically is added interfaces whose methods have a definition and also having attribute. Adding methods can be done at runtime. (Flavor 1986).
A trait is a mixin without attribute.
Operator overloading / ad hoc polymorphism
Operators are redefined in the programm to perform different operations according to the objects they connect. (ALGOL 68).
Character sequence representing a search and possibly replacement command, in accordance with a grammar. (Inventor Stephen Kleene in 1956, AWK language in 1977).
Some languages like TCL allow to add new constructs to the language itself.
Construct with a definition of parameters, which will replace the construct during compilation.
The formulation: if x == y then a1 else a2 may be replaced by:
x == y ? a1 : a2
Simplified syntax for reading or replacing an element in a table row. In ALGOL 68 already, we may write [x: y] to denote the interval between x and y in the list of items.
Ability to perform parallel processing, possibly with an interaction between them. (Described by Dijkstra in 1965).
Instead of defining the processing steps, each dependent on the completion of the previous step, we define the properties of an element, and where all properties have a desired value, an action is performed. (Prolog III 1989).
Instruction block (routine, function) whose processing is interrupted or resumes according to external orders. While a function is interrupted at a return instruction. (Simula 67).
Ability to make a modules or objects of a program running on different computers. This goes beyond concurrency that operates on the same computer.
Exception handling is the ability of a language to catch errors that could interrupt a program and redirect the flow to a block of instruction that allows its continuation. (Lisp 1958).
We define a goal that is an assignment or a function call, which occurs when a process returns a desired result. So instead of writing "if cond then action", one writes "action if condition".
This structure makes sense if the condition is the result of processing performed repeatedly until you can reach the goal. (Planner 1969).
In logic programming, evaluations are actions and the flow is directed by expressions resolution. This is the case of Prolog, and it was added as an extension to other languages.
The first logical inferences language is Prolog (1972).
Compares an expression to a series of conditions and performs the action associated with the condition that matches it. (SNOBOL 1962).
Concept originally introduced by several authors between 1976 and 1977, it would have been first implemented in Act 1 (1981) and MultiLisp (1985).
Variables are not assigned statically but dynamically: their content depends on the content of other variables and are updated when the content of these other variables change. This is the operating principle of spreadsheets where the content of a cell depends on other cells. Replace the spreadsheet by a table of a database and you can describe a processing in a few lines of code.
Ability given to the program to analyze its own code and improve it based on the results. This implies building the program as a tree.
Manager of memory allocation that periodically packs the freed areas to eliminate fragmentation and provide access to a wider space. (Lisp 1960+).
The state of objects and possibly variables is automatically saved when the program stops, and are restored at the next session. (MATHLAB 1964).
RAII (Resource Acquisition Is Initialization)
Automatic memory management where memory location are released automatically when objects that use them are deleted. (C++ 1984).
The evaluation of an argument or expression is generally deferred until the result is required for further processing. This can significantly speed up the overall processing. (Described in 1976).
Compiling a function whose arguments are generic, in several versions, one for each type of argument.
Portability is best achieved through an intermediate language (first UNCOL, 1958) running on a virtual machine implemented on each system.
Virtual Machine which compiles the program code to native code during the first and run the native code in subsequent sessions.
Virtual Machine which compiles the source code or part of the source code in native language during each session before running the native code. (Lisp, 1958).
We see in fact that most of the features of current programming languages have existed for decades.