This is my first post in the series. Rich Hickey is the creator of the Clojure Language. He is widely known for his clear thinking and unique approach towards software. These are my notes for his talk titled "Maybe Not", which he gave at at Clojure Conj 2018.
NULL
I call it my billion-dollar mistake. It was the invention of the null reference in 1965. — Tony Hoare
Why are nulls / options used?
- Optional requirements
- Clojure mitigates this by providing varaidics and kw-args (keyword args)
- Conditional provision (returns)
- Managing partial information (aggregates)
Maybe ?
If we make an arguments optional or make the return value optional by wrapping them in a maybe
, both break all the API whereas It should be compatible change as we are making things optional.
Maybe
/Either
are not type system's or
/union
type, rather evidence of lack of first-class union types
Kotlin solves this by providing Nullable and Non-nullable types
Dotty (Successor to Scala): Union types are dual of intersection types. Values of type A | B
are all values of type A
and all values of type B
.
|
is commutative i.e. A | B
is the same type as B | A
Aggregate → Flock/Herd that moves together
Maps vs Records/Fields/Product Types
- Maps
- maps are mathematical functions
- Simplest functions in programming
- Key → value
- No code, No categories
- Records
- Place-oriented programming
- Even with named fields
- Names are not first class indices
- thus are not functions
- Product types complect meaning and place
-
data Person = Person String String
there's no way to tell what the first string stores and what does the second
-
- But records are more restrictive (which is good)
- spec/keys
- Independent, reusable attributes, RDF-style
- aggregate attributes to form a schema
Optionality and aggregates
- When something is missing from a set → leave it out
- Maps are enumerable, so if we leave out what we don't know, then their are no empty slots
Context
RDF style attributes are context free
No maybes → Either you know a model or you don't.
- A name is always a string, the fact that you know it or not is an orthogonal idea and binding them together using a type is wrong
It's a mistake to put optionality in aggregate definitions because unlike args and returns there is no usage context.
We want
- Maximum schema re-use, as defining multiple context specific schemas for the same idea leads to disconnect between the various schema definitions.
- Support symmetric request/response
- Information building pipelines
Schemas are deep
- schemas can nest
- attribute values can be collections
- optionality specs should be deep
Fix
Split apart the schema(shape) and the selection(optionality for current context)
The schema will only mentions the structure not optionality
The selection will described in the method signature, so that the it can be clearly specified what parts of the schema are required.
Separate requiring attribute from requirements of the attribute, example: address is optional but if address is provided then the zip-code is required
This system is flexible to allow you to specify your assumptions of the incoming data while making the default to allow everything.
Make systems that are extensible, that you can change and enhance over time
If you like this do check out the other posts in the series :)
Top comments (1)
This talk could have been so much better if Rich Hickey did not reveal with smug his ignorance of the whole field of optics.