• 0 Posts
  • 21 Comments
Joined 2 months ago
cake
Cake day: August 12th, 2026

help-circle





  • Sorry, I misread your earlier comment. In my reply when I said “mental model” I meant your mental model of the thing you’re trying to build, not of the tool.

    The output of LLMs is defined as much as optimizing compilers is

    It definitely is not. Compilers perform a very well defined transformation from input to behavior (not 100% defined, but as close as practical politics can get it). A compiler that “optimizes” by violating that definition is a broken compiler. (The 1% that’s undefined causes a lot of discussion, which takes place while everyone relies absolutely on the other 99% being correct.)

    Whereas in most cases you can’t even tell if the output of an LLM did achieve desired behavior, because the input isn’t precise enough to determine the desired behavior in the first place. LLMs not backstopped by deterministic tools (compilers, test harnesses, proof engines, even just plain reliable arithmetic) in a loop have a hard time even making artifacts that are functional.


    score 1 · canonical


  • I agree it’s a spectrum, but at some point just saying “it’s a spectrum” erases the interesting distinctions. The boundary of impreciseness that can’t be crossed by the “compiler” used to be limited to a fairly narrow range. Think of the possible abstracts of a paper in a PLT journal.

    But with an LLM you can literally say nothing but “make a website for scheduling a kids’ soccer league” and it will do it. That is, even if I had a mental model, I didn’t tell the “compiler” what it was. Not only that, while it’s working the “compiler” can ask me what my mental model is, rather than just telling me the model I gave it is incomplete or inconsistent and stopping.

    And where it really gets into a new category for me is that the output of the compiler isn’t even defined. You could just as well say “make a presentation for a soccer league” or “get the accounting in order for my soccer league” or “automatically answer questions about our soccer league”. The analogy just seems to completely fall apart at that point.


    score 1 · canonical


  • I’d say the closer analogy to CNC is the compiler. The input to CNC is still a precise transformation of the intent of the designer. It does the work faster but it’s the same work. On the other hand, sometimes a human needs to precisely define the lower level, doing some manual filing because the cutting tool won’t fit in the space, or writing some assembly because the compiler doesn’t know how to do indirect threaded code.

    As a craftsperson or client you may look at the result and miss the imperfections (the “hand”, it’s called) of the old way: the curvature is implausibly perfect, or the assembly is too clever to have been written by a human. But you can always see the human intent everywhere.

    LLMs, on the other hand, take imprecise descriptions and turn them into precise output by making stuff up instead of waiting for the human to fill the gap. It’s the “imprecise description” part that’s really new. I don’t know of a very good analogy for that in any pre-existing tool.


    score 1 · canonical







  • I’m sorry I used the imprecise term “relational algebra” to refer to the semantic model of SQL. My point is that the expression tree of a SQL statement is not made of loops, it’s made of table expressions (with join operations), column references, aggregates, filters, CTEs, etc. To oversimplify again, it’s mostly about set operations, not loops.

    Of course in the query planner it gets turned into something executable, which will sometimes involve loops, but that’s not the model of the language itself. Python expressions get turned into bytecode so they can be executed, but you don’t write Python as a way of expressing bytecode.

    To be concrete, the semantic expression tree of

    select users.id, (select sum(posts.likes) from posts where posts.user_id = users.id) from users
    

    isn’t

    R=[]
    for (u in users) {
      x=[]; for (p in posts) { if (p.user_id = u.id) x+=p.likes }
      R+=(u.id, sum(x))
    }
    return R
    

    it’s more like

    users
      .join(posts
        .filter(user_id=users.id)
        .groupby()
        .project(sum(likes) as sum))
      .project(users.id, posts.sum)
    

    (Which in 2024 would be a much more natural way to write it in the first place, which is why I mentioned LINQ.)

    In my experience writing and helping others to write SQL, if you write it thinking that you’re writing loops, it’s not as effective as if you write it thinking about set operations, especially as the queries get more complex. Not to mention that the error messages will actually make sense! To me this is like writing Rust thinking about structs, traits, borrows, etc. rather than thinking about assembly (99% of the time).

    I’m not a SQL expert (though I have dug into the PG query planner on occasion) so maybe I’ve been doing this wrong, but it does seem to work.


    score 3 · canonical