<div style="font-family: Arial, sans-serif; font-size: 14px;">I developed and maintain a units of measurement library. The target audience is educational - predominantly high school students with minimal experience with Java or programming in general - so its API must be accessible, readable, and type safe for anyone to use it. Otherwise they would just use a raw <code>double</code>​ and try to keep track of unit conversions themselves (usually in code comments, and often incorrectly - thus the library).</div><div style="font-family: Arial, sans-serif; font-size: 14px;"><br></div><div dir="auto" style="font-size: 14px;"><span style="font-family: Arial, sans-serif;">The core part of the library is a <code>Unit</code>​ </span><font dir="auto" face="Arial, sans-serif">class with a recursive self type to make unit interactions and conversions type safe, and a generic <code>Measure</code>​ record that holds values in terms of an arbitrary unit. <code>Unit</code>​ is subclassed for concrete unit types (think distance, time, temperature, and so on) and also mathematical types representing quotient and product types (think velocity, area, or force). The self type is necessary to allow methods in the unit class to have a factory method for returning measurements in terms of itself, and for providing dimensional analysis in the measure record, but causes myriad problems with type inheritance more than one level deep.</font></div><div dir="auto" style="font-size: 14px;"><font dir="auto" face="Arial, sans-serif"><br></font></div><div dir="auto" style="font-size: 14px;"><font face="Arial, sans-serif">This class setup works very well for modeling units and their interactions. A velocity can be represented as <code>Quotient<Distance, Time></code>​; force can be represented (rather verbosely) as <code>Product<Mass, Quotient<Quotient<Distance, Time>, Time>></code>​. The problem is that the type compositions only represent the underlying building blocks; they completely fail to express what the results of the compositions actually mean. Imagine a new programmer given the choice between representing torque as <code>Product<Product<Mass, Quotient<Quotient<Distance, Time>, Time>>, Distance></code>​ with the type-safe unit API or with a raw <code>double</code>​ - they'd (rightly) dismiss the unit outright as being too complex and just use a raw <code>double</code>​, trying their best to handle unit safety on their own. Even though the library can express unit types correctly and exhaustively, it cannot do so ergonomically, and so the users who would most benefit from unit safety would never use it.</font></div><div dir="auto" style="font-size: 14px;"><font face="Arial, sans-serif"><br></font></div><div dir="auto" style="font-size: 14px;"><font face="Arial, sans-serif">However, nobody would run screaming from a type simply named <code>Torque</code>​. But here we run into limitations in the type system: <code style="scrollbar-width: thin; background-color: rgb(255, 255, 255);">var</code><span style="display: inline !important; background-color: rgb(255, 255, 255);">​ only applies to local variables, not fields, and explicit types may sometimes still be desired for pedagogy; </span>simple subclassing fails due to the recursive self type not being inherited more than one level down; "bubbling up" the self type for subclasses to specify pollutes any usages of the intermediate types; wrappers have a different type signature, making them incompatible with the types they wrap; and flattening the hierarchy to avoid subclassing results in frustrating edge cases like <code>Velocity</code>​ and <code>Quotient<Distance, Time></code>​ being incompatible types <i>even though they both represent the same thing.</i></font></div><div dir="auto" style="font-size: 14px;"><span style="font-family: Arial, sans-serif; font-size: 10.5pt;"><br></span></div><div dir="auto" style="font-size: 14px;"><span style="font-family: Arial, sans-serif; font-size: 10.5pt;">A way to define type aliases is the most obvious solution (but perhaps not the best):</span></div><div dir="auto" style="font-size: 14px;"><span style="font-family: Arial, sans-serif; font-size: 10.5pt;"><br></span></div><div style="font-size: 14px;"><span></span><div><ol data-editing-info="{"orderedStyleType":1,"unorderedStyleType":1}" dir="auto" data-listchain="__List_Chain_3502"><li style="list-style-type: "1. ";"><span><span> We can define direct, expressive type names for units without needing to create specialized subclasses</span></span></li><li style="list-style-type: "2. ";">Because there's no inheritance, the recursive self-type problem disappears</li><li style="list-style-type: "3. ";">Aliases would mean <code>Velocity</code>​ and <code>Quotient<Distance, Time></code>​ are <i>exactly the same type</i>, and would therefore always be two-way compatible</li></ol><div><br></div></div><div>I'm not proposing any particular syntax, or even to add C#-style <code>using</code>​ or Kotlin's <font face="monospace">typealias</font>. Just that a way of declaring in code that velocity is shorthand for <code>Quotient<Distance, Time></code>​, or that <code>Torque</code>​ is shorthand for that monstrous set of nested generics, would neatly resolve all the tradeoffs between verbosity and type safety. I figured amber is a good place to bring this up, given the project's focus on improving developer ergonomics and onboarding  of new programmers.</div><div><br></div><div><div><div><div><div><div><span><span>~ Sam</span></span></div></div></div><div><br><span style="display: inline !important; background-color: rgb(255, 255, 255);">ps: I have made significant simplifications to my examples for the sake of brevity. I'd be happy to clarify anything or share code samples if it would be useful</span><br></div></div></div></div></div>
<div style="font-family: Arial, sans-serif; font-size: 14px;" class="protonmail_signature_block protonmail_signature_block-empty">
    <div class="protonmail_signature_block-user protonmail_signature_block-empty">

            </div>

            <div class="protonmail_signature_block-proton protonmail_signature_block-empty">

            </div>
</div>