Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Their reasoning is along the lines of

Now I'm sure that many feel like that, but I don't think it's the majority, but I also don't know.

Here are some more arguments against types (don't necessarily agree with all of them myself, but for reference in the future when you want to write from the perspective of someone who feels more productive without types):

- There are other, more flexible ways to solve the same problems you solve with typing, the clojure.spec way is one of them

- You lose flexibility when suddenly everything is locked to each other by name. Even if Account and Person both has a first and last name fields, you can't use both of them if the function is expecting a Account and only use the first and last name. Then you need to add an interface, name it something, then make Account and Person be based on that. Now the function is locked to the interface, and so on

- Type checking is a very basic form of testing that doesn't solve the most common, annoying and hard-to-track down bugs, logic bugs.

- Metaprogramming becomes harder. Not impossible, just harder.

- Types (at least in TypeScript and other languages I've been using in the past) disappear in runtime, so you can't really use them. It's just a tool for you to tell the compiler what something is so it can say "no, you did wrong here"

Now I'm neither a type lover nor hater. I just want to use the right solution for the right problem, sometimes, that's making a program that will take longer time to write but specification is set in stone and requirements won't change, so types will help you a lot. Other times, it's in a very dynamic and experimental environment where you have to be able to apply changes as quickly as possible and minor errors don't matter as much, as long as you can move forward fast and test theories. Then you can go back and refactor things.



> You lose flexibility when suddenly everything is locked to each other by name.

This is only true of nominally typed languages (such as... most typed languages). TypeScript is a notable exception: values just have to have the same property names and types and they'll fit. The language's philosophy is basically to describe the way people write JS rather than prescribe how people should write it, so idiomatic JS is usually easy to express in TypeScript.


There are some caveats to the structural type system in TypeScript. The most glaring of which is multiple versions of the same typings will not align with each other regardless of sharing the same shape.


> You lose flexibility when suddenly everything is locked to each other by name.

TS uses structural typing.


That's good, compared to the nominative type systems, on that point at least!

I'm just trying to help the person I'm replying to to see more arguments in favor of dynamic systems without types, not necessarily straightly aimed at TypeScript as they mainly mentioned just types.


> You lose flexibility when suddenly everything is locked to each other by name. Even if Account and Person both has a first and last name fields, you can't use both of them if the function is expecting a Account and only use the first and last name. Then you need to add an interface, name it something, then make Account and Person be based on that. Now the function is locked to the interface, and so on

I see this argument frequently, and it doesn't make sense to me. Take the following function below in JavaScript and Typescript:

    function fullNameUntyped(obj) {
        return `${obj.firstName} ${obj.lastName}`;
    }

    type FirstAndLastName = { firstName: string, lastName: string };

    function fullNameTyped(obj: FirstAndLastName): string {
        return `${obj.firstName} ${obj.lastName}`;
    }
In both cases, the function's argument is bound to the interface represented by FirstAndLastName. The difference is that TypeScript allows you to be explicit about it and can statically determine if your code conforms to this. Without static type checking, you're implicitly bound to that interface.

Also, you seem to have a misunderstanding. TypeScript is Duck-typed. This means that interface compliance is based on structure, not name. So the following code is correct and type-safe:

    class Person {
        personId: number;
        firstName: string;
        lastName: string;

        constructor(firstName: string, lastName: string) {
            this.personId = 0;
            this.firstName = firstName;
            this.lastName = lastName;
        }
    }

    class Account {
        accountId: number;
        firstName: string;
        lastName: string;

        constructor(firstName: string, lastName: string) {
            this.accountId = 0;
            this.firstName = firstName;
            this.lastName = lastName;
        }
    }

    interface FirstAndLastName {
        firstName: string;
        lastName: string;
    }

    function fullName(obj: FirstAndLastName): string {
        return `${obj.firstName} ${obj.lastName}`;
    }

    let person = new Person("John", "Doe");
    let account = new Account("Jane", "Doe");

    console.log(fullName(person)); // Prints "John Doe";
    console.log(fullName(account)); // Prints "Jane Doe";
Both the Person and Account classes satisfy the interface FirstAndLastName in structure, but they don't have to reference it at all.

> Type checking is a very basic form of testing that doesn't solve the most common, annoying and hard-to-track down bugs, logic bugs.

First of all, challenge. Types can help with logic bugs just fine, but also my guess would be that type bugs come up more often. This includes typos, using the wrong variables, incorrect function argument order, etc. But I'd like to see any reference for that kind of claim anyway.

Second of all, no one says you can't still can't write tests even if you're using TypeScript.

Types are some work up front but like any tool once you learn to use them it isn't really a hinderance on prototyping or experimenting-- if anything they make it easier for me. They also make it easier to refactor, since static analysis tools can help with many refactoring tasks as well.


Ive been using Python for +16 years. Most of that time, my development was using Vim with no sort of autocompletion or even a linter. After a few years away from Python, I'm back heavy into it, currently using 3.7. I have totally embraced type hints and automatic linting in an IDE (mostly use PyCharm, but sometimes Vs code). I was always pretty productive with Python, but type hints have made me even more productive. (It also helps that I'm currently doing green field development).

I like that they're optional and not enforced. However, I also like that my IDE visually indicates when I've violated that contract. Has boosted my effectiveness quite a bit. Ive defaulted to type hints almost everywhere, especially in any library code I write (I also try and write useful docstrings). For me, its especially important because I'm the most senior Python dev on the team, the other 5 are experienced devs, but just learning Python. Me taking the time to do the type hints and docstrings is immensely helpful to them, as they all come from statically typed languages.

That said, this is my opinion. That's what this "argument" comes down to. Arguing over opinions and tastes. Each has their own and their own reasoning. Doesn't make either side right or wrong. Id just say go in whatever direction works best for one's self or team. There's no one size fits all solution.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: