Earlier quoted context omitted.
> I know what a UUID (or a String) is. I don't know what an AccountID, UserID, etc. is. Now I need to know what those are (and how to make them, etc. as well) to use your software. Yes, that’s exactly the point. If you don’t know how to acquire an AccountID you shouldn’t just be passing a random string or UUID into a function that accepts an AccountID hoping it’ll work, you should have acquired it from a source that…
And that's my point: I'm usually getting AccountIDs from strings (passed in via HTTP requests) so the whole thing becomes a pointless exercise.
Use Your Type System
201–210 of 357 posts
Re: Use Your Type System
#202I like this. Very much falls into the "make bad state unrepresentable". The issues I see with this approach is when developers stop at this first level of type implementation. Everything is a type and nothing works well together, tons of types seem to be subtle permutations of each other, things get hard to reason about etc. In systems like that I would actually rather be writing a weakly typed dynamic language like…
You can always enforce nominal types if you really need it.
Re: Use Your Type System
#203Earlier quoted context omitted.
Ada has this ability to define ranges for subtypes. I wish language designers would look at Ada more often.
Academic language designers do! But it takes a while for academic features to trickle down to practical languages—especially because expressive-enough refinement typing on even the integers leads to an undecidable theory.
But yeah maybe expressive enough refinement typing leads to hard to write and slow type inference engines
Re: Use Your Type System
#204Earlier quoted context omitted.
Typescript's type system is turing complete, so you can do basically anything with it if this sort of thing is fun to you. Which is pretty much my problem with it: this sort of thing can be fun, feels intellectually stimulating. But the added power doesn't make coding easier or make the code more sound. I've heard this sort of thing called the "type puzzle trap" and I agree with that. I'll take a modern hindley milne…
>Which is pretty much my problem with it: this sort of thing can be fun, feels intellectually stimulating. But the added power doesn't make coding easier or make the code more sound. In practice nobody goes too crazy with it. You have a problem with a feature almost nobody uses. It's there and Range is like the upper bound of complexity I've seen in production but that is literally extremely rare as well. There is no…
Re: Use Your Type System
#205Re: Use Your Type System
#206Re: Use Your Type System
#207Type systems, like any other tool in the toolbox, have an 80/20 rule associated with them. It is quite easy to overdo types and make working with a library extremely burdensome for little to no to negative benefit. I know what a UUID (or a String) is. I don't know what an AccountID, UserID, etc. is. Now I need to know what those are (and how to make them, etc. as well) to use your software. Maybe an elaborate type sy…
Re: Use Your Type System
#208Swift has a typealias keyword but it's not really useful for this since two distinct aliased types with the same underlying type can be freely interchanged. Wrong code may look wrong but it will still compile. Wrapper structs are the idiomatic way to achieve this, and with ExpressibleByStringLiteral are pretty ergonomic, but I wonder if there's a case for something like a "strong" typealias ("typecopy"?) that indicat…
In what precise way are you envisioning that this would be different from a wrapper struct?
Re: Use Your Type System
#209Separate types for each model id is an extremely tedious way of avoiding bugs that can easily be prevented by a single test.
The compiler tests the type is correct wherever you use it. It is also documentation.
Still have tests! But types are great.
But sadly, in practice I don't often use a type per ID type because it is not idiomatic to code bases I work on. It's a project of its own to move a code base to be like that if it wasn't in the outset. Also most programming languages don't make it ergonomic.
Re: Use Your Type System
#210Separate types for each model id is an extremely tedious way of avoiding bugs that can easily be prevented by a single test.
func AddMessage(u UserId, m MessageId)
If it's just func AddMessage(userId, messageId string)
it's very easy to accidentally call as AddMessage(messageId, userId)
and then best-case you are wasting time figuring out a test failure, and worst case trying to figure out the bug IRL.V.S. an instant compile error.
I have seen errors like this many times, both written by myself and others. I think it's great to use the type system to eliminate this class of error!
(Especially in languages like Go that make it very low-friction to define the newtype.)
Another benefit if you're working with any sort of static data system is it makes it very easy to validate the data -- e.g. just recursively scan for instances of FooId and make sure they are actually foo, instead of having to write custom logic or schema for everywhere a FooId might occur.