Hacker News new | ask | show | jobs
by jmull 2559 days ago
People should not be downvoting this.

There's a weird impulse out there to try to pretend the limitations of static type-checking don't exist... namely, that it's static. That is, it's build-time checking and doesn't provide guarantees at runtime.

For tightly coupled systems were you control all tiers, you can stretch the value of static type checking by ensuring that changes to back, middle, and front all roll out together. But obviously, you're seriously limiting the scalability of your product and agility of your releases when you do this (you need a command-and-control dev communication structure). If you want static type checking to make guarantees beyond the local component, this is a major architectural commitment. To maximize the "guarantees" of static type-checking, it will affect the topology of your entire product, including the release process. (How much downtime is acceptable per release? What limitations are you willing to accept in terms of distributed scalability? Is it acceptable that user sessions become invalid for a release and how will you handle the UX for this?)

Not saying you shouldn't do it, but go in with your eyes open.

Now, static tools certainly have their uses. But:

(1) type-checking is just one limited case. e.g., go get eslint, turn on almost all the rules, and work with that for a few weeks. After you get over the initial shock, you'll get a lot of benefit from from it and it will last for years.

(2) it doesn't help you with anything external to the source file that's not tightly coupled through some additional control mechanism. (Note that you pay a price for control mechanisms.) So, it's a small solution to small problems. Quite nice. But limited without paying an additional price, which may be quite expensive depending on the other goals of your system.

I don't agree with the previous poster's assertion that it's a useless hack. But I understand why one might feel that way. The utility of static type-checking seems to be greatly oversold.

2 comments

I don't get this argument at all.

If you look at a typical call stack - in any language - going from the frontend all the way to the database, there will be hundreds of lines. Two, maybe three of those will be remote jumps.

Every one of those calls is an opportunity for a contract mismatch. Even if static type checking misses a half-percent of your calls, it's still working to enforce 99.5% of your contracts. The value of that is hard to oversell.

There’s nothing wrong with static type checking, It’s generally good and will prevent certain kinds of problems with out the cost of unit tests. I’m all for static checking generally, not just for types.

My point was to point out the limitations. I might be wrong, but people seem to often ignore these limitations. This oversells the benefits and leads to frustrated people like the one whose comment I originally responded to.

99.5% is not nothing, but not something you can live with in most systems so you are probably going to need something more. Also, you are going to be a lot happier if the vast majority of those hundreds of lines in your cross-system call stack are completely agnostic to the types of your problem domain and you want to be careful to minimize the coupling between components living on different sides of the jumps you mention. You can do that, of course, with static types, but it takes more care and intentional design and you really need to acknowledge the issues before you can get it reasonably right.

Tangentially, but in a similar vein, this is my gripe with TypeScript: It leads you down a path that takes the best part of JavaScript out: namely it's dynamicity, and prototypical object orientation, and leaves you with a hamstrung, not-so-good statically typed OO language. When you view it in that light, it hardly stands up to other options out there, IMO of course.

That's why I was lead to something like ReasonML because it solved the things I was already trying to do with my front end code (keep my renders in React immutable, minimize side effects, use more functional paradigms, have strong typing), but it did it with a much more powerful functional language, with a world class type system in which only Haskell rivals.

TypeScript does not take out dynamic typing or prototypical object orientation. If you can more cleanly communicate something dynamically, do it. `any` is right there. (And I do this sometimes! Of course, code where I do this is invariably where most of my unit testing has to be, but I have the choice, and I'm making it.)

And, not to be pointy, but I always get a real weird vibe about people who come rolling in professing that TypeScript isn't a backhoe when it professes to be a shovel. TypeScript is not about a "world class type system" and that's never been the claim. It's about reducing the ways in which normal developers can shoot themselves in the foot. If ReasonML or whatever equally bloggable thing scratches your itch, sure, but you're never getting the 95th percentile of developers, to say nothing of the 50th, to write it--and that 50th, and that 95th, percentile can benefit from better tools, too.

I see what you’re trying to say here, but Reason (and its compiler BuckleScript) aren’t the kind of puristic language folks might think they are. BuckleScript has one of the most comprehensive way to bind to whatever piece of JS you have: https://bucklescript.github.io/ and you can also just include raw JS code as a last resort, all type checked still, while keeping type soundness (in this case, almost like `any` but not really).

HN’s too short to describe the extent of it; if you’d like some language that shares a similar spirit as TypeScript (with extra features such as native compilation), please do check out Reason and BuckleScript. Our main goals are great JS interop, fast build, robust type system and a familiar syntax for JS users.

I'm familiar with the project, and with both F# and OCaml generally. ;) And I'm not saying it's bad or anything, to be clear. I am saying that it's functionally impenetrable to most programmers. To draw an analogy to something less contentious in this crowd, Elixir, even though I quite like it, is doomed to the same fate.

TypeScript is the good-enoughest thing that doesn't surprise, and I think that's enough to put it over the top. (It helps that, in this case, "good enough" is also "very good".)

Thank you for all the work you do btw -- Reason is awesome and I am having a lot of fun learning. Interop seemed daunting at first but after I tried it, it was a great experience.
> TypeScript does not take out dynamic typing or prototypical object orientation

Hence my wording, leads you down the path not forces you to. More often than not, your TypeScript codebase (at least the part you have written yourself or by your team) will be Classical OO style and fully typed, and your code reviews will consist of copious amounts of "we should add a type here"