7 ms·
I'm really puzzled by the decision to use a separate file for this. The stated justification ("it doesn't require changing Ruby code") doesn't make sense, and m
by setpatchaddress 6y ago
I'm really puzzled by the decision to use a separate file for this. The stated justification ("it doesn't require changing Ruby code") doesn't make sense, and my personal experience with languages with external type specifications is strongly negative. It's an unbelievable pain to keep multiple interface files in sync over time.
`.h` files are not something to emulate! External interfaces should be generated by tools where needed.
- fasterpython 6y agoYeah I agree with this. They cite the typescript compiler, which in addition to supporting .d.ts files also supports compiling regular JS in additon to separate TS files in the same project. I think this would have been a better approach for backward compat as well, so that users could upgrade to versions szupporting static typing and incrementally change projects one file at a time (leaving existing code intact).
- heavenlyblue 6y agoHow do you even type local variables?
- RangerScience 6y agoWhy would you need to? Edit: Like, seriously. Either the local var is populated by something coming in externally (which is then typable) or, unless your code is too complex / large, it should be easy to see everywhere it's used, and then why would you need that additional typing info?
- viraptor 6y agoCould be needed if you have a factory returning various subclasses, but you're making a call which you know will create only one type. Like `foo=open_database("mysql://...")`.
- frewsxcv 6y agoIf something is untyped in Sorbet, you can give it a type with `T.let`. So if the return value of function `foo` is untyped, but you have a high degree of confidence that it will return a `String`, you can do `ret = T.let(foo, String)`
- amw-zero 6y agoBecause when you see the benefit of type annotations (I’m not saying that’s objective, just if you do go that route) you want to add type information to as much as possible. Leaving them off because you want to is one thing. Not being able to is an unnecessary limitation.
- kgilpin 6y agoThe point is that the type of a local variable can almost always be inferred based on what it’s assigned to.
- amw-zero 6y agoWhile that’s true, that’s not what I’m talking about. I’m talking about the communicative benefit of type annotations. If you get the benefit from seeing the types, you don’t want them to be inferred. You use them as a reading tool.
- hombre_fatal 6y agoOne big use-case of types is the sanity-check that the value is what you think it is. A classic example of where I might have an inline type annotation in Rust is when I'm doing a non-trivial chain of Future/Result combinators in the middle of a function. It doesn't take much code for your understanding to desync from reality. Annotating "Result<String, IOError>" inline both documents to others what this intermediate value is but also creates better, local errors as the chain is modified. Complex stuff does generally get factored out into functions, but at the same time, it's nice when you're the one who decides when it makes sense to extract code rather than a limitation of the typing syntax. Those things don't always line up.
- rattray 6y agoI mentioned elsewhere that Sorbet (an implementation) allows inline type definitions. Its syntax for local variables is this: def foo username = T.let("heavenlyblue", String) end It's a little clunky but gets the job done, and in practice it's quite rare that you need to type a local variable. However, more important to have in the body of a program is tools for casting and asserting types, like these: T.assert_type(foo, String) T.cast(foo, String) T.must(foo) # assures the compiler foo is not nil T.unsafe(foo) # the equivalent of a TS `any` cast Docs at https://sorbet.org/docs/type-assertions https://sorbet.org/docs/type-assertions I'm not sure how tools that use RBS without inline syntax will handle these situations, but to be honest I expect the community to adopt Sorbet in practice anyway. It's very fast and battle-hardened in production at Stripe and several other large companies. Disclaimer, again: former Stripe employee.
- rattray 6y agoFWIW, you can use inline syntax with Sorbet[0], one of the two typecheckers that will work with the RBS format (the other being Steep, which does not have inline syntax). Here's a full example, complete with a typo, based on the example in the blog post: https://bit.ly/3hMEMSp https://bit.ly/3hMEMSp Here's a truncated excerpt to get the basic idea across: # typed: true class Merchant extend T::Sig sig {returns(String)} attr_reader :name sig {returns(T::Array[Employee])} attr_reader :employees sig {params(token: String, name: String).void} def initialize(token, name) @token = token @name = name end end Disclaimer, I used Sorbet while I was an employee at Stripe. I found it to be a terrific typechecker. It's also just absurdly fast (most of the time). [0] https://sorbet.org https://sorbet.org
- baweaver 6y agoSorbet was written in C++ and is a great piece of work, Stripe did a great job with it. It does have some issues as soon as someone gets into the magic weeds with metaprogramming like Rails does. Disclaimer: Working at Square, have friends at Stripe, enjoy both type checkers.
- cheez 6y agoThis syntax is horrible. I'm surprised they didn't just copy Python's typing syntax.
- Conlectus 6y agoAn important limitation here is that it needs to be valid Ruby syntax as well, since this was added without/before official Ruby typing support.
- Trasmatta 6y agoI believe one of their guiding principles was that they wanted all the syntax to be valid Ruby, because they did not want it to become a separate Ruby interpreter. So they were pretty limited in the syntax available to them.
- mekster 6y agoRight. TypeScript also doesn't require changing files and everything is opt in but you can add them inline. If the author thinks that's the biggest benefit, I'm inclined to think the ruby community doesn't seem to have enough eyes these days in the core development.
- michaelfeathers 6y agoSeparate files make sense if you consider typing a form of coupling. I pitched the idea for something like RBS in Ruby back in 2006. The reasoning is here: https://www.artima.com/forums/flat.jsp?forum=106&thread=155960 https://www.artima.com/forums/flat.jsp?forum=106&thread=1559...