Live data from Hacker News

Don't Be Afraid of Types

lmika.org

41–50 of 233 posts

Re: Don't Be Afraid of Types

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

you are just describing a function. Not a type.

And as others replied, the issue of naming a type exists in all languages.

Re: Don't Be Afraid of Types

#42
post #19

Earlier quoted context omitted.

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.

The whole point of static typing is to ensure that runtime behavior is consistent with what gets passed. Right? The beauty of a typed OO language (like AS3 or TS) is that you immediately know if you might be referencing something using the wrong type. The only major language where every variable is cast/guessed in message passing at runtime is in naked Javascript, where everything's type is any/wildcard. It's such a…

> The whole point of static typing is to ensure that runtime behavior is consistent with what gets passed. Right?

More or less. While the whole point of object-oriented programming is that behaviour is defined at runtime through the passage of messages. The messages may originate from the very same codebase, but not necessarily. Consider something like NeXT's Interface Builder, which relied heavily on injecting messages into the program externally.

> But in pure form, a well typed OO language should never run into undefined behaviour at runtime.

It is not known until runtime what kind of messages will appear. You can define what should happen when an "unknown" message shows up (ignore it, for example), but you cannot statically prove that it won't occur. –– If you could, what do you need OO for?

Re: Don't Be Afraid of Types

#43
post #27

Please be afraid of types. On top of new cognitive load, introduction of redirection, and anti-patterns like pretend-simplification where you shuffle a bunch of unrelated parameters into a struct to make a function receive only a single argument (which quickly evolves into functions receiving parts of that struct they don't need, making use and testing much harder — I am surprised an article is really recommending th…

Conversely, do you also consider the downsides and consequences of not having types? If you don't, then you're blind to whole categories of issues. As a good engineer, you need to be able to reason both ways to come to a reasonable solution, not just one that conforms to your particular ideology.

Re: Don't Be Afraid of Types

#44

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…

Agree.

I try hard to push the validation to static checks, but it can't always be done. For example:

- a "probability" represented as a double must always be between 0 and 1

- A vector of values given to some group of functions must always be sorted (by some given order)

But even in those cases, using types allows me to ensure that this validation always happens (when the type instance is created). It also let's me avoid having to explicitly validate this inefficiently (e.g. redundantly in preconditions in functions that receive these values).

This doesn't change the fact that static validation is a better approach, but compliments it.

I wrote a bit about it here: https://github.com/alefore/weblog/blob/master/edge/correctne...

Re: Don't Be Afraid of Types

#45
> That’s what the type system is for: a means of grouping similar bits of information into an easy-to-use whole.

While types can be used for that, they are a much broader concept.

I would say the general purpose of types is to tell apples from oranges.

Re: Don't Be Afraid of Types

#46
post #35
post #26

Earlier quoted context omitted.

As shown by The Art of Metaobject Protocol that is the genesis of CLOS, not really.

The Art of the Metaobject Protocol does not seem to go into any detail about senders sending blobs of data to receivers. What do you think it shows, exactly? That you don't need to send blobs of data? That should be obvious by the fact that you can count the number of languages that support that concept on one hand, but does not remove that message passing when employed is necessarily dependent on runtime.

It shows that message passing and types get along just fine.

Re: Don't Be Afraid of Types

#47
post #25

Earlier quoted context omitted.

For whatever reason Java gets the blame for what was already common Smalltalk, C++, Clipper 5, Object Pascal, Actor, Eiffel, Objective-C,....before Oak idea turned into Java. To the point many think the famous patterns book used Java, when it is all about Smalltalk and C++ patterns.

> For whatever reason Java gets the blame for what was already common (...) Java's problem is that it's hugely successful, and to some it's the only language they ever experience in their formative years. Thus, because poor workmen always blames the tools, Java becomes the root of all evil.

That and the historical illiteracy the industry suffers from.

Re: Don't Be Afraid of Types

#48
post #46
post #35

Earlier quoted context omitted.

The Art of the Metaobject Protocol does not seem to go into any detail about senders sending blobs of data to receivers. What do you think it shows, exactly? That you don't need to send blobs of data? That should be obvious by the fact that you can count the number of languages that support that concept on one hand, but does not remove that message passing when employed is necessarily dependent on runtime.

It shows that message passing and types get along just fine.

It is not like they are sworn enemies, but as messages can originate from outside the program, they cannot be typed statically. It is impossible to know what types will appear before runtime. For messages that originate from within the same codebase, you can, perhaps, start to layer static typing on top, but it can only be a partial solution as it remains that messages can come from other sources.

Re: Don't Be Afraid of Types

#49
post #48
post #46

Earlier quoted context omitted.

It shows that message passing and types get along just fine.

It is not like they are sworn enemies, but as messages can originate from outside the program, they cannot be typed statically. It is impossible to know what types will appear before runtime. For messages that originate from within the same codebase, you can, perhaps, start to layer static typing on top, but it can only be a partial solution as it remains that messages can come from other sources.

Then we are talking about distributed computing, and nothing will help you understand that glob of undefined bytes.

This has nothing to do with OOP.

Re: Don't Be Afraid of Types

#50
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,…

> Don't all types need names, regardless of what language you use?

No.

- In very dynamic languages (like javascript), most types arguably don't have names at all. For example, I can make a function to add 2d vectors together. Even though I can use 2d vectors in my program, there doesn't have to be a 2d vector type. (Eg, const vecAdd = (a, b) => ({x: a.x+b.x, y: a.y+b.y}) ).

- Most modern languages have tuples. And tuples are usually anonymous. For example, in rust I could pass around 2d vectors by simply using tuples of (f64, f64). I can even give my implicit vector type functions via the trait system.

- In typescript you can have whole struct definitions be anonymous if you want to. Eg: const MyComponent(props: {x: number, y: string, ...}) {...}.

- There's also lots of types in languages like typescript and rust which are unfortunately impossible to name. For example, if I have this code:

    #[derive(Eq, PartialEq)]
    enum Color { Red, Green, Blue }

    fn foo(c: Color) {
        if c == Color::Red { return; }

        // What is the type of 'c' here?
    }
Arguably, c is a Color object. But actually, c must be either Color::Green or Color::Blue. The compiler understands this and uses it in lots of little ways. But unfortunately we can't actually name the restricted type in the program.

Rust can do the same thing with integers - even though (weirdly) it has no way to name an integer in a restricted range. For example, in this code the compiler knows that y must be less than 256 - so the if statement is always false, and it skips the if statement entirely:

https://rust.godbolt.org/z/3nTrabnYz

But - its impossible to write a function that takes as input an integer that must be within some arbitrary range.

Post reply on HN