9<img class="ba" src="https://media.urbit.org/site/posts/essays/pre-01.jpg">
11Urbit is a principled approach to system design and programming, but it's often not obvious what those principles are. We have many specific terms for the different parts of the project: Arvo is the OS, Hoon is the language, Tlon is the company, Azimuth is the identity system, Ames is the network. But the word most associated with the project is "Urbit", and it's not clear what technically it refers to. It's only a small stretch to say that "Urbit" *is* this set of principles, and that if anybody follows these principles strictly they will create a system that is isomorphic to the Urbit.
13Some of these are commonly held among many software projects, and some are not. Some are only debatably better than the alternatives, but Urbit exclusively chooses them.
15We’ll start with a brief description of many principles, then we’ll go into a long-form justification.
211) Data is better than code.
23 Store data in your state, send data over the wire, dispatch based
262) Everything should be CQRS.
283) (Almost) Everything should be pubsub.
304) A subscriber shouldn't affect a publisher.
325) Communication between nodes should be communication between
35 Each message should do one complete thing, and there shouldn't
36 need to be a sequence of coupled messages.
386) Represent your data as closely as possible to the essential structure
417) A client's representation of data should be as close as possible to
44 This blurs the distinction between client and server. It allows
45 offline-mode, reduces communication to syncing, and decentralizes.
478) When mating different paradigms, build one cleanly on top of the
50 Never try to make them work on some of the same primitives. Never
51 abuse one to make the other work. For example, ducts in
52 themselves are very general - if you want to do pubsub, that can
53 easily be built on top of ducts, but don't pretend that pubsub is
54 a *part* of the duct system.
569) Never misuse an abstraction.
58 An abstraction provides a certain set of tools; use them and only
6110) Correctness is more important than performance.
6311) Be simple and uncompromising in defining what's correct; go crazy
66 Nock is a great example of this. It contains the character of the
67 virtual machine, but its asymptotics are bad. Add jets to fix the
70 Another example is the ACID nature of Arvo. Arvo is a pure
71 function f(logs) of its event log, so formally Arvo is just a
72 function run against an event log. A naive implementation has
73 very bad asymptotics; processing each new event is O(n) in the
74 number of historical events. Choose the function g(state,log)
75 such that f(logs ++ log) = g(f(logs),log). Then, as long as you
76 keep the state in memory, processing each new event is constant in
77 the number of previous events. This still requires O(n) restart
78 from disk, but you can also periodically (and non-blockingly)
79 write a checkpoint of the state to disk, so that restart from disk
80 is only linear in the number of events since the last checkpoint.
8212) Correctness is more important than optimality.
8413) If you don't completely understand your code and the semantics of
85 all the code it depends on, your code is wrong.
8714) Deterministic beats heuristic.
89 Heuristics are evil and should only be used where determinism is
90 infeasible, such as in cache reclamation.
9215) Stateless is better than stateful.
9416) Explicit state is better than implicit state.
9617) Referential transparency is honesty and stability.
98 Lack of referential transparency and other forms of
99 disingenuousness are some of the world's big problems. Only
100 deviate from referential transparency if absolutely necessary.
10218) Responsibilities should be clearly separated.
104 This applies from kernel modules through network citizens.
10619) Dualities must be faced head-on and analyzed differently at
109 Statically typed vs. dynamically typed, imperative vs. functional,
110 code vs. data, and effectful vs. pure can all be a matter of
111 perspective, and all relevant perspectives must have coherent
11420) One hundred lines of simplicity is better than twenty lines of
117 It's not enough for an abstraction to reduce code duplication; it
118 must actually make the code simpler.
12021) Prefer mechanical simplicity to mathematical simplicity.
122 Often mechanical simplicity and mathematical simplicity go
12522) The Law of Leaky Abstractions is a lie; abstract airtightly.
127 If your abstractions are leaking, it's not due to some law of the
128 universe; you just suck at abstracting. Usually, you didn't
129 specify the abstraction narrowly enough.
13123) Some cliches are repeated because they are true; others must be
132 repeated because they are not.
136<img class="ba" src="https://media.urbit.org/site/posts/essays/pre-03.jpg">
138### B: Specific Design {#specific}
1401) Always ack a dupe; never ack an ack.
142 It's okay to ack a nack as long as you never nack a nack.
1442) Never construct or deconstruct a duct.
1463) Route on wire before sign, never sign before wire.
1484) Only go from statically typed to dynamically typed if you must.
150 Once you go into a dynamically typed world, it's hard to go back.
151 Statically typed is better than dynamically typed, so if something
152 can be made static, it should be.
154 Each timeless data structure is a brick in the foundation of
155 digital civilization.
1575) Anything with business logic speaks one paradigm; anything that
158 translates paradigms has no business logic.
1606) Functionally enforced semantic rules are better security primitives
161 than memory access restrictions.
163 A compiler can use type safety as an effective tool to enforce
164 some classes of security guarantees.
171 If you avoid changing a section of code for fear of awakening the
172 demons therein, you are living in fear. If you stay in the
173 comfortable confines of the small section of the code you wrote or
174 know well, you will never write legendary code. All code was
175 written by humans and can be mastered by humans.
177 It's natural to feel fear of code; however, you must act as though
178 you are able to master and change any part of it. To code
179 courageously is to walk into any abyss, bring light, and make it
1822) No time for lazy people.
184 If there's clearly a right way to do something and a wrong way, do
185 it the right way. Coding requires incredible discipline. Always
186 follow conventions, and fire anyone who won't. Anything that can
187 be solved by discipline is not a real problem.
189 > "To him who knows to do good and does not do it, to him it is
1923) When a smart person makes an obviously stupid suggestion, before
193 responding take a full 60 seconds to envision how you would implement
194 it and what the effects would be.
1991) Academia is a succubus.
201 Academia has a really high ratio of smart people to useful
202 products. Academia has many genuinely smart and interesting
203 ideas, but always remember that pursuing them whole-heartedly will
204 never result in a useful product.
208 Academia is inefficient, but it's also correct. Those people
209 wasted a lot of time finding the right answer, but now that
210 they've done it, you must exploit it. If you don't know the
211 theory, learn it. No excuse for being "bad at math". Most who
212 are "bad at math" are simply lazy or fearful. Be strong and of
213 good courage. If you're truly so bad at math that you cannot
214 learn it, you should not design systems.
2163) Not being qualified to solve a problem is no reason not to solve it.
218 If you don't know how to do it, do it anyway. "We are too young
219 to realize that certain things are impossible. So, we will do
2224) The best way to get the right answer is to try it the wrong way.
224 You cannot design a good system without spending most of your time
225 in contact with the problem. The bad parts about systems are
226 rarely obvious in theory, but often in practice.
2285) Practice tells you that things are good or bad; theory tells you why.
230 Never use theory to design a good system from scratch; only
231 practice can tell whether the system is good.
2336) Everyone must regularly alternate between theory and practice.
235 There is an eternal wheel of system design. Given a system, use
236 practice to discover what is bad, missing, or unnecessary. Then,
237 use theory to fix the bad, add the missing, and remove the
2431) No code should extend beyond 80 characters, most within 55.
2473) A text file is a series of lines, each ending with a newline
250 Corollary: all non-empty text files end with a newline (often
251 hidden by editors). An empty text file does not end with a
2544) One block comment is better than interleaved comments on every line.
2565) Don't name anything you don't have to.
258 This includes conventional names for variables of particular
259 types. For example, the conventional name for a variable of type
260 `path` is `pax`. You should have a good reason for using any
261 other name for a `path`.
263 A more recent convention that follows the same principle is to
264 give the variable the same name as its type.
2666) If it's the same thing, give it the same name.
2687) Humans are good at memorizing.
2708) Abbreviations aren't worth it.
2751) If it's not deterministic, it isn't real.
2772) If it's centralized, it isn't real.
2793) If it's owned by someone else, it isn't yours.
2814) If it's managed by someone else and you can't change who that is, it
2845) If it's not yours, it isn't permanent.
2866) If it's not permanent, it isn't real.
2887) The way it is isn't always the way it ought to be.
290 If you can make it the way it ought to be, do so.
2928) The way it ought to be isn't always the way it is.
294 Some things can't be made more elegant.
296 For every ailment under the sun
297 There is a remedy, or there is none;
298 If there be one, try to find it;
299 If there be none, never mind it.
3019) Timeless software is good software.
30310) System modules should be designed to be frozen permanently;
304 conversely, Urbit consists of that system software which admits of a
30711) The two procedures for achieving timelessness are distillation and
310 Every temporary or contingent feature in a system module should
311 eventually either be removed (distillation) or relaxed into
312 timelessness (generalization). For an example of the result of
313 both procedures, consider the abstraction of the core in Nock and
31612) Standardization is better than perfection.
318 Kelvin versioning stops when we run out of versions, not when
319 every defect has been rectified.
32113) That which cannot be Kelvin-versioned should update fluidly and
324 All incompatible upgrades should provide permanent and automatic
325 upgrade paths. This is principled permanent backward
32814) Humans are interactive and temporal; technology is permanent and
33115) Communities are autonomous.
33316) Sovereignty necessitates understanding.
335 If you don't understand a system you're using, you don't control
336 it. If nobody understands the system, the system is in control.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list