Design note: folding design patterns into the language

This note goes with the purpose of creating EK9 in the Introduction to EK9. EK9 pulls design patterns and framework ideas into the language as constructs. This note sets out why, and the case against.

Constructs are the value

The higher-level abstractions, such as classes and traits, could all be implemented in 'C'. Functions could have been implemented in 'assembly' code as subroutines. Classes could be 'C' structs with a virtual function table for the methods. Traits/Interfaces are no more than abstract classes with no properties and only method signatures.

So why create new constructs if they can all be defined in existing ways? Because concepts and abstractions are the value being added, not ease of implementation. The much higher-level constructs, such as components and Inversion of Control, could be called an excessive number of abstractions - but so could functions, classes and traits, if you are or were a C or assembler programmer.

Library design is language design

It has been said that 'Library Design is Language Design'. Java uses this widely through Annotations, especially in 'Spring' and to some extent 'project Lombok'. The Java example below uses only a class, but its Annotations tell the developer more about how that class is meant to be used.

...
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource (name = "employeeProperties", value = "employee.properties")
@ConfigurationProperties
public class EmployeeConfig {
}
...

Over time it becomes obvious that a 'design pattern' can be formalised into a construct. Assembly subroutines became the function; C structs and virtual function pointers became the class; abstract classes became the Trait/Interface, with more flexibility and decoupling in a polymorphic way. Classes used in specific contexts can become components, and once you have components you may want to allow them only in a specific way or context that does not suit plain classes.

Parts of the 'Spring' snippet above could be pulled into the language itself. Then the compiler can make sure the concepts are used in the right way at compile time, not only at run time.

The same goes for Lombok, which generates methods from Annotations. 'Spring' and 'Lombok' each add a programming language on top of Java, written in Annotations, that the Java compiler does not check as a language. EK9 builds what is worth having into the language - default constructors and generated operators - and leaves out what is not, such as generated getters and setters.

Criticism

Some developers and language theorists argue that languages should be minimal. A larger set of keywords and concepts expands what a developer must learn to be productive, and design patterns and frameworks should not be drawn into a language, because patterns come in and out of favour. There is much to be said for this view, and most languages take it. If you prefer a minimal set of keywords and constructs, use Lisp or Clojure.

Reasoning

There are good reasons to go against that advice, carefully and in a controlled way. Above all, none of these features is compulsory. If you develop web services, you have to deal with HTTP verbs whether they are in the language or in a third-party API; with them in the language you do not learn the API as well. If you don't develop web services, you never need to learn the verbs at all.

EK9 is a tool box. Most large-scale software uses these techniques in some form, but inconsistently, or with so many additional dependencies that fusing them together takes real work. In EK9 they fit together, and you take out only the tools you need.