On Scaling Mental Models
buttondown.email
On Scaling Mental Models
1–10 of 60 posts
Re: On Scaling Mental Models
#2Taking the example of adding maps, you (where "you" means the language designers or language community) just need to define what `+` means for primitive types and the composition follows naturally. What does adding maps mean then? It means adding together the primitive types found under each key. If everyone agrees 1) there is a `+` operation and 2) what it means for primitives, there isn't much room for confusion. At some point you might want to give this concept a name and then you have basically reinvented monoids.
This is one of the differences between my experience in untyped functional languages (primarily Scheme) and inexpressive languages (primarily Java) and typed functional languages (primarily Scala). In the former each abstraction was a perfect snowflake crafted to the specific situation. In the latter we just reuse existing abstractions. The problem with the former is you have to learn the meaning and idiosyncrasies of each new abstraction. In the latter you can leverage your existing knowledge in new domains.
Re: On Scaling Mental Models
#3Re: On Scaling Mental Models
#4Re: On Scaling Mental Models
#5During the implementation process some knowledge is lost. What the author is describing is a kind of merge operation. If you would know the semantic meaning of the data that is being represented, it is rather obvious what choice should be made. When a number represent a quantity, it is obvious they should be added, but when a number is a kind of identifier, like an article number, it is obvious that they should not be added. And yes, maybe in that case the number should have been better represented as a string. In the process of implementing it is often smart to represent it like a number, because it is much easier to deal with a 64-bit number than a variable length string.
Re: On Scaling Mental Models
#6Re: On Scaling Mental Models
#7Articles like this are missing an important point. Namely, that generic data structures in programming languages are used to represent rich semantic data models. This is done by a process that I would call 'implementing'. It is a mapping of a certain semantic model to, often a rather limited, set of primitives. Some languages, are completely optimized for one type of data structure. Take for example the relational da…
In a modern typed language you wouldn't represent an ID as an integer or a string, you'd represent it is an ID. Then define addition as whatever makes sense for IDs. This can mean not defining the operation at all, in which case you can't compile code that tries to add IDs. This is the viewpoint that statically typed FP people take, and the viewpoint that languages like Rust take.
Your view is more inline with untyped languages or languages with weak type systems like Java or Go. (Arguably Java is changing as it adopts more modern features but I don't think the culture is changing as rapidly as the language.)
Re: On Scaling Mental Models
#8Current modern languages are built around the false dicotomy that you have to choose between one of two representations, like those in the provided example:
1. mydict1.merge(mydict2, handle_duplicates=(key, v1, v2) => v1 + v2)
2. mydict1 + mydict2
A mid-level language will use the first style so that programmers will know what's going on, but then the team will be stuck to using that style everywhere even when they already understand that it's "oh, just adding two dictionaries". Powerful languages let you use the second style but then, as the article explains, it's hard for a new programmer to tell what's the mental model behind that complex operation.
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.
I.e. you should be able to inspect 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's runtime debugging tools. But why that approach is not integrated into the language itself, I have no idea.
Re: On Scaling Mental Models
#9The problem is programmers crafting the language to their own mental model. One solution is languages that don't allow much abstraction. The other solution is to craft a shared mental model. This latter approach is the more powerful in my opinion. Taking the example of adding maps, you (where "you" means the language designers or language community) just need to define what `+` means for primitive types and the compo…
Re: On Scaling Mental Models
#10The problem is programmers crafting the language to their own mental model. One solution is languages that don't allow much abstraction. The other solution is to craft a shared mental model. This latter approach is the more powerful in my opinion. Taking the example of adding maps, you (where "you" means the language designers or language community) just need to define what `+` means for primitive types and the compo…
I can't parse your last paragraph, in which "Scheme and Java and Scala" (3 things) are compared as "former vs latter" (2 things).
The former is Scheme and Java. The latter is Scala.