<story><title>On Scaling Mental Models</title><url>https://buttondown.email/hillelwayne/archive/on-scaling-mental-models/</url></story><parent_chain><item><author>TuringTest</author><text>The problem with powerful languages is they&amp;#x27;re great for allowing you to create new abstractions, but they&amp;#x27;re terrible at piercing that abstraction and let you know what&amp;#x27;s going on inside when you need it (such as, when learning what the abstraction means when you find it for the first time).&lt;p&gt;Current modern languages are built around the false dicotomy  that you have to choose between one of two representations, like those in the provided example:&lt;p&gt;1. mydict1.merge(mydict2, handle_duplicates=(key, v1, v2) =&amp;gt; v1 + v2)&lt;p&gt;2. mydict1 + mydict2&lt;p&gt;A mid-level language will use the first style so that programmers will know what&amp;#x27;s going on, but then the team will be stuck to using that style everywhere even when they already understand that it&amp;#x27;s &amp;quot;oh, just adding two dictionaries&amp;quot;. Powerful languages let you use the second style but then, as the article explains, it&amp;#x27;s hard for a new programmer to tell what&amp;#x27;s the mental model behind that complex operation.&lt;p&gt;A good powerful Lisp-like language should allow you to build the second abstraction in terms of the first, and use the simple syntax everywhere, but then switch between both representations easily.&lt;p&gt;I.e. you should be able to &lt;i&gt;inspect&lt;/i&gt; the meaning of the more abstract syntax by expanding its definition in place and see how it works in context. Programmers typically address this shortcoming with support of powerful (yet ad-hoc) IDE&amp;#x27;s runtime debugging tools. But why that approach is not integrated into the language itself, I have no idea.</text></item></parent_chain><comment><author>hinkley</author><text>My most recent Orwellian moment was reading about an old heuristic algorithm with high complexity that has been abandoned as the middle ground between a simpler heuristic and much more complex ones because of its computational complexity.&lt;p&gt;The problem as I see it is in how they represent the data in a way that makes one think of linear algebra.  Refinements brought the naive original implementation down to cubic time, and the literature, as far as I can tell, stops there.&lt;p&gt;But here’s the thing, when I tried to unpack the logic to figure out what is actually going on under the hood, I realized that a quadratic subproblem could be restated as a sorting problem. Sorting is very much nlogn these days, if not lower due to radix sort being an option.&lt;p&gt;Which means that this heuristic has the same computational complexity as the naive solution. I’m not saying I’ve discovered anything new, except perhaps that this algorithm is homomorphic to another one.  It’s just that it’s so stuck in one representation that you can’t see it for what it is unless you stare pretty hard at it.</text></comment>
<story><title>On Scaling Mental Models</title><url>https://buttondown.email/hillelwayne/archive/on-scaling-mental-models/</url></story><parent_chain><item><author>TuringTest</author><text>The problem with powerful languages is they&amp;#x27;re great for allowing you to create new abstractions, but they&amp;#x27;re terrible at piercing that abstraction and let you know what&amp;#x27;s going on inside when you need it (such as, when learning what the abstraction means when you find it for the first time).&lt;p&gt;Current modern languages are built around the false dicotomy  that you have to choose between one of two representations, like those in the provided example:&lt;p&gt;1. mydict1.merge(mydict2, handle_duplicates=(key, v1, v2) =&amp;gt; v1 + v2)&lt;p&gt;2. mydict1 + mydict2&lt;p&gt;A mid-level language will use the first style so that programmers will know what&amp;#x27;s going on, but then the team will be stuck to using that style everywhere even when they already understand that it&amp;#x27;s &amp;quot;oh, just adding two dictionaries&amp;quot;. Powerful languages let you use the second style but then, as the article explains, it&amp;#x27;s hard for a new programmer to tell what&amp;#x27;s the mental model behind that complex operation.&lt;p&gt;A good powerful Lisp-like language should allow you to build the second abstraction in terms of the first, and use the simple syntax everywhere, but then switch between both representations easily.&lt;p&gt;I.e. you should be able to &lt;i&gt;inspect&lt;/i&gt; the meaning of the more abstract syntax by expanding its definition in place and see how it works in context. Programmers typically address this shortcoming with support of powerful (yet ad-hoc) IDE&amp;#x27;s runtime debugging tools. But why that approach is not integrated into the language itself, I have no idea.</text></item></parent_chain><comment><author>hhas01</author><text>Bad example is bad example. Programmers are awful for using algebraic symbols to describe non-algebraic semantics. Algebra is already its own language; a lingua franca of math. If you’re abusing it for a different purpose then you’re doing both of them wrong.&lt;p&gt;Otherwise, article is basically arguing we should drag everyone down to the lowest-common denominator “to be safe”, rather than allowing individuals and groups to raise themselves up as appropriate in order to tackle their given problems more effectively.&lt;p&gt;That’s group-think, authoritarianism, and reducing expert knowledge workers to anonymous plug-n-play “human resources”. What’s the software equivalent to “Churnalism”? Because that’s how you get the software equivalent to “Churnalism”.&lt;p&gt;Now, if you want to talk about the criticality of Human Communications, and how utterly atrocious many programmers are at it, even amongst their own (never mind with “outsider” stakeholders like users and management), then I’m all on board with that discussion. Good and bad use of abstraction (trade jargon), effective knowledge “transfer” (really reconstruction), and successful team collaboration (especially heterogeneous teams, which are vital to solving the &lt;i&gt;actual&lt;/i&gt; problem at hand). This is epically important stuff, and this profession has so much yet to learn.&lt;p&gt;But rationalizing away “this is how we’ve always done it so this is how we will always do it”? Don’t be surprised when the rest of the world treats you as cheap, easy, disposable code-monkeys, paying you peanuts and zero respect. That’s the deal you bought into yourselves, and you have no-one to blame but yourselves.</text></comment>