Comment by pron
2 days ago
> Where type system complexity entails a tradeoff between the complexity of the language and how powerful the language is in allowing you to define abstractions.
I don't think that's right. The level of abstraction is the number of implementations that are accepted for a particular interface (which includes not only the contract of the interface expressed in the type system, but also informally in the documentation). E.g. "round" is a higher abstraction than "red and round" because the set of round things is larger than the set of red and round things. It is often untyped languages that offer the highest level of abstraction, while a sophisticated type system narrows abstraction (it reduces the number of accepted implementations of an interface). That's not to say that higher abstraction is always better - although it does have practical consequences, explained in the next paragraph - but the word "abstraction" does mean something specific, certainly more specific than "describing things".
How the level of abstraction is felt is by considering how many changes to client code (the user of an interface) is required when making a change to the implementation. Languages that are "closer to the underlying machine" - especially as far as memory management goes - generally have lower abstraction than languages that are less explicit about memory management. A local change to how a subroutine manages memory typically requires more changes to the client - i.e. the language offers a lower abstraction - in a language that's "closer to the metal", whether the language has a rich type system like Rust or a simpler type system like C, than a language that is farther away.
The way I understood the bit you quoted was not as a claim that more complex type system = higher abstraction level, but as a claim that a more complex type system = more options for defining/encoding interface contracts using that language. I took their comment as suggesting an alternative to the typical higher/lower-level comparison, not as an elaboration.
As a more concrete example, the way I interpreted GP's comment is that a language that is unable to natively express/encode a tagged union/sum type/etc. in its type system would fall on the "less complex/less power to define abstractions" side of the proposed spectrum, whereas a language that is capable of such a thing would fall on the other side.
> which includes not only the contract of the interface expressed in the type system, but also informally in the documentation
I also feel like including informal documentation here kind of defeats the purpose of the axis GP proposes? If the desire is to compare languages based on what they can express, then allowing informal documentation to be included in the comparison renders all languages equally expressive since anything that can't be expressed in the language proper can simply be outsourced to prose.
But that's why the word "abstraction" is the wrong choice. The ability of a language to express detail and the ability of a language to have high abstractions are two different things, and when we talk about high and low level languages, I claim that what we intuitively mean is abstraction, not the expressivity of contracts. For example, ATS's contracts are virtually unlimited in their expressivity (it makes Rust indistinguishable from C by comparison), yet few would say it's particularly high-level. On the other hand, Scheme or even JavaScript can express few contracts, and yet are considered high level. I think that when we think of a high-level language, what we have in mind is a language where programs typically need to concern themselves with fewer details. This corresponds more with abstraction rather than "contract expressiveness".
> The ability of a language to express detail and the ability of a language to have high abstractions are two different things, and when we talk about high and low level languages, I claim that what we intuitively mean is abstraction, not the expressivity of contracts.
I think you're right with respect to discussion about abstractions in the context of high-/low-level languages, but again, I feel like what GP was trying to get away from the high-/low-level framing in the first place and might have meant something different when they used the word "abstraction".
Perhaps this is me misinterpreting things, but I took GP's use of "abstraction" as something more along the lines of what it might mean in "this library's abstractions are designed poorly/well because they are easy/hard to misuse and/or understand". In that context I think "abstraction" is more about the precise interface contract and its quality - e.g., a poorly-chosen abstraction might not reflect the domain it ostensibly represents well because it permits actions/behaviors that don't make sense for that domain, and that in part might be due to a language being unable to express a more appropriate contract. I feel that better matches GP's high-/low-type-system-complexity axis.
1 reply →