Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The article's a little meandering.

I think the 'waist' in this case is just 'interface', in the general sense - i.e. where two pieces of software meet.

You make the {N-waist-M} composition problem easier because not much detail can leak from N to M and vice-versa. N and M only need to know about e.g. JSON to compile, not each other.

I'd consider a slightly fatter waist to be something like LLVM. My language is wide and complicated, and all the various assembler outputs for different architectures are also wide and complicated, and the idea of LLVM is to bridge the two, but it still feels like it would be a pain to couple my language to LLVM (JSON is narrower than LLVM)



And, reading between the lines o/t article: stable interfaces. The more stuff exists that uses an interface, the slower it tends to evolve. So very-popular interfaces tend to be stable & long-lived by necessity, because 'breaking the world' is not an option.

Come to think of it: that also applies to physical infrastructure: building codes & materials, road networks, AC power grids, gas stations + associated infrastructure to supply those, telecom networks, etc etc. Anything deployed at scale tends to evolve slowly.

Come to think of it: ... [biology]


If I’ve understood then, a narrow waist architecture follows two principles:

- code to an interface not an implementation

- segregate interfaces, don’t overload them with responsibilities


That’s not really an architecture though, it’s just basic principles of modularization.


True, which is perhaps why it's unclear what the difference is between a "skinny waist" and hexagonal architecture, "ports and adapters".


hexagonal architecture gives you the direction of the "waist", not its thickness.

You could have a really skinny interface (one method call only):

    class TaxLogic {
        data = iDatabase.loadOneDatabaseRow(id);
        process(data);
    }

    interface IDatabase {
        loadOneDatabaseRow(id);
    }

    class PostgresDb implements IDatabase {
        loadOneDatabaseRow(id) {...}
    }
But this violates ports and adapters because the logic is on the outside and the database is on the inside.


This is just "loose coupling" expressed with different terminology.

It's not wrong but it's also nothing new - it's about as novel as object oriented programming or DRY.


I don't think it's loose coupling but more: don't build shitty overcomplicated interfaces for simple things.

What it doesn't go into is the fact you don't know if it's a shitty overcomplicated interface or not for about a decade at least, until everyone has built their universe on top of it.

What we have in the article is survivor bias. Things that are exemplars rather than the status quo and that's a good thing. But even considering what it explains, we will still blow our toes off 9 out of 10 times.


>shitty overcomplicated interfaces for simple things.

This is tight coupling.


No tight coupling is a strong immutable dependency. That doesn't necessarily mean complexity. It could mean a leaky abstraction around a simple API, like half of POSIX etc.

What does screw you is things that are hard to reason about and you don't know if you can reason about them until many years have passed or you've tried to replace either side of the abstraction.


Shitty overcomplicated interfaces are directly caused by leaking abstractions.

This is tight coupling.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: