— Innumerable motivations
— Today focuses on a single one
— Typed Filesystems
— Data: blob of bytes Array[Byte]
— Value: Data of a Type, Array[Byte] constrained
— Type: set of all possible Values and meanings
— A Type speciﬁes all possible values
— A Type System enforces Type membership
— There are no "dynamic" or "runtime" types
— Memory inspection is not typing
— minimal: Data => Boolean
— atomic: Data => T
— composite: (V1,...,Vn) => T
— differential: T => Change[T] => T
A complex system that works is
invariably found to have
evolved from a simple system
-– John Gall
— Change is far more common than creation
— ...obscured by constructor-oriented languages
— (A, A => B) offers insight which (A, B) cannot
What's in a change
— (3:00:00, 75mph) and (3:00:01, 0mph)
— Individually ﬁne, 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
— Pre-suffuse, every ﬁle on the system is "Data"
— At best there may be a type hint, but never
— Files can't be called typed until data always conforms
— Sounds good, but how?
— An initial ﬁle and a series of changes?
— We have something for that already
— Typed ﬁles all to be under revision control
— Changes typechecked, differentially if available
What's the type of a ﬁle?
— Might be declared: user given, suffuse enforced
— Might be inferred: ﬁle extension, "ﬁle" program
— The ﬁle metadata exposes all type information
— Enforce type-preserving writes where appropriate
— Log/warn where enforcement is too strong
— Programs have "compile time" and "run time"
— For a ﬁle, compile time is when you change it
— Run time is when you need it
— We move enforcement to "compile time"
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 ﬁlesystem is "uncompilable code"
— Currently we have only the "dirty" universe
— Developers most likely stay there
— Production code lives in "clean" universe
— Every ﬁle can be trusted to be of its type
— Every ﬁle loaded with reliable metadata
— Our generality offers huge ﬂexibility
— Types unimaginable in a proglang easy here
— Any Data => Boolean is a valid type
Typed source code
— We can deﬁne typed source different ways
— For this example it is
— "parsed and bound" (thus, ASTs and symbols)
— All ﬁles 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!
— Typed ﬁles 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, ﬁnd, grep
— Assume typed ﬁles and typed executables
— What happens to mp3info *.aac?
— Deﬁne translations between convertible types
— As in scala, implicit machinery can bridge gap
— (As in scala, "magic" carries a cost)