This is a note of the Rich Hickey’s 10 Years of Clojure Vidoe and its transcripts. The talk is a look back about the motivations behind Clojure: how Clojure got its opionions. It is about the design choices makde for Clojure.
Clojure is Opinionated and Why
- Most projects involved a db, different kinds of db.
- run continuously
- deal with informaiton
- have time-extensive memory
- deal with real-world iregularity
- interact with other systems
- interact with humans
- siuated in a changing world
- use other people’s code
- are not compilers (not deal with regular things)
being effective is mostly not about computation, but it’s about generating predictive power from information
- Effective means working – producing the intended result, not “make the type checker happy”.
- programming is about makeing computer effective in the world via
- leverage experience to generate predictive power
- enable good descisions and successful activities
- experience is information that is facts about things that actually happend.
- math proofs and algorithms are not the goal of programming.
Logic, such as theorem prover or a compiler, is a small part of the programming. Programs are about information processing. Programs use libs and talk to databases and other programs via protocols – each has its languages, libs and its view of the world.
The program is a system that has a time-dimensioin. Everything may change over time. Clojure’s target is
information-driven situated programs.
Problems of Programming and Design Goals
To get it accpeted, it needs good performance, be in a popular platform and be compatible. The Lisp syntax and few static type checks are not problems.
The following digagram shows the problems of programming, ordered by the severity. Clojure took on those green ones.
- Effective, situated programs out of substantially simple stuff
- Low congnitive load from language
- Be a Lisp
- PLOP (the number one self-inflicted probelm): FP, immutable persistent data structrues the default with 2x read and 4x write preformance, large library of pure functions, immutable local bindings.
- Weak support for information: sparse, open, incremental/accumulateive, names (not types) capture semantics, composable. Statically typed langauges are terrible at information. Non-composable types are a little parochialism around some tiny piece of data that doesn’t compose. Clojure uses maps that
- maps are functions of keys, keyword/symbols are functions of maps.
- generic library that is algebra and composable.
- names are first-class, namespace-qualified.
- associating semantics with attributes, not aggregates.
- Brittleness/coupling: dynamic typing, open constructs, runtime polymorphism, open maps.
- Language model complexity: Lisp syntax and Java execution model.
- Parochialism/context: types are language-specific rules that samsh against db, other langauge and wire. Clojure use namespace-qualified keys to represent the meaning.
- Weak support for names: Clojure uses namespace-qualified keywords and symbols. Names are first class.
- Distribution: Distributed objects failed. The internet is about sending plain data, maps of scalas/vectors/maps.
- Runtime intangibility: the system should be tangible to langauge. JVM is a dyanmic system that runs everywhere and can dynamic load code.
- Concurrency: FP and immutability. Use epochal time model that represent identity as a squence of values over time. Each state is a snapshot of values in a certain time.
Lisp is small, has first class names, is tangible. Other features: code is data; data is data; REPL.
- read: text to data structures
- eval: data to executable code
- print: data to human-readable text
Fixes for Lisp
- mutable list
- lack of immutable data structure
- lists are weak data structures
- packages and interning are complex
- Strong host support
- access everyting
- can reify interfaces
- extend abstraction to host types
- support host abstractions
- use host scalars
- large functional libraries
- defined with Java interfaces or protocols for ClojureScript
- EDN data model
- just the basics
- values only
- good with names
The joy of types
- gurantee absence of certain kinds of errors
- is a partial machine-checked specification (very partail)
- are a design language
- support interactive development with intellisense
- optimize performance
- help software maintenance
- type errors are not big errors. testing helps.
- names, not types domainate semantics and always will.
- type doesn’t deal with changes well
- Type systems are fun but proof has diverse needs.
Information vs Logic
Logical theories are good for puzzles. Human has information trained brains and logic has limited use. Real-world safety comes from experience (history data and information), not proof.
A programming language should be programmable - that’s the misconception problem, a huge problem. Let’s make a system that could learn from information. Programmable programs
- generic information represenation/emphasis
- compose args without type system
- dynamic discovery and invocation
- dynamic enhancement
To bee effective
- Logic is your tool, not your master
- design at the system level, outside of language
- make programmable programs
- sovle problems, not puzzles
Programming language is not the key to programming. It is a small part of programming.