[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)