[HN Gopher] Universal domain types
       ___________________________________________________________________
        
       Universal domain types
        
       Author : thunderbong
       Score  : 95 points
       Date   : 2024-02-27 08:30 UTC (1 days ago)
        
 (HTM) web link (mmapped.blog)
 (TXT) w3m dump (mmapped.blog)
        
       | noduerme wrote:
       | I think the "Quantity" type is a neat idea. I'm wondering how to
       | implement that as a utility type in Typescript.
        
         | notarobot123 wrote:
         | You can use an intersectional type with a unique constraint to
         | make something that behaves like a nominal type (see:
         | https://www.typescriptlang.org/play#example/nominal-typing)
        
           | kroltan wrote:
           | If you use a symbol as the brand key, you can even stack
           | multiple different brands!
        
       | qsort wrote:
       | What the article calls "loci" satisfy the axioms of an affine
       | space, with the exception (for example in the case of pointer
       | arithmetic) that the base set might not be a field but only a
       | ring, and therefore it would be a "pseudo-affine" space based on
       | a module rather than a vector space.
       | 
       | Programming by specifying algebraic properties is very easy and
       | natural, but in most languages it's a pain to encode in the type
       | system.
        
         | red_trumpet wrote:
         | His loci do have an origin though. An affine space doesn't have
         | an origin. So basically, his loci is (canonically isomorphic
         | to) the module.
        
       | catapart wrote:
       | This is all pretty interesting. I definitely like how methodical
       | this all is. I'd be willing to try some of this practically to
       | see where I chafe with it!
        
       | owlstuffing wrote:
       | Considering the Amount domain types, I like the manifold
       | project's unit expression[1] approach where the unit and domain
       | type are integrated and always reconciled.
       | 
       | 1. https://github.com/manifold-
       | systems/manifold/tree/master/man...
        
       | naasking wrote:
       | A good breakdown, but money resists all of these categories when
       | mixing currencies. Here's a good analysis of various money types:
       | 
       | https://deque.blog/2017/08/17/a-study-of-4-money-class-desig...
        
         | deathanatos wrote:
         | ... there's a number of (rather trivial?) fixes to some of the
         | problems they hit.
         | 
         | First, you _can_ have a type-checker check the currency; that
         | doesn 't have to be a runtime error:                 Money<Usd>
         | m = ...;
         | 
         | There will, of course, be instances where you must handle
         | currency dynamically.
         | 
         | "MoneyExpr" is a bit more complicated; I find most people
         | usually implement "MoneyBag" intuitively first, so it's odd
         | they left that for third? So, the article gets there, and we
         | "fix" the problems, but it feels roundabout.
         | 
         | The criticism of MoneyBag is bizarre:
         | 
         | > _Compared to the Martin Fowler's design, it remains heavier.
         | It consumes more memory and more CPU_
         | 
         | This is apples to oranges? Fowler's design is a Money type;
         | MoneyBag is a different thing; of course it consumes more
         | memory. A Vec<int> consumes more memory than an int, too?
         | 
         | Perhaps the article author isn't comfortable with that Money
         | merely isn't closed over addition. But if you accept that Money
         | isn't closed over addition, then naturally there must be
         | another type in the type system.
        
           | naasking wrote:
           | I'm not sure what the confusion is, the question being
           | explored is, "how do you define a Money type that features
           | the operations we typically expect to perform and with the
           | results having the expected properties?". He reviews various
           | well-known published designs and their drawbacks, and
           | outlines a design that does not have those drawbacks.
           | 
           | > I find most people usually implement "MoneyBag" intuitively
           | first, so it's odd they left that for third?
           | 
           | I have not found that at all.
        
       | weinzierl wrote:
       | If you are interested in physical domain types specifically,
       | there are _uom_ and _simple-si-units_ , which can be used
       | separately or in combination.
        
       | pizza wrote:
       | Reminds me a lot of David Spivak's "ologs", down to the example
       | of how dollars are a vector space
        
       | feoren wrote:
       | Although I disagree with some of the details, I think this type
       | of approach to domain modeling is some of the most valuable work
       | software engineers can do; in fact it's the type of analysis and
       | rigor that justifies the word "engineer" in the title of
       | "software engineer". But I do have two important points to add:
       | 
       | 1. Don't restrict yourself to "common" types when you're thinking
       | this way -- _all_ of domain modeling can be approached this way.
       | Working on a Pizza Ordering app? Think about the properties of
       | various operations in your domain and how they are related to
       | mathematical structures. Are they commutative, well-orderable,
       | equatable, multiplicative, scalar, groups /rings/fields, monoids?
       | Are there changes you can make that would allow your operations
       | to have desirable properties? This stuff genuinely does pay off
       | down the road when you want to expand your ideas or re-use your
       | code on something else.
       | 
       | But be careful: not all useful mathematical structures have names
       | or show up in textbooks! The goal is not to map your domain to
       | things that mathematicians have named, it's just to understand it
       | at this level (and get your code to understand it at this level
       | too). If you find yourself arguing over whether it's actually a
       | vector space, a tensor space, or an affine space, then stop
       | worrying about external definitions and re-focus on the
       | properties of your domain. Arguments about how your domain works
       | are good; arguments about exactly what other mathematicians have
       | written are bad.
       | 
       | 2. This post is focused on getting the compiler to understand
       | these concepts, but there's still a lot of value in explicitly
       | modeling them in code even if it's "runtime checked" instead of
       | compile-time checked. Many of these techniques end up requiring
       | higher-kinded types to really get the compiler on board, which
       | unfortunately most languages today don't support. But that
       | doesn't mean you should change the abstraction, it just means you
       | get a lower (or later) level of checking.
        
       | Tainnor wrote:
       | Years ago, I had concluded for myself that money could be
       | naturally treated as a vector space. It's nice to see that
       | somebody's had the same idea.
        
       | paldepind2 wrote:
       | Really great and interesting blog post! The different categories
       | of domain types identified all seem useful. It's clear how
       | practical these ideas can be when implementing or thinking about
       | domain-specific types. I'll definitely be keeping these terms in
       | mind for future programming.
       | 
       | > Identifiers have no structure, i.e., we don't care about their
       | internal representation. The only fundamental requirement is the
       | ability to compare values of those types for equality. This lack
       | of structure suggests an appropriate mathematical model for such
       | types: a set, a collection of distinct objects.
       | 
       | I don't understand what this is trying to say and this
       | "mathematical model" of sets doesn't seem to be applied further
       | on. In math, objects are usually always assumed to have a notion
       | of equality, so I don't see how that alone implies a set. A
       | mathematical abstraction that matches the `Eq` trait would be a
       | setoid.
       | 
       | The `LocusLike` trait is a lot like a metric space with a total
       | order. I wonder if it can be implemented by things that are not
       | basically numbers under the hood (not that it needs to, just
       | curious)?
       | 
       | > Unlike design patterns, the universal domain types are based on
       | mathematical abstractions and can be specified precisely.
       | 
       | I feel like this is over-selling it a bit. I think the ideas are
       | great but, at least as presented here, I don't think they are
       | rigorous enough to deserve the label "mathematical abstractions".
        
         | Tainnor wrote:
         | > I don't understand what this is trying to say and this
         | "mathematical model" of sets doesn't seem to be applied further
         | on.
         | 
         | I think what is meant by it is that we have a set without
         | additional structure. Other structures like vector spaces,
         | groups, fields, etc. are (at least in mainstream maths) also
         | sets, but they're equipped with structure - operations and
         | axioms that govern how these operations work. But if you have
         | just a set, you can't assume anything about the internal
         | structure of what's in that set.
        
       | munchler wrote:
       | The basic problem addressed here is a code smell called
       | "primitive obsession" [0]. Strange name, but worth knowing.
       | 
       | [0]: https://medium.com/the-sixt-india-blog/primitive-
       | obsession-c...
        
         | ryandv wrote:
         | Also see Fowler's book Refactoring [0] where "Primitive
         | Obsession" is listed among many other code smells in Chapter 3.
         | 
         | [0] https://martinfowler.com/books/refactoring.html
        
       | thepaulmcbride wrote:
       | This reminds me a lot of value objects from Domain Driven Design
        
       ___________________________________________________________________
       (page generated 2024-02-28 23:02 UTC)