Skip to content

Instantly share code, notes, and snippets.

@andrewf

andrewf/goals.md Secret

Created December 13, 2021 12:55
Show Gist options
  • Save andrewf/c6774d1bc8ad793b4b3e3172ba13f6b0 to your computer and use it in GitHub Desktop.
Save andrewf/c6774d1bc8ad793b4b3e3172ba13f6b0 to your computer and use it in GitHub Desktop.
Fern Goals Draft

Philosophy:

Get full benefit of computers

  • Whatever is possible in principle should be possible in practice (notably, deterministic simulation).
  • Whatever is simple in principle should be simple in practice. Stretch: also easy.
  • Computer does all the work it can, especially boring work, while humans focus on creativity.
  • Take full advantage of knowledge humans provide (usually by representing it in maximally general form).
  • You can interact with/modify anything (as long as it's not actually a security problem).

Reduced rage

  • Good defaults, don't ask dumb questions.
  • Don't drop info (especially human knowledge), or fail to even make room for it, only to ask for it again later.
  • No lost data (I mean, hardware failure happens, but software should not eat data and backups should be mostly solved).
  • Don't flipping hide things from the user (unless for security, from unprivileged user; absolutely don't hide from owner). If the computer obviously knows, tell the user, or at least give them a way to find out.
  • Rightful owner of a computer has both legal and practical control of all the bits that pass through it.
  • Reduce tyranny of arcana. Things should make sense.
  • Stretch: No dangling/meaningless/stupid edge cases in system's logic, etc. Everything expressible should be meaningful and useful.

Support humane interfaces/systems

  • Don't force people to make meaningless decisions, e.g. order, arbitrary names, organization into an ill-fitting schema, etc. All digital info should be ASAD (As Specific As Desired).
  • A place for every idea.
  • It's the content, stupid. System and UX are content-focused.
  • Actions have predictable consequences. Reduce implicit context-dependence. Easy to see trial results of any action.
  • Humans have short memory. Record and make accessible history, etc.
  • Mistakes are common: reversibility, deeper than content undo.
  • Amenable to alternate UIs: plain text, audio, VR, etc

Separate intent and implementation (intent vs encoding)

  • Intent exists independent of models in bits, platonic.
  • As Specific As Desired (ASAD), again. Attributes user doesn't care about (e.g. spurious order) are not present or are at worst semantically transparent. Intent is often less specific than implementation is comfortable with. Apply good defaults.
  • Operational definitions (in terms of intended result) where possible.

Good programming patterns should be path of least resistance. (Note that actually preventing user from causing messes is a non-goal)

  • Enlightenment should result in less work, not more. "Pit of success".
  • Easy security/verifiability (including picking weakest computation model needed for app).
  • Easy reusability/generality.

Let solved problems be permanently solved, avoid rewriting things.

  • Enable creating radically reusable code. (ed note: I claim this is semantically distinct from "easy reusability" by relaxing standards for ease and increasing standards for power. It's true that with any luck they work out the same.)
  • A library of solutions to common problems, built to be interoperable with itself and the wider world.

Explicate assumptions

  • Everything outside the platonic realm has an encoding. We should know about it, think about it, name it.
  • Everything has context that defines its meaning (decodes it).
  • Code is always data, data is always code (in the right context).

Verifiable code, pervasive provability

  • Actually reliable software.
  • Computer does heavy lift of analyzing any code.
  • Enable safely running code from others, knowing effects are confined to what code declares and what we choose to allow for it.

Heuristic/fast-changing things are swappable

  • E.g. data layouts for perf, cache invalidation strategies, or fuzzy matching heuristics related to identity.
  • Use multiple implementations for an intent. Transition between them with no downtime.
  • Don't form hard dependencies on things that change.

Stretch: No duplicate concepts

  • All those concepts that feel roughly the same should actually be the same. E.g. all the things that look like objects/closures/processes are identical.
  • Simulation, fixpoint/recursion, contexts, uniqueness guarantees, should appear once in semantic rules and be applied everywhere.

Idiosyncratic terminology:

  • Knowledge: what humans know about the real-world things they want to model in software. Both declarative and procedural.
  • Intent: What people want to express about how they want to change/transform/render their models. Slippery concept. We assume a given intent is precise enough to be computable before we have to think about representing it in our computer system.
  • Encoding: Representing an intent or model in terms of a lower-level model. Recursive. Data can be encoded as action and vice versa. We can think of a piece of data being "encoded" by a server-type process that mediates access to it. Machine code "encodes" an intent about the computer's actions on data. Machine code is decoded into movements of electrons, i.e. action.
  • Context: something that gives meaning to something else. Famously slippery concept. For our purposes, closely related to a decoder. We will use it for both program evaluators, symbol tables, and everything in between. A simulator is a kind of context.
  • Simulation: running (or analyzing) code in a context where you exercise explicit control over all its inputs, outputs, and computation steps. Usually where you implement its computation steps. Key aspect is the hermetic isolation. Alternately, turning data into action (a decoding into action, in a sense).
  • Ownership: an entity A (or agent) owns another entity B if A can both freely modify or destroy B. Ownee can be a figment of owner's imagination (though that's technically more of a simulator thing). Usually (always?) entails lifetime inclusion.
@tomlarkworthy
Copy link

Is this for a programming language or something bigger? I guess yes for a PL "Verifiable code, pervasive provability". Well that would be cool but I am yet to find a formal system that is easy to program, unless you count types (and actually scala is not all that easy to program). Hmm, "No lost data", so no lost data is backed by a database? So maybe this is a workflow engine? Very interesting, if the runtime has a formalized runtime with inbuilt persistence, could be quite handy.

"Let solved problems be permanently solved, avoid rewriting things." -> actually I think this is an issue with humans not technology, see the "it's not written in Rust problem class".

"Use multiple implementations for an intent." I have seen algorithms expressed as pointer rewrites rules that allow you to switch between different levels of immutability. https://en.wikipedia.org/wiki/Persistent_data_structure#Generalized_form_of_persistence. there are algorithms that can synthesize different levelrs of persistence (e.g. partially persistent) which can be more memory effecient and faster than the fully persistent alternative. Is this what you mean?

Intriguing stuff but I don't get a good sense of how you would approach starting such a system or even what it would look like in practice.

@andrewf
Copy link
Author

andrewf commented Dec 15, 2021

@tomlarkworthy definitely a vision for the full stack, OS/languages/UX. Does saying that clear up the confusion, or would it help to be more specific?

Ease vs verifiability: agree that's one of the harder problems here. I think the biggest trick will be making it easy to use weaker computational models wherever they are good enough, down to HFSMs. Fully Turing-complete code should be pretty rare.

There's definitely a social aspect to the continual rewriting, but definitely also a technical aspect. It's hard to make things that are really reusable. A large part of the problem is interoperability, which you could see as an aspect of composability... I probably need to clarify that we don't terribly want to prevent people from rewriting, it just should be much easier to re-use things.

Re multiple implementations: That's one of the kinds of thing I'm talking about, but applied all up and down the stack.

TBH, my vision for what it would look like in practice is still hazy, too. Being precise about my goals is partly to help me flesh that out. Thanks for reading and commenting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment