1. 5

    Some thoughts on horizontal overflow:

    If you ever have trouble tracking down what element is causing overflow, add this rule in the browser inspector:

    * { outline: thin solid red }
    

    This makes the bounding boxes of every single element visible. Very helpful.

    The author mentioned using work-break: break-word. I have an open question on that rule: Is there any reason not to set it on the body on most sites? I’ve gone on quests to remove scrolling from user-entered content, and I end up setting word-break in a ton of different places. I’m not sure of the trade-offs of just setting it globally.

    1. 2

      Some googling reveals that break-word is not CJK-aware, but I’m no expert myself. I only publish English content, so this is fine for me :)

    1. 3

      The article hypothesizes:

      1. The compilers will achieve great performance
      2. The compilers can be made to stop breaking constant-time properties of the code

      These two seem at odds with each other. Even the breakage example in the article is caused by an optimization pass.

      1. 4

        The author mentions one pass that breaks the constant-time properties: the “x86-cmov-conversion.” He proposes extending the compiler to allow programmers to selectively disable this pass on certain variables.

        Now, all of this counts on a sufficiently smart compiler™, but it seems to me that this would have no performance impact; the compiler pass would only be disabled in the case of variables marked as secret, and these variables were already not using the pass.

        1. 2

          Of course if human can write fast constant-time code, then sufficiently smart compiler can too. But in practice it’s very hard. The stricter the semantics, the harder it is to optimize. Compilers split optimizations into passes, because that’s a way to have manageable complexity, but that makes individual passes less smart about global view and higher-level semantics of the code.

          Passes are designed to be independent for simplicity, and yet interact, to achieve better results together. For example, common subexpression elimination can leave unused code behind, and rely on dead store elimination to clean this up. But later dead store elimination won’t be aware whether it’s eliminating unused code of folded subexpressions, or removes an attempt to clear secrets from memory. And you could try to add more metadata to track these things across passes, but preserving that metadata throughout transformations makes things harder (e.g. LLVM already struggles with preserving aliasing info, which prevents Rust from optimizing better).

      1. 5

        I really wish that instead of data classes, which force me to invent types for my data, we’d get a nice built-in syntax for named tuples that wouldn’t require importing a module and repeating the record name twice.

        1. 3

          I really wish that instead of data classes, which force me to invent types for my data, we’d get a nice built-in syntax for named tuples that wouldn’t require importing a module and repeating the record name twice.

          Well, you still have to specify the types of your data and do an import, but there is a nice alternative syntax for named tuples if you want to avoid repeating the record name:

          class Component(NamedTuple):
              part_number: int
              weight: float
              description: Optional[str] = None
          
          1. 1

            Thanks, I didn’t know about the capitalized NamedTuple.

          2. 2

            I agree, the types seem like an unnecessary complication.