3. Definitions
— Data: blob of bytes Array[Byte]
— Value: Data of a Type, Array[Byte] constrained
— Type: set of all possible Values and meanings
4. Types
— A Type specifies all possible values
— A Type System enforces Type membership
— There are no "dynamic" or "runtime" types
— Memory inspection is not typing
5. Type Specification
— minimal: Data => Boolean
— atomic: Data => T
— composite: (V1,...,Vn) => T
— differential: T => Change[T] => T
6. A complex system that works is
invariably found to have
evolved from a simple system
that worked.
-– John Gall
7. Change orientation
— Change is far more common than creation
— ...obscured by constructor-oriented languages
— (A, A => B) offers insight which (A, B) cannot
8. What's in a change
— (3:00:00, 75mph) and (3:00:01, 0mph)
— Individually fine, deadly in combination
— Constraining the set of possible values is not enough
— We constrain the set of possible derivations
— Sharpen constructors, only produce initial values
9. Typed Files
— Pre-suffuse, every file on the system is "Data"
— At best there may be a type hint, but never
enforcement
— Files can't be called typed until data always conforms
— Sounds good, but how?
10. Immutable files
— An initial file and a series of changes?
— We have something for that already
— Typed files all to be under revision control
— Changes typechecked, differentially if available
11. What's the type of a file?
— Might be declared: user given, suffuse enforced
— Might be inferred: file extension, "file" program
— The file metadata exposes all type information
— Enforce type-preserving writes where appropriate
— Log/warn where enforcement is too strong
12. Files/programs analogy
— Programs have "compile time" and "run time"
— For a file, compile time is when you change it
— Run time is when you need it
— We move enforcement to "compile time"
13. How does it work?
— Every write triggers a type check
— A type-preserving write immediately committed
— Other writes sit in the index "dirty"
— A later write may turn a bad write good
— Dirtiness in the filesystem is "uncompilable code"
14. Multiple universes
— Currently we have only the "dirty" universe
— Developers most likely stay there
— Production code lives in "clean" universe
— Every file can be trusted to be of its type
— Every file loaded with reliable metadata
15. Flexibility
— Our generality offers huge flexibility
— Types unimaginable in a proglang easy here
— Any Data => Boolean is a valid type
16. Typed source code
— We can define typed source different ways
— For this example it is
— "parsed and bound" (thus, ASTs and symbols)
18. Synergies
— All files are seqs (at worst, of bytes)
— More commonly, UTF-8 lines
— More usefully, a known type (e.g. csv, pwent, ...)
— Typed seqs mean typed pipelines!
19. Type-directed shell
— Typed files are decomposable other than line by line
— The decomposed types feed back into the shell
— cat file.csv | filter _.N<tab> = bob
— Many tools to upgrade: bash, find, grep
20. "Implicit Conversions"
— Assume typed files and typed executables
— What happens to mp3info *.aac?
— Define translations between convertible types
— As in scala, implicit machinery can bridge gap
— (As in scala, "magic" carries a cost)