Live data from Hacker News

The type system is a programmer's best friend

dusted.codes

81–90 of 467 posts

Re: The type system is a programmer's best friend

#81
post #76

Why is it better to have two email types, VerifiedEmail and UnverifiedEmail vs. one Email type with an "isVerified" field? One type is probably going to align with storage and transport better, and you probably mostly want to treat verified and unverified email addresses the same except for some very specific situations. (E.g., maybe only your EmailBlaster cares, where it's like a privilege: some can send to unverifi…

> Why is it better to have two email types, VerifiedEmail and UnverifiedEmail vs. one Email type with an "isVerified" field?

You obviously have no idea what a type is.

    type VerifiedEmail = { email: string; is_verified: true; };

    type UnverifiedEmail = { email: string; is_verified: false; };

Re: The type system is a programmer's best friend

#82

Oh god, please just use primitive types. Don't make assumptions about things. Everyone thinks they are so smart validating emails, phone numbers, zip codes and all until their great design goes live and they discover that users in the real world do not follow their assumptions. I have seen that happen again and again. No, if your idea of validating an email is more complicated than "should have an @ symbol", I guaran…

There's a sharp distinction between validation and typing. I can cast a string into a domain-specific Email type without validating the string. I can also reject a string due to a validation rule without changing its type.

Opaque type aliases are great because they impose semantics. Even if I don't know how to validate an email, it's nice, at times, to distinguish a string which I suspect to be an email from all other sorts of strings.

Re: The type system is a programmer's best friend

#83

Oh god, please just use primitive types. Don't make assumptions about things. Everyone thinks they are so smart validating emails, phone numbers, zip codes and all until their great design goes live and they discover that users in the real world do not follow their assumptions. I have seen that happen again and again. No, if your idea of validating an email is more complicated than "should have an @ symbol", I guaran…

My favorite "easy win" find from learning Haskell last year was just the `newtype` keyword, which basically just let you alias primitive types with zero runtime impact. `newtype Email = Email String` and `newtype Username = Username String` are just `String`s with guard rails.

Python's type annotation system has this feature too:

    from typing import NewType

    UserId = NewType('UserId', str)

    user_id: UserId

    user_id = "abc"          # Type check error
    user_id = UserId("abc")  # OK

    # At runtime, a NewType is the identity function
    s1: str = "abc"
    s2: UserId = UserId(s1)
    assert s1 is s2
Docs: https://docs.python.org/3/library/typing.html#newtype

Runtime: https://tio.run/##TU49D4JADN37K544CIkLupk4OBoTXXQ2CKdcDHeXts...

Type checking: https://mypy-play.net/?mypy=latest&python=3.10&flags=show-er...

Re: The type system is a programmer's best friend

#84
post #76

Why is it better to have two email types, VerifiedEmail and UnverifiedEmail vs. one Email type with an "isVerified" field? One type is probably going to align with storage and transport better, and you probably mostly want to treat verified and unverified email addresses the same except for some very specific situations. (E.g., maybe only your EmailBlaster cares, where it's like a privilege: some can send to unverifi…

Type correctness can be verified at compile time while Boolean values can’t.

Re: The type system is a programmer's best friend

#86
post #43

>A string value is not a great type to convey a user's email address or their country of origin. These values deserve much richer and dedicated types this is a classic case of not needing more types but needing proper names . Types as concretions, i.e. simply collections of data or functions are a terrible idea because they're static and don't accrete. Data in the real world always does. This becomes very obvious whe…

No, there should only be the one EmailAddress type. If it's not valid, it's not an EmailAddress. Does having an EmailAddress type guarantee you won't accidentally accept crap? No, but when you get it wrong, you edit the validation in one place in the system.

If that place is the EmailAddress type, then you have built your system wrong. You check that stuff when the data enters the system.

Re: The type system is a programmer's best friend

#87
post #76

Why is it better to have two email types, VerifiedEmail and UnverifiedEmail vs. one Email type with an "isVerified" field? One type is probably going to align with storage and transport better, and you probably mostly want to treat verified and unverified email addresses the same except for some very specific situations. (E.g., maybe only your EmailBlaster cares, where it's like a privilege: some can send to unverifi…

It's so that when you are 50 function calls deep you don't have to remember if you are handling a verified email or not. This is the same problem I have with "sum types" as implemented in languages that don't have algebraic data types. You either have a massive struct that contains mostly nullable values or something like a tagged union.

>verified and unverified email addresses the same except for some very specific situations.

This is when typeclasses are a useful concept (or interfaces). Instead of designing your function around a concrete type, you can codify that the caller needs to provide any types that satisfy some requirements. For example, if the function only cares that the input can be treated as a string, you can ask for something like `As`. Then, the caller can provide literally anything as long it implements `As`.

> types are just one tool

Indeed, types are just a tool. But it is a much better tool. Its an electronic shaver instead of rusty axe. This is my biggest gripe with "simple and small languages". More often than not, you just end up writing more verbose and complicated code just to compensate.

To illustrate, I wanted to implement `INCR KEY VALUE` from Redis.

```

item, exists := db.keys[key]

if !exists { return }

value, ok := item.Value().(string)

if !ok { return }

intValue, err := strconv.ParseInt(value, 10, 64)

if err != nil { return }

intValue++ // db.keys[key] = intValue;

```

Re: The type system is a programmer's best friend

#88

Articles like this bug me. You've given me a list of why types are awesome. Great. Now, tell me what the tradeoff is. Nothing is free in engineering. To get something, you have to give up something else. Even grug[0] understands this. [0]: https://grugbrain.dev/#grug-on-type-systems

This is brilliant. Just made my day

Re: The type system is a programmer's best friend

#89

The most successful languages are typed but weakly so. Just enough type system to avoid the biggest class of bugs, not enough to get in your way all the time. Golang strikes this balance very well. Too little typing, and your Python unit tests get too heavy to run after every commit. Too much, and you have to read a book on category theory before you can figure out how to grab that one field using Lenses in Haskel. E…

I think ascribing PL popularity to striking the right tradeoff in this respect is leaping a bit far. It's compatibility and familiarity with predecessors, marketing dollars, etc. They tend to have C++ style syntax for example which is a similar path-dependence-formed quirk of history.

Re: The type system is a programmer's best friend

#90

Articles like this bug me. You've given me a list of why types are awesome. Great. Now, tell me what the tradeoff is. Nothing is free in engineering. To get something, you have to give up something else. Even grug[0] understands this. [0]: https://grugbrain.dev/#grug-on-type-systems

Understanding existing code is a big benefit of static types as well.

I’m sure one could argue that member names should obviate the need for type annotations.

There’s also the distinct possibility that my preceding ~15 years of statically-typed software development have affected how I think about software development in some way. (wink)

But I am finding type annotations internet useful while working on a huge application that is about 2 years into adding a gradual typing system, enough so that I usually take time whenever I enter a new code area to add annotations to everything, just to understand what’s going on.

My perception is that I invest time to build understanding of the types, and then document what I’ve learned in the form of these type annotations so that future maintainers then gain a quicker understanding without having to do the initial research.

At least my non-statistically-significantly-sized team agrees.

Post reply on HN