Live data from Hacker News

Don't Be Afraid of Types

lmika.org

11–20 of 233 posts

Re: Don't Be Afraid of Types

#11
post #2

my code became much easier to maintain once i stopped thinking of it as writing "algorithms" and "processes" and started thinking of it as a series of type conversions. structuring what lives where became easier, naming things became systematic and consistent, and writing unit tests became simple.

I agree; in my experience, pretty much everything is ETL. We take data from one thing, change it a bit, and put it somewhere else. Sometimes, as a treat, we take data from two things, put them together, and then put that somewhere else.

Frontend, backend, databases, services, reports, whatever - ETL.

In that context, the types and transformations between types are the most important feature. (Everything is actually Category Theory)

Re: Don't Be Afraid of Types

#12
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…

Really depends on your intent. Ideally code has meaning that reflects your problem domain and not just what happens to work at the moment.

Code that just works right now never scales.

Re: Don't Be Afraid of Types

#13
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…

Now when you establish full functional languages, most languages will allow you to do

    fullName = map list \(firstName, lastName) -> firstName + " " + firstName
and type it as `funfullName: (String, String)[] -> String`.

I have worked on large scale systems in both types and untyped languages and I cannot emphasize strongly enough how important types are.

Re: Don't Be Afraid of Types

#14
Encapsulation isn't the real reason why types help. Pass 5 variables individually, the only difference will be in verbosity.

The real benefit is type narrowing. (Or declaring the space of all possible combinations of values.)

Instead of

id: null | string

name: null | string

...

You'd have

user: null | User

And

User: { id: string, name: string, ..}

declaring that all are not null together.

Pushing validation to static checker instead of runtime.

Re: Don't Be Afraid of Types

#15
Huh. I don't see any conflict between loving OO-programming and also loving types. Isn't 9/10ths of OO just about consolidating your business logic into interfaces and types that you'd ideally want to re-use? I feel like if it's not, then people are using OO the wrong way.

Re: Don't Be Afraid of Types

#16
post #9
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…

> Every darn little thing in Java needs a name. Don't all types need names, regardless of what language you use? Look at typescript, and how it supports structural typing. They don't seem to have a problem with names. Why do you think Java has that problem when nominal type systems simplify the problem? > There's no need to declare a type ObjectWithFirstNameAndLastName. It would be quite silly. Naming things is hard,…

C# has anonymous types, for example. Kind of like tuples but you can name the fields.

Re: Don't Be Afraid of Types

#17
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…

Now when you establish full functional languages, most languages will allow you to do fullName = map list \(firstName, lastName) -> firstName + " " + firstName and type it as `funfullName: (String, String)[] -> String`. I have worked on large scale systems in both types and untyped languages and I cannot emphasize strongly enough how important types are.

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.

Re: Don't Be Afraid of Types

#18
post #9
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…

> Every darn little thing in Java needs a name. Don't all types need names, regardless of what language you use? Look at typescript, and how it supports structural typing. They don't seem to have a problem with names. Why do you think Java has that problem when nominal type systems simplify the problem? > There's no need to declare a type ObjectWithFirstNameAndLastName. It would be quite silly. Naming things is hard,…

I think Java culture had something to do with the ridiculously verbose names, but even more so the prevalence of Factory and Singleton paradigms in Java created these issues. Maybe because it was the first OO language that a lot of procedural coders came to in the 90s. Those patterns became sort of escape hatches to avoid reasoning about ownership, inheritance and scope. They're still common patterns for emergencies in a lot of ECMA-whatever languages resembling Java: You need a static generator that doesn't own the thing it instantiated, and sometimes you only need one static object itself... but one reaches for those tools only as a last resort. After thinking through what other ways you could structure your code. The super-long-name thing in Java always felt to me like people trying to write GOTO/GOSUB type procedural programs in an OO language.

Re: Don't Be Afraid of Types

#19

Huh. I don't see any conflict between loving OO-programming and also loving types. Isn't 9/10ths of OO just about consolidating your business logic into interfaces and types that you'd ideally want to re-use? I feel like if it's not, then people are using OO the wrong way.

You can love conflicting things, but the basis of OO programming, that which makes it object-oriented and not just object-based, is message passing, which sees messages flow between objects for inspection. That is inherently runtime behaviour which is at odds with static type enforcement.

Re: Don't Be Afraid of Types

#20
I was refactoring a 700 line recursive C function (!) - one of those with all variables declared at the outer scope while the function itself was mainly a one pass switch with goto’s for error handling. I created c++ classes for each case, hoisted them out and coalesced types that were otherwise identical. The new version was way smaller and and (imho) far more readable and maintainable.

At some point I needed to change the types to capture a byte range from a buffer rather than just referring to the base+offset and length, and it was trivial to make that change and have it “just work”.

These were no vtable classes with inline methods, within a single compilation unit - so they just poof go away in a stripped binary.

‘Tis better to create a class, than never to have class at all. Or curse the darkness.

Post reply on HN