• The Ringelmann Effect Shows Groups Become Less Productive as They Grow

    An inverse relationship exists between group size and productivity which shows that group effort does not necessarily lead to increased effort from the group members.

    In an experiment, a group was asked to pull a rope. As more people were added, the average performance significantly decreased. This seems to show that each participant felt their own efforts were not critical and further studies showed that motivational losses were largely to blame for an individual’s decline in performance.

    See also:

    • Baumol’s cost disease is similar in that salaries can rise without any material gain in productivity simply salaries of other roles went up.
    • Larger informal groups can have other negative consequences such as opaque decision making and lack of accountability.

  • Nobody Wants to Run Their Own Server

    The original idea of the web was that everyone would be both a producer and a consumer. They would run their own server and connect to the servers of others.

    It’s difficult to run your own server. You need to figure out how to get it working. You need networking knowledge to connect it. You need to keep it up to date with new versions of software and security updates. You might even need to scale it which requires even more expertise.

    What we learned from Web2 is that no one wants to run their own server—even those with the technical skills to do so. We would rather have someone else figure out how to keep it running all the time and pay them to host our website or content.

    Read Web3 First Impressions by Moxie Marlinspike.

    See also:

    • This is a reason why centralized platforms are popular—convenience is king
    • Large centralized platforms have outsized power which raises demand for decentralized systems
    • Web3 suffers from the same problem, no one hosts their own blockchain and so you end up with centralized platforms all over again

  • Distributed Apps Are Centralized

    Blockchains are a server technology. They don’t live on the client and things like a web frontend to a dApp can’t perform CRUD operations without a server. While it’s possible to host your own node, in reality nobody wants to run their own server, not even the ones with the technical skills to do it.

    Web3 developers building a frontend to their dApps end up using a platform like Infura to provide web APIs that proxy operations to the underlying blockchain. This contradicts the whole point of a being trustless because there’s now a few centralized platforms (private companies) that need to be trusted and relied on.

    Read Web3 First Impressions by Moxie Marlinspike.


  • Defadvice Is Text Editor Superglue

    The Emacs advice system lets you modify the code running Emacs in a simple way. For example, if you wanted to change one line in a package you use to do something different or fix a bug before the maintainers release a new version, you can “advise” code to do what you want.

    Here’s a recent example from my init.el that wraps a function to fix a bug in my setup:

    ;; ox-hugo doesn't set the `relref` path correctly so we need to
    ;; tell it how to do it
    (defun my/org-id-path-fix (strlist)
      (file-name-nondirectory strlist))
    
    (advice-add 'org-export-resolve-id-link :filter-return #'my/org-id-path-fix)
    

    See also:


  • Good Explanations Are Hard to Vary

    A good explanation can not be modified or molded to fit when new information contradicts it. It predicts situations that are both known and unknown. The domain of its meaning and applicability is not yours to specify.

    Contrast that to a bad explanation—like a myth of winter caused by Persophone visiting Hades—which can be altered to fit new observations while resulting in the same prediction. It has no error-correcting mechanisms and the myth can always be constrained or expanded to apply to any situation.

    See also:


  • Justificationism Secures Ideas Against Change

    One way to answer “how do we know…?” is to justify one’s belief by reference to an authoritative source or cornerstone of knowledge. This is, in effect, saying “by what authority do we claim…?” which seeks endorsement in order to have certainty. Justificationism as a theory of knowledge therefore resists change (or at least delays in a form of path dependence).

    Accepting authority as a source of knowledge also means accepting any other theories that stem from said authority.

    Few things—if any—that are true in the absolute sense and the success of science proves that. Simply look at all the things we knew to be true that ended up being incorrect or misunderstood. Then observe all the progress since the 17th century compared to prior human history.

    See also:


  • The GUNMAN Project Was the Catalyst for a Digital Arms Race

    In 1984 it was discovered that the Soviet Union was spying on communications from US embassies. It was previously believed they only had audio bugs which could be swept for. However, the GUNMAN project revealed a remarkable new form of digital surveillance that used bugged typewriters to intercept plain text communications (typed on physical paper). They later found out this was in practice for the last 7 years.

    The impact of the discovery was far reaching. The NSA became an important agency, developing anti-tamper devices. New groups formed to create offensive capabilities. Some would alter argue that this was the catalyst cyber-warfare and a digital arms race.

    Read Learning from the Enemy by the NSA.


  • Trends Are Not Explanations

    Extrapolating from past data points is not an explanation. Building your confidence that something that will happen—like Bayes Theorem—is useful for descrete, observable problems, but fails to reveal the truth. It’s the equivalent of saying “because it’s always been that way” which is a flawed way of reasoning about the world.

    For example, let’s say you are trying to predict the temperature of a beaker water. You start to turn up the heat on a burner and, based on previous data points, you expect the temperature to rise. It correlates well—heat goes up, water temperature goes up. Until it hits the boiling point and the water temperature remains constant. Trends are not sufficient to explain what’s going on here because it doesn’t explain the idea what is truly happening.

    Listen to The Beginning of Infinity part 1 on Naval Ravikant’s podcast.

    See also:


  • We Reduce Anxiety With Activity

    When things get challenging or stressful, we attempt to reduce our anxiety by doing things (sometimes anything). By doing things we feel like we are making progress. However, this doesn’t solve the problem at and can even make it worse.

    This is an important habit to interrupt because it’s ineffective—the real problem still exists no matter how busy you are. For leaders, it’s important to be able to sit with this discomfort and find a solution rather than try to mitigate with activity if only to make yourself feel better.

    See also:


  • Keeping React Hooks With UseState in Sync With Props

    An annoying footgun with React hooks is using useState with an initial value from props. It might appear like useState will be called each render, but it doesn’t (the bad kind of magic). Instead, it will run once when the component is initially rendered and you will run into stale read bugs when you rely on props to re-render the component with updated data.

    To workaround the issue, you need to use useEffect to update the stateful data.

    function MyComponent(props) {
      const [user, setUser] = React.useState(props.user);
    
      // This is needed or you will get a stale read when props.user
      changes React.useEffect(() => {
        setUser(props.user);
      }, [props.user]);
    
      return (
        <h1>Ugh that's easy to forget {user.name}</h1>
      )
    }
    

    This is annoying because it breaks the mental model of React Hooks as “just functions”. Maybe that’s still true, but they’re more like “functions with a lifecycle and state that you can’t easily inspect”.

    An alternative (found in this StackOverflow thread) is to wrap this behavior in a custom hook.

    import {useEffect, useState} from 'react';
    
    export function useStateWithDep(defaultValue: any) {
      const [value, setValue] = useState(defaultValue);
    
      useEffect(() => {
        setValue(defaultValue);
      }, [defaultValue]);
    
      return [value, setValue];
    }
    

    Then you could rewrite the original example like so:

    function MyComponent(props) {
      const [user, setUser] = useStateWithDep(props.user);
    
      return (
        <h1>Yay no stale reads when props change {user.name}!</h1>
      )
    }