Live data from Hacker News

Don't Be Afraid of Types

lmika.org

71–80 of 233 posts

Re: Don't Be Afraid of Types

#71

As somebody who is afraid of types (and also, who hates types, because we all hate what we fear), may my point of view serve as balance: you don't need a type system if everything is of the same type. Programming in a type-less style is an exhilarating and liberating experience: assembler : everything is a word C : everything is an array of bytes fortran/APL/matlab/octave : everything is a multi-dimensional array of…

But once you get down to the unit data values inside any of those aggregates, you're still dealing with either characters, ints, floats, strings, arrays, and they each have their own individual access patterns and, more importantly, modification functions.

You can't add a number to a string, only to another number.

If you are dealing with a float, you better be careful how you check it for equality.

If it's pure binary, what kind of byte is it? Ascii, unicode code point, unsigned byte, signed multi-byte int, ... whatever.

There's no escaping the details, friend.

And your saying "everything is a word" for assembler is just plain wrong.

Re: Don't Be Afraid of Types

#72

As somebody who is afraid of types (and also, who hates types, because we all hate what we fear), may my point of view serve as balance: you don't need a type system if everything is of the same type. Programming in a type-less style is an exhilarating and liberating experience: assembler : everything is a word C : everything is an array of bytes fortran/APL/matlab/octave : everything is a multi-dimensional array of…

I feel the need to issue a correction: while I'm programming in assembly, I very well have types. This word over here (screen position) represents a positive number only, but this one over here (character acceleration) can be negative. When adding one to the other, I need to check the arithmetic flags like so to implement a speed cap...

The types certainly exist. They're in my mind and, increasingly through naming conventions, embedded within some of the comments of my assembler code. But nothing is there to check me. Nothing can catch if I have made an error, and accessed a pointer to a data structure which contains a different type than I thought it did. Without a type system, that error is silent. It may even appear to work! Until 6 months later, when I rearrange my code and the types are arranged differently in memory, and only THEN does it crash.

Re: Don't Be Afraid of Types

#73

I'm not a huge fan of types because they don't model the real world accurately. In the real world, most concepts which we describe with human language have many variations with optional properties and it's a pain and a waste of time to try to come up with labels to categorize each one... It induces people to believe that two similar concepts are distinct, when in fact, they are extremely similar and should share the…

If you flipped things a bit and think of types as more or less "allowed shapes of the things happening in my program", it might seem closer to the real-world comparison that you are thinking of.

Re: Don't Be Afraid of Types

#74

As somebody who is afraid of types (and also, who hates types, because we all hate what we fear), may my point of view serve as balance: you don't need a type system if everything is of the same type. Programming in a type-less style is an exhilarating and liberating experience: assembler : everything is a word C : everything is an array of bytes fortran/APL/matlab/octave : everything is a multi-dimensional array of…

I feel the need to issue a correction: while I'm programming in assembly, I very well have types. This word over here (screen position) represents a positive number only, but this one over here (character acceleration) can be negative. When adding one to the other, I need to check the arithmetic flags like so to implement a speed cap... The types certainly exist. They're in my mind and, increasingly through naming co…

> increasingly through naming conventions

The original goal of hungarian notation :) But Petzold mistakenly used 'type' in the paper and we ended up with llpcmstrzVariableName instead of int mmWith vs int pixelWidth, which was what they were doing in Office and frankly makes a lot of sense.

Re: Don't Be Afraid of Types

#75
post #66

Earlier quoted context omitted.

Doable in TypeScript[0], but I'd wager if that's really necessary. [0]: https://www.typescriptlang.org/play/?#code/C4TwDgpgBAogdgVwL... from StackOverflow[1] [1]: https://stackoverflow.com/questions/39494689/is-it-possible-...

> but I'd wager if that's really necessary. I think its more useful in a language like rust, because the compiler can use that information to better optimize the emitted assembly.

Even in compiled languages I think the benefits won't outweigh the difficulties in compiler optimization.

It starts with the question of how I would like to design my sequences:

- Is it the range (0, 10] in steps of 1?

- Is it the range (0, 2^10) in steps by the power of 2?

- Is it the range (0.0, 2PI] in steps of EPSILON?

How would the compiler engineer generalize this optimization?

And the question would continue whether I'd be really able to define them that precisely before runtime. Most applications are just dealing with lightweight structures, mostly serialized JSON nowadays, and then even there are enough fuck-ups[0] where such an optimization wouldn't help at all.

I can imagine the places where they really matter are some heavy memory intensive data structures like deep neural networks, graphics or video and the like - for the time being they're just dealing with tensors of data type floatX, and that seems to be fine AFAIK.

I mean, I'd be really nice if the smaller memory footprint could come out-of-the-box during compilation. But all the CLI tools written in rust certainly don't have the use case to put this complication on the shoulders of compiler research.

[0]: https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...

Re: Don't Be Afraid of Types

#76

As somebody who is afraid of types (and also, who hates types, because we all hate what we fear), may my point of view serve as balance: you don't need a type system if everything is of the same type. Programming in a type-less style is an exhilarating and liberating experience: assembler : everything is a word C : everything is an array of bytes fortran/APL/matlab/octave : everything is a multi-dimensional array of…

But once you get down to the unit data values inside any of those aggregates, you're still dealing with either characters, ints, floats, strings, arrays, and they each have their own individual access patterns and, more importantly, modification functions. You can't add a number to a string, only to another number. If you are dealing with a float, you better be careful how you check it for equality. If it's pure bina…

> And your saying "everything is a word" for assembler is just plain wrong.

I also love x87 registers, but they are becoming rarer these days.

Re: Don't Be Afraid of Types

#77
post #4

The issue is names. Every darn little thing in Java needs a name. If there is no good name, that's a hint that maybe you don't need a new type. Obligatory Clojure example: (defn full-name [{:keys [first-name last-name]}] (str first-name " " last-name)) This defines a function named `full-name`. The stuff between [] is the argument list. There's a single argument. The argument has no name. Instead it is using destruct…

If we're philosophizing here:

1. This (or maybe a less trivial form of this) will bite you in the ass when you end up using other people's unnamed types. Or even when you use your own unnamed types that come from code you haven't touched in three years.

2. That's what interfaces are for in Java. Or at least modern Java.

Re: Don't Be Afraid of Types

#78

Earlier quoted context omitted.

The only thing with anonymous functions is, when the boss says "please include every user's middle initial", you need to go find every instance of an inline function that resembles this. Consolidating that function in a getter in a class object called Person or User or Customer is a lot nicer.

This is more a question about architecture. But one thing is certain: When you have that one function that is used 165 times throughout the code base, having a type checker is certainly going to help you when you add in the users middle initial.

> This is more a question about architecture.

In an ideal world :)

In the real world the customer doesn't know what they want and you can't fully guess what they want or need ahead of time no matter how many diagrams you draw.

Incidentally, one of the few good things that came out of the "agile" religion.

Re: Don't Be Afraid of Types

#79
post #77
post #4

The issue is names. Every darn little thing in Java needs a name. If there is no good name, that's a hint that maybe you don't need a new type. Obligatory Clojure example: (defn full-name [{:keys [first-name last-name]}] (str first-name " " last-name)) This defines a function named `full-name`. The stuff between [] is the argument list. There's a single argument. The argument has no name. Instead it is using destruct…

If we're philosophizing here: 1. This (or maybe a less trivial form of this) will bite you in the ass when you end up using other people's unnamed types. Or even when you use your own unnamed types that come from code you haven't touched in three years. 2. That's what interfaces are for in Java. Or at least modern Java.

I’ve first learned Java in introduction to programming in 2001 and that’s what interfaces were for back then already.

Re: Don't Be Afraid of Types

#80

> I found that there’s a slight aversion to creating new types in the codebases I work in. I've encountered the same phenomenon, and I too cannot explain why it happens. Some of the highest-value types are the small special-purpose types like the article's "CreateSubscriptionRequest". They make it much easier to test and maintain these kinds of code paths, like API handlers and DAO/ORM methods. One of the things that…

> I've encountered the same phenomenon, and I too cannot explain why it happens. I think that some languages lead developers to think of types as architecture components. The cognitive cost and actual development work required to add a type to a project is not the one-liner that we see in TypeScript. As soon as you create a new class, you have a new component that is untested and unproven to work, which then requires…

> I think that some languages lead developers to think of types as architecture components

It's not any languages doing that; it's their company culture doing that.

Java-style languages (esp. those using nominative typing, so: Java, C#, Kotlin, Swift, but not Go, Rust, etc) have never elevated their `class` types as illuminated representations of some grandiose system architecture (...with the exception of Java's not-uncontroversial one-class-one-file requirement); consider that none of those languages make it difficult to define a simple product-type class - i.e. a "POCO/POJO DTO". (I'll pre-empt anyone thinking of invoking Java's `java.beans.Bean` as evidence of the language leading to over-thinking architecture: the Bean class is not part of the Java language any more than the MS Office COM lib is part of VB).

The counter-argument is straightforward: reach for your GoF Design Patterns book, leaf through to any example and see how new types, used for a single thing, are declared left, right and centre. There's certainly nothing "architectural" about defining an adapter-class or writing a 10-line factory.

...so if anyone does actually think like that I assume they're misremembering some throwaway advice that maybe applied to a single project they did 20 years ago - and maybe perhaps the company doesn't have a meritocratic vertical-promotion policy and doesn't tolerate subordinates challenging any dictats from the top.

> Think about it for a second: one of the main uses of types is to prevent developers from misusing specific objects if they don't meet specific requirements.

...what you're saying here only applies to languages like TypeScript or Python-with-hints - where "objects" are not instances-of-classes, but even then the term "type" means a lot more than just a kind-of static precondition constraint on a function parameter.

Post reply on HN