Lecture: end-to-end arguments

preparation

discussions

For JOS, in the page-fault handler/fork thing, we provide a “correct” low-level implementation that is simple and we allow users to specify their own page-fault handlers. This is because users may want dumbfork, or copy-on-write fork, and although we could implement these at the lower-level, we trust that the user knows what they want and need. For filesystems, we need to check the superblock and make sure it’s not corrupted. This applies to the end-to-end argument because the hardware may provide some kind of function to do this but we can’t be sure that this is totally reliable.

Anonymous

The end-to-end argument argues that no compiler more sophisticated than an assembler should be used. Any decisions made by the compiler in the language design will always be suboptimal for some application.

If your language is object oriented, then some applications will have a need for features that run counter to your model, for example a specific flavor of multiple inheritance in a language that only supports single inheritance or one flavor of multiple inheritance.

If your language has procedures, some some applications will need to use a different calling convention to interface with other parts of the system, or need to use continuations or closures when the language doesn’t support them.

Furthermore, applications which do not need these convenience features will still be burdened with overhead arising from supporting the convenience features (How long is a Java hello world program?).

Therefore, compilers should support only the minimal features needed to translate from a human-readable language to machine language, i.e. every compiler should be no more than a dumb assembler, and all applications should be written in assembly so as to use exactly the abstractions that make sense for that application.

Anonymous

Last summer I interned at X Computer (anonymized). X is a game engine with a concept of a scene. Entire scenes were stored in a single file, so naturally this results in difficult to resolve merge conflicts for game devs. My project was to create a tool to resolve merge conflicts for scenes. There existed one tool that was already built that could resolve scenes, but couldn’t accept any user input. Due to this limitation, it would always attempt to resolve conflicts. I built my tool, which could accept user input, on top of this tool. Unfortunately, when attempting to resolve conflicts on large files, the lower level tool would take a while to process the scene, resulting in a long load time for my merge tool. By allowing the lower level tool to do a worse job, my tool could load faster. The extra work done by the lower level tool was unnecessary because I would always prompt the user for input on how to resolve each conflict in a scene, instead of relying on a complex tool to resolve it automatically. This was a case where making the lower level tool do a worse job actually made the overall application better.

Anonymous