6 ms·
Note how some of these are directly at odds with writing easily maintainable code. For example, using type annotations for return types [0]: - import { other
by Etheryte 6y ago
Note how some of these are directly at odds with writing easily maintainable code. For example, using type annotations for return types [0]:
- import { otherFunc } from "other";
+ import { otherFunc, otherType } from "other";
- export function func() {
+ export function func(): otherType {
return otherFunc();
}
Not manually annotating the return type here reduces both the work you need to do when refactoring and the visual overload when working with the code. In my opinion, both of those are far more important than small changes in compile time.
[0] https://github.com/microsoft/TypeScript/wiki/Performance#using-type-annotations https://github.com/microsoft/TypeScript/wiki/Performance#usi...
- staticassertion 6y agoI honestly find it so annoying when return types aren't annotated. It's considerably less overhead for me when I can look at the signature and see the return type, even if a few characters are added.
- jasonhansel 6y agoAgreed. I think Rust had the right approach here: require type annotations for function parameters & return values, but perform type inference within functions. That makes it obvious when a function's public interface (so to speak) has changed.
- aszen 6y agoNot really, rust is unusable for interactive programming because of this reason. I understand that's not rust target domain but still there's downsides to be had with their approach.
- ImprobableTruth 6y ago>rust is unusable for interactive programming because of this reason I'm not sure I understand, could you elaborate more?
- capableweb 6y agoLots of current and potential issues around interactive programming in Rust are outlined and discussed here: https://github.com/rust-lang/rfcs/issues/655 https://github.com/rust-lang/rfcs/issues/655
- identity0 6y agoYou mean like a REPL? Most languages are unusable for interactive programming. And it's not a downside if it stops use in a domain that was nobody's goal.
- aszen 6y agoYes, just pointing out the trade offs here. Btw many functional languages have quite good interactive experiences, (ocaml, f sharp, Haskell , clojure all have decent repl's). Usually they work instantly for small sized projects.
- identity0 6y agoHave you ever seen a procedural language with a good REPL? Python maybe, but definitely no compiled procedural garbage-collectorless language. The "needing to put type signatures" is completely unrelated. I have no idea how that would stop Rust from being good in a REPL.
- lstamour 6y agoSure: https://cdn.rawgit.com/root-project/cling/master/www/index.html https://cdn.rawgit.com/root-project/cling/master/www/index.h... Can’t speak to its quality, but there’s nothing stopping someone from writing a repl from a sufficient compiler API... and “good” is only limited by inference quality and runtime performance. IDEs are pretty snappy at showing you autocomplete as you type regardless of whether the language has a garbage collector. And performance - well, that’s what caching would be for, and an optimized compiler design that only needs to recompile changed code... I would also point out the “auto” keyword in CPP likely saves folks a lot of typing ;-) I know it and similar inferences changed my mind on the whole static vs dynamic debate...
- aszen 6y agoMy experience with f sharp and recently with the new Haskell langauge server has been that not having written type annotations is a no issue because the language tooling still shows them above the function definition and better yet can autogenerate them. So I think this is more of a tooling issue, do keep in mind global type inference is really handy for interactive programming in the repl and short scripts. Type inference
- ragnese 6y agoI've not had the chance yet to play with OCaml or Haskell in earnest, but it's on my list. One thing that I'm fascinated and terrified by is the global type inference. Doesn't it get really hard to figure how how you're allowed to call things? Does it make your IDE experience slow? Similar to one of the things mentioned in the OP, I would think that the type hints would be super helpful to the compiler/analyzer.
- aszen 6y agoI would say it works surprisingly well 90% of the time. The main help type hints give to the compiler is that it can generate better error messages for when things do go wrong, apart from that there is no major difference. As I mentioned earlier it's a powerful feature, and has its uses, especially when you are still trying to figure the types of your program. For an easier taste of global type inference you can try elm language, it's also a good stepping stone to learning haskell
- Xenoamorphous 6y agoExactly, and if I declare that a function returns a string, and then edit its code and add a return statement that returns a number by mistake, the compiler will tell me right away. If I didn’t declare the return type then the function will silently now infer the return type to be “string | number” (which might or might not break compilation elsewhere).
- breck 6y agoVSCode shows return type on hover, and could easily show it all the time via an inline secondary notation, if desired. no need for more tokens.
- int_19h 6y agoThe problem is that the type it infers is not necessarily the type you want to be exposed on that export. And then it's quite possible to have a bug in implementation of the function that results in a type that's outright wrong. Types are a subset of contracts. Contracts are best explicit at the API boundary - which is to say, on exported functions and members of exported classes.
- breck 6y agoAgreed—there are times you definitely need to specify the type. I have them every week, but still find it the exception rather than the rule, and easier to adjust for those, than adjust for the more common case.
- Etheryte 6y agoLooking at the votes on my comment jump up and down, I was very surprised to find that my opinion is apparently very controversial. I find this very intriguing, and I'd like to hear from your side. From your perspective, doesn't IDE intellisense and the like cover that use case? Or do you prefer to have all of that information visible all the time?
- jitl 6y agoI think this can go both ways. There are lint rules that encourage explicit return types for exported functions and public functions, because return types are the interface between modules. As your codebases grow, having clear relationship and contracts between modules becomes more important. This goes doubly for modules distributed as NPM packages - you want the compiler to tell you when changing the body of an exported function constitutes a breaking change to your module’s API - and the easiest way to make that mistake is to change an inferred return type, and conversely the lowest-hanging fruit to prevent that error is to lint for explicit return types.
- dahfizz 6y agoI don't understand this at all. Type annotations absolutely make a code base easier to maintain, not the opposite. If you are in the "types are overhead" camp, why use typescript at all?
- FlorianRappl 6y agoThis is over simplified. Using TypeScript you should specify all the types required to have your code base fully qualified - not more. In the example above having a fully typed `otherFunc` would directly specify the type on `func`. If you (automatically) refactor `otherFunc` the type naturally flows and you don't end up with (unnecessary) modifications on other spots. Use type inference when possible, but don't over do it.
- Etheryte 6y agoThere's a distinct difference between type annotation and type information. In the case shown above, as long as `otherFunc()` is strictly typed, the manual annotation is simply duplicating information that's already there. At no point did I argue against having types, I'm opposing needless duplication. As perhaps a simplified example, annotating `Foo` in the below example is similarly redundant: const foo: Foo = new Foo();
- efdee 6y agoTypescript is perfectly capable of telling you what the return type is without needing you to manually specify it.
- Androider 6y agoIt tells you what the function return type is, which isn't necessarily the same as the return type you might have manually typed or intended. For example, undefined's sneaking into the type because of branching code.
- cogman10 6y agoI'm going to have to disagree here. The return type is part of the contract for what a method does. Changing it is just as dangerous as changing the type on a method parameter. I agree that using type inference locally is a boon to productivity. I disagree that it's a negative for a method return parameter. Keeping it fixed prevents a future refactor from breaking the method expectations and contracts down the line.
- blauditore 6y agoI would argue the opposite: Omitting the return type makes refactorings significantly riskier, and code less readable in my opinion. Leaving out types should only be done in trivial, small-scope areas of code. When done on an exported, widely-used function, this smells like "write-only" code and is hard to maintain.
- lucideer 6y agoAnnotated return types are one of the single most prominent readability benefits of typed syntax. Knowing with certainty what type will be returned in a single brief glance, without the cognitive overhead of parsing function body and checking various return statements (at best: returning a variable obtained from an external source may obscure type further). For me this also greatly improves my ability to refactor quickly and confidently (not needing to check additional places/files during refactor for edge cases in expected type). Yes any type-related refactor mistakes should in theory be picked up at compile time, or by smart IDEs but having the context in front of you still greatly improves speed when writing. It's also great for code reviews where grokking context is trickier and IDE goodies are typically not as rich.
- breck 6y ago> in a single brief glance this is something VSCode/editors could always show if desired via secondary notation, without requiring annotations.
- lucideer 6y agoIDEs are great and all, but their features should be an augmentation of the usefulness of the language, not a requirement. I've already mentioned code reviews as a good example of contexts where we need to read code outside of an IDE regularly, but even beyond that, a language's readability shouldn't be dependent on using some specific environment to read it.
- breck 6y agoThe LSP pattern allows for bringing anything you’d find in an ide to other targets (like code review tools, as used by GitHub). I used to be a language purist, but nowadays the costs of not using an ide or lsp supported tools is just too high. I’d prefer minimal tokens and abundant secondary notations provided by parsers than having to add clunky syntax myself.
- lucideer 6y ago
- breck 6y agoI agree. You do need to check the inferred return type (sometimes it will infer a union or new interface you didn't intend), but it helps with refactoring and encapsulation to not add those annotations.