• The Internet Is Not Prosthetic

    The internet is not some other thing, separate from life, it is an abstraction that is very real.

    Fundamentally, I can inspect and see the packets and bits between my computer and the network. I can manipulate the pixels I see in the browser using code. These days more atoms are controlled by bits.

    I can also make a life from the internet. I can read information. I can communicate with people and machines. I’ve made my livelihood from it by arranging bits just so.

    If the internet is real life, how should our relationship with it change? I think we should care a lot more about living a rich digital life in the same manner we think about health, fitness, and gardening. Investing in quality of life ought to include being thoughtful about our digital skills, interests, and safety.

    (Based on a conversation I had with Jake Stein)


  • Getting Started Is a Productivity Hack

    The most reliable way to stop procrastinating is to get started. Not with the intention of completing the task at hand, but doing just a little bit.

    By doing just a little bit to get started, the task you’re dreading becomes approachable. From there, it’s highly likely you’ll complete the whole darn thing.

    The activation energy needed to get going always seems higher if you stare at the mountain ahead of you rather than the next step.

    Even though I know the trick, it still amazes me that it works.


  • You Can't Wake Up if You Don't Fall Asleep

    Asteroid City, Wes Anderson’s latest movie, is a movie about a play where the plot never quite make sense. There is a scene where the playwright is asking a room of actors to be asleep. The movie returns to this moment a few times. On the final time, the director, after telling the lead actor there are no answers for why he burned his hand on purpose, tells everyone “you can’t wake up if you don’t fall asleep.”

    I think this is the whole point of the movie. The story is not the point, but a plot device to articulate the moment of “waking up”. The juxtaposition of sleep or dreaming (or watching a meandering Wes Anderson film), helps us realize reality and wake up. I caught myself noticing reality a little more clearly as that scene was happening.

    Maybe not profound, but artful and interesting!

    See also:


  • Don't Work With People Who Are Perpetually Aggrieved

    It’s difficult to work with someone who always seems to be aggrieved. It’s a sign they will blame others rather than take responsibility themselves. It’s also a sign that they won’t be interested in improving their performance or making adjustments to collaborate better with you or the team.

    If someone is perpetually aggrieved, it’s just a matter of time before they start blaming you for treating them unfairly. If that someone is particularly persuasive (it’s easy to get sucked into), it can have a far reaching, negative pull on everyone.

    See also:


  • Sloppyness Adds Up

    Imagine a busy executive trying to work with multiple people. They’re coming in and out of meetings and working on several projects all day long. They have maybe 15 minutes to concentrate on a thing to try and keep things moving or prevent holding things up. Every time there is a broken link, spelling error, obviously incorrect statement, or something that needs to be double checked, it creates delays and more work.

    A culture of sloppyness and lack of attention to detail multiplies the delays and increases the amount of work across everyone in the organization. Ostensibly small details become very important when multiplied by a large number of people.

    See also:


  • How Long Should You Spend Automating Tasks?

    This chart, adapted from xkcd, tells you the amount of time saved over 5 years based on how much time you are able to shave off of the task. For example, a task that you do daily that you are able to reduce by 30 minutes will save 5 weeks of time over 5 years. This chart can also tell you how much time you should spend on trying to optimize so you don’t spend more time than it’s worth.

    How often
    Time Shaved Off 50/day 5/day Daily Weekly Monthy Yearly
    1 Second 1 Day 2 Hours 30 Minutes 4 Minutes 1 Minute 5 Seconds
    5 Seconds 5 Days 12 Hours 2 Hours 21 Minutes 5 Minutes 25 Seconds
    30 Seconds 4 Weeks 3 Days 12 Hours 2 Hours 30 Minutes 2 Minutes
    1 Minute 8 Weeks 6 Days 1 Day 4 Hours 1 Hour 5 Minutes
    5 Minutes 9 Months 4 Weeks 6 Days 21 Hours 5 Hours 25 Minutes
    30 Minutes 6 Months 5 Weeks 5 Days 1 Day 2 Hours
    1 Hour 10 Months 2 Months 10 Days 2 Days 5 Hours
    6 Hours 2 Months 2 Weeks 1 Day
    1 Day 8 Weeks 5 Days

    See also:


  • OpenAI Incorrectly Handles Dates

    OpenAI GPT models (GPT 4 at time of writing) do not accurately or consistently parse or manipulate dates.

    For example:

    • Giving wrong year: when converting 2023-12-13 to a Unix timestamp and it returns the wrong year (2022 instead of 2023)
    • Wrong timezone: when converting an ISO date, it randomly adds on hours of time even if instructed to use UTC midnight
    • Giving current date: when asked to convert 2023-12-13 into a timestamp and it sometimes gives today’s date

  • Langchain Self Query With Dates

    Self querying by date using LangChain doesn’t work well. The default schema used for parsing natural language into the internal representation of langchain for querying a vector store does not work with dates because it uses the wrong type (it tries to use a dict but you can only filter using integers or strings).

    To fix that, create your own “structured request” schema for use with a vector DB (like ChromaDB).

    TASK_METADATA = [
        AttributeInfo(
            name="title",
            description="The title of the task, meeting, or heading",
            type="string",
        ),
        AttributeInfo(
            name="created_date",
            description="The timestamp the task or meeting was created formatted as an integer",
            type="int",
        ),
    ]
    
    TASKS_SCHEMA = """\
    << Structured Request Schema >>
    When responding use a markdown code snippet with a JSON object formatted in the following schema:
    
    ```json
    {{{{
        "query": string \\ text string to compare to document contents
        "filter": string \\ logical condition statement for filtering documents
    }}}}
    ```
    
    The query string should contain only text that is expected to match the contents of documents. Any conditions in the filter should not be mentioned in the query as well.
    
    A logical condition statement is composed of one or more comparison and logical operation statements.
    
    A comparison statement takes the form: `comp(attr, val)`:
    - `comp` ({allowed_comparators}): comparator
    - `attr` (string):  name of attribute to apply the comparison to
    - `val` (string): is the comparison value
    
    A logical operation statement takes the form `op(statement1, statement2, ...)`:
    - `op` ({allowed_operators}): logical operator
    - `statement1`, `statement2`, ... (comparison statements or logical operation statements): one or more statements to apply the operation to
    
    Make sure that you only use the comparators and logical operators listed above and no others.
    Make sure that filters only refer to attributes that exist in the data source.
    Make sure that filters only use the attributed names with its function names if there are functions applied on them.
    Make sure that filters only use timestamp in seconds as an integer when handling date data typed values. If you need to convert them, translate the date into a unix epoch timstamp with UTC timezone and double check that it is the correct year. NEVER use the `eq` operator for timestamps, if the requested date is a single day, use the `gte` operator for the requested date AND a `lte` operator for the requested date plus one day. Be very careful with dates.
    Make sure that filters take into account the descriptions of attributes and only make comparisons that are feasible given the type of data being stored.
    Make sure that filters are only used as needed. If there are no filters that should be applied return "NO_FILTER" for the filter value.\
    """
    TASKS_SCHEMA_PROMPT = PromptTemplate.from_template(TASKS_SCHEMA)
    
    prompt = get_query_constructor_prompt(
        document_contents="My tasks",
        attribute_info=TASK_METADATA,
        schema_prompt=TASKS_SCHEMA_PROMPT,
    )
    output_parser = StructuredQueryOutputParser.from_components()
    query_constructor = prompt | TASKS_LLM | output_parser
    

    Unfortunately, this only works for a very limited number of cases because OpenAI doesn’t handle dates well.


  • Lorca Model 1 Review

    The Lorca Model 1 is a romantic watch. It blends elements of several iconic watches that remind me of a time I never lived through. It’s a thoughtful combination of specs and details that make the watch charming and unique.

    The dial is fantastic. The sword hands end in a fine point that gives the precise feeling to telling the time, which adds to the legibility. The GMT hand stands out nicely with its diamond head that matches the 12 o’clock marker on the bezel. The sector lines bisect the dial in a subtle way. The indices play a neat trick in the light where they appear darker than the hands and give off a slightly grayish-brown color that makes it match nicely with a leather band. The minute track markers add contrast to the indices, which further highlights the different color tones on the dial.

    About the minute trackβ€”the longer I wear the watch, the more it’s clear to me that this is the most important element of the dial. In some lights, where you can’t see it as well, the dial looks plain, but in daylight, it pops out beautifully and brings the other elements together. The minute track is also why it’s impossible to place your finger on the exact combination of 1950s inspiration.

    While some complain about the typeface chosen for the 24-hour fixed bezel, I think it suits the watch just fine. It appears like a superscript Garamond to my eyes, which I find pleasing and gives the watch a bookish vibe. The typeface and use of a diamond at the 12 o’clock and GMT hand also reminds me of a deck of cards.

    The finishing is very good but not excellent. The applied index at 12 o’clock is ever so slightly off dead center with the vertical sector line. The date wheel comes across flat and paper-like (maybe the white needs some sort of texture to it?).

    The lume needs some charging to be visible at night. This is probably a weird “me” thing, but I like to check the time when I wake up in the middle of the night. The Sinn U50 doesn’t need any special charging to last the entire night though there’s a lot more lume to work there.

    Wearing the Lorca Model 1 fits almost any situation. The beads-of-rice bracelet dresses it up a bit (though not as much as the Cartier Tank), but putting it on a strap makes it look more casual. I prefer it on the bracelet, which also happens to be extremely comfortable.

    Now that I’ve traveled with the watch, I can say that having a GMT complication is not that useful in practice. Converting 24-hour time to 12-hour time is still slow (for me). It’s easy to misread the hour when it’s late in the hour and there isn’t much space between ticks. The best way to read the GMT hand on the Lorca is to focus on the tip of the diamond shape, not the large plot of white lume.


    The Lorca Model 1 deserves more attention. Of all the vintage-inspired modern watches, this one stands out to me. You can tell how agonizing the design process must have been when you inspect the tiny details all over the watch. By my favorite definition of good taste, the sum of all these details works beautifully together.


  • High Growth Companies Grow Quadratically

    Most runaway successes we hear about often have some mythology of the moment the founding team unlocked exponential growth. Examples include Slack, Facebook, and HubSpot. The only problem is, most of these growth stories are not actually exponential but closer to “an initial period of quadratic growth followed by linear growth”.

    In The myth of exponential hypergrowth from A Smart Bear, the author argues that this distinction is important because we need better mental models for how to achieve high growth. To do that, consider successful products and marketing campaigns follow an elephant curve (steap rise, followed by a drawn out decline) and the idea is to stack these over time. Only then can you create multiple activities that sustain high growth.

    See also:


  • A Moat or a Long Bridge

    In business strategy you’ll often hear a competitive advantage described as a moat, but most moats are more like a long bridge. The moat is the thing that prevents others from easily replicating another business. A long bridge takes a time build and is effectively a moat if it’s impractical to catch up or simply makes it a schlep.

    In a sense, generative AI is a bridge shortening technology opening up many businesses to greater competition. Of course, replication does not a business make, but what happens when a motivated group of smart people uses better tools to build a competitive offering in a short-bridge amount of time?

    See also:


  • Like/Wish Feedback

    A simple way to deliver effective feedback to an employee is the use the like/wish framework. Say the specific actions you liked about their employees performance and then say which specific actions you wish they would have done differently (emphasis on specific actions!). This leads to productive conversations about how to adjust performance and clear up any misunderstandings.

    From The Great CEO Within.


  • Use Git Logs to Search for Deleted Content

    If you’ve ever accidentally deleted something from a file and want to recover it using git you can search the full history for a string.

    This will return any commit that includes the string in the diff:

    git log -i -p -S "my search term here"
    

    I’ve used this several times now to recover some previous code and prose I had written many commits ago.

    See also

    • This is especially useful not that I use git as the backend for org-roam mobile
    • Working Copy is surprisingly useful for bringing git workflows to iOS