Hacker News new | past | comments | ask | show | jobs | submit login
Ruby3 Will Have Types (twitter.com)
232 points by darkdimius 5 hours ago | hide | past | web | favorite | 116 comments





Very cool! I didn't think this would happen, as Matz has expressed disinterest in adding type annotations. However, keeping an open mind and reconsidering one's positions are the hallmarks of a great leader :D

I worked on a summer project to add type annotations to Ruby. Didn't get very far since I ran into some challenges with the internals of the parser and the parser library, Ripper. I'm extremely interested in seeing how the Ruby team designs the type system. It'll be gradual, of course, but also it'll be interesting what adaptations they'll have to make to accommodate existing code. JavaScript relied on a lot of stringly typed code, so TypeScript added string literal types. Perhaps Ruby's dynamic, block oriented style could lead to some interesting decisions in the type system.

Not to mention, the types will most likely be reified as per Ruby's philosophy.

Super excited for this. Between the JIT and types, Ruby could definitely see a renaissance in the near future.


Indeed Sorbet does have literal types for strings and Ruby symbols. We're still figuring out the details and converging on a common type system for Ruby3, but we've found them super useful, as you rightly point out!

And +1 on the Ruby renaissance! Super excited about all the exciting things that are currently being built!


I can't wait for Sorbet's open sourcing! Ngl I tried decompiling the wasm binary just for fun. Not that it ended up being readable haha

We're currently looking for beta users! Reach out to us at sorbet@stripe.com. If you describe your team&codebase in the email, it will help us figure out what cohort to include you in.

What is the rationale of adding types to a language that will still retain all performance penalties from the need to have dynamic typing code to interact with non-typed data?

The rationale is that types are there to check correctness (types as proofs), not to improve performance.

Speed is not the first and foremost benefit of types. Type checking is (and other stuff that comes with that, like better completions, self-documenting code, etc).


Who's to say we couldn't use the types to make the runtime faster in the future?

One of the reasons why Sorbet does both runtime checking[1] more than just static checking is so that we can know that signatures are accurate, even when a typed method is called from untyped code.

If the signatures are accurate, a future project could take advantage of method's signatures to make decisions about how the code should actually be run. If the signatures lie, then any runtime optimization made using the types would only be overhead, because the runtime would have to abort the optimization and fall back to just running the interpreter.

[1]: https://sorbet.org/docs/runtime


Well I am skeptical about performance improvements due to type annotations as well. Other languages have similar different systems and didn't get faster.

Dart had gradual types but didn't enforce them at runtime because of performance. The PyPy devs don't believe that type annotations help them for performance (http://doc.pypy.org/en/latest/faq.html#would-type-annotation...). Also there is no JS engine that uses TypeScript annotations so far to improve performance.

Types are usually on the wrong boundary: e.g. Integer doesn't state whether that value fits into a register or is a Bignum.

Also: Aren't some type checks quite expensive? So more expensive than a simple map/class/shape check? E.g. passing an array from untyped code to a signature with something like `Array<Integer>`. Wouldn't a runtime that verifies signatures have to check all elements in the array to be actual Integers?


I work on an alternative Ruby implementation, and it looks like I'll be able to take these type definitions and use them to add extra type constraints to my intermediate representation very easily - just insert a type constraining node around each expression that's annotated with a type. It'll remove extra guards and increase performance, so should definitely be an option.

I programmed C back in my high school years 14+ years ago. Today I am mostly using JS because it is the cash crop of the industry, and it made me quite some money when I was away from electronics business (my main occupation) for a year after getting troubles with Canadian visas.

To me, it feels that there is a very thick wall in between high level languages and something with raw data access like C, C++, and D. You either completely throw out every convenience feature, or go all in on them.

In C, a lot of data access turns into single digit number of load/store or register access instructions. It is easy to see that it is close to impossible to add fancy data access functionality on top of that without going from single cycles to kilocycles.

I was once told "when your try improving a programming language performance, it eventually turns into C"

P.S. on JIT - it is not given that a JIT language be automatically faster than a well written interpreter on a modern CPU. One of early tricks of making fast interpreters was to keep as much of interpreter in cache and data in registers as possible to benefit from more or less linear execution flow of unoptimised code in comparison to unpredictable flow of JIT made executable code. Today, with 16MB caches, I think the benefit of that will be even bigger.


> I was once told "when your try improving a programming language performance, it eventually turns into C"

Which is kind of ironic given how bad C compilers generated code during the mid-80s, versus other mainframe languages.


Types are the means of "improving language performance" without turning into C. It's all about encoding invariants for the optimizer.

I doubt a competent JIT is ever slower than a competent interpreter, but it may not be that much faster or worth the workload.

It depends on the size of the primitives. An array language could be close to 1:1, while for a cpu-level instructions you will struggle to reach 1/6 of JITted perf.


You forget this is ruby, which will not have a competent JIT. They have such a bad JIT with enormous overhead that only very special cases will be faster, most cases are slower and will wait for locks or be racy.

Readability most likely. Type checking tends to also reduce basic bugs from mismatched inputs as well.

so that you can gradually add types?

now that ruby has an actual jit compiler, it could benefit from typing to optimize code further. And a gradual migration process will help people speed up parts of their code. Unless they mess it up like python where abstractions are costly.


With types you get more compile-time checks - safer code, better documentation, and the possibility to improve runtime performance and ffi. With a guaranteed int you don't need to check for bignum overflows, and you can avoid all runtime type checks. A typed ffi struct can be used as is for the ffi, raw data. strings are guaranteed to be 0 delimited.

In certain basic blocks typed ints or floats can be unboxed, if they will not escape. This is what php7 made 2x faster. the stack will get much leaner. simple arithmetic ops can be inlined, using native variants. ops with typed vars cannot be overridden.


We're collaborating with @yukihiro_matz, @mametter, @soutaro and Jeff Forster to make sure that types are not disruptive to Ruby. Thus, types are optional. The intention is to deliver value for unmodified Ruby programs. Hear more from Matz at https://youtu.be/cmOt9HhszCI?t=2148

As long as types can be required to be explicit where ambiguous (e.g., TypeScript) in the file itself (via a magic comment or similar), I'm all for it. I am happy to declare types for external calls if I need to.

I have said for awhile that "Ruby with types" would be my favorite language to work in. I recently returned to Ruby briefly and had to integrate with a poorly-documented API. I spent more time digging through third-party code trying to figure out what certain parameters were supposed to be than writing the program itself.


So, something along the lines of https://github.com/soutaro/steep but without the annotations in the original source code, because Matz said "no annotations". That's nice because it doesn't pollute the code. I use Ruby because of Rails and because I don't have to write types. I can use many other languages if I want to write them.

Fascinating to see the circle turn further back towards strong / static typing.

One of the major things that has kept me using Groovy over the last 10 years was the reluctance to leave optional / gradual typing behind. Now, nearly every major dynamic language has given in and introduced types, so it seems like this idea of hybrid dynamic/typed languages is now fully mainstream. The problem of course, is they are all built on a legacy of untyped code, not to mention giant communities of people with no culture or habit of tying their code. So it's not clear to me that any amount of added language features can actually compensate for that.


I get what you mean, but dynamic typing is a feature, just like static typing is.

Some languages are better from a static POV, and offer some auto features. Some languages are better from a dynamic POV and offer some hinting feature.

You don't want to type your code to do data exploration and analysis, but you may want to extend the original project later to something bigger and move on to types.

There is no such thing as the perfect language for everything anyway. Plus, it's very good that some languages integrates unnatural features to them, for the case where you want to go beyond their initial best case scenario. It won't be perfect, but I don't need perfect, I need programmatic.

The world of programming is vast, the pool of programmers very heterogeneous, and the constraints are super diverse.


I expect a split between very strictly coded and strongly typed everywhere libraries and shared components, and looser high level scripts mix and matching when convenient.

That could be the best of both worlds.


I understand why PHP started to add support for type annotations as the hype around type annotations (Dart, Flow and Typescript) still was quite strong a few years ago.

By now I think it is quite obvious that type annotations aren’t as helpful as initially expected and that a library approach seems more pragmatic and more powerful. See Clojure + Spec.

The thing is dynamically typed languages with type annotations tend to no longer feel like dynamically typed languages as the annotations and the tooling spreads and spreads and spreads. Not easy to put up boundaries.


Types are massively helpful with JavaScript. I’ll never write untyped JS again if I can help it. Switching to typescript has done wonders for my productivity and code quality.

It's it obvious?

There seems to be a never ending cycle of new languages that are dynamically typed because it is easy for small codebases, which then become popular, get large codebases and then realise that static types are actually a really good idea.

Python, Dart, Ruby, JavaScript (via Typescript), etc...


This is HUGE! Ruby's pace of development continues to impress. It's always been an impressively practical language and keeps getting better.

Ruby already had types, no? This is about static typing.

Interesting. I thought the Ruby community generally prefers shorter code, e.g. `to_s` instead of `to_string`, and yet that type signature is very verbose: `sig {params(x: Integer).returns(String)}`

Integer and String are the actual classes:

    “foo”.class # => String

The type signature in (secure) ruby [1] - an alternative ruby (subset) with type (optional) annotation - is `sig Integer => String` or `sig [Integer] => [String]. Since the sig is just ruby you can create an alias for types e.g. I = Integer, S = String and than use sig I=>S, for example. [1]: https://github.com/s6ruby

small discussion that was marked as dupe https://news.ycombinator.com/item?id=19696669

The trend of adding type annotations to dynamically typed languages is now unstoppable. I wonder if some more exotic features (eg. side effects handling, monads or dependent types) will ever become mainstream in the feature.

It's hardly unstoppable its been there for literally decades. Common lisp had it for a very long time for example and has a few compiler implementations that are really quite sophisticated.

The problem is that most popular dynamic languages are really quite terrible. They have atrocious runtime environments and usually quite limiting language semantics.


You could argue that something that has been around for decades is unstoppable :)

I recommend whatching "Ruby3: What's Missing?", a presentation Matz gave earlier this month: https://www.youtube.com/watch?v=cmOt9HhszCI

This might be misleading. That is, jump to around the 29 minute mark where he talks about the type profiler and .rbi file stuff.


As a user of Homebrew, I just wonder if Ruby's ever going to have performance.

homebrew's performance is mostly network (git / http / https) and compilation times when needed.

also for some reason homebrew really likes to updates its index all the time (I think it got tamed in the newest version), but setting HOMEBREW_NO_AUTO_UPDATE to 1 helps a lot.


It is no worse than python, but with the 3x3 initiative the main implementation will be a lot faster than today, which will never happen to python unless the current lead will go 180 degrees against what Guido always claimed.

> It is no worse than python

Eeeeeeeh…


Yes and no. You need to basically fork the compiler and invent a new type of ruby that sacrifices certain things in favor of performance.

FYI: For an alternative ruby (subset) with type annotations today see sruby, that is, secure ruby - https://github.com/s6ruby

The biggest problem for me with gradual typing is code clutter. My favourite languages are Clojure and Ruby precisely because they reduce code clutter. What I would prefer, if we are to have types, is for the signatures to go in a companion file. I've never understood why types have to be inlined. A good IDE can easily provide the signature in a mouseover or something similar.

The way to reduce clutter in strongly, statically typed languages is to use strong, robust type inference.

For example, Java is pretty terrible at type inference (still) and you have to annotate types almost everywhere (Java 8 had a very tepid improvement on that front.)

But languages like Haskell and Rust are very good at type inference, and you almost never actually need to specify the types.

It's still good Haskell style to always annotate the type sigs of top-level functions. Why? Because they serve as more than just hints to the compiler: they are part (and a very important part!) of the documentation. That is why they're in-line. Because A function like

    zipWith:: [a] -> [b] -> (a -> b -> c) -> [c]
tells you what it does in its type signature.

There's nothing lost by putting the sig in a companion file and leaving it to your editor/IDE to provide a popup.

Java 10 and 11 introduced real type inference, at least for local variables and function parameters.


what's cool is that you can write your types in another directory / another repo, e.g. https://github.com/sorbet/sorbet-typed

Instead of:

  sig {params(name: String).returns(Integer)}
... why not simply:

  sig {name: String, returns: Integer}

Ruby itself has zero changes from sorbet, so all sorbet syntax has to be valid Ruby. `sig` is implemented as a library.

In this case, your example is not valid syntax, which violates this rule. Not that I personally could tell you why the parser makes a distinction here, but it's at least part of the reason :)

  irb(main):010:0> foo {a: "b"}
  SyntaxError: (irb):10: syntax error, unexpected ':', expecting '}'
  foo {a: "b"}
       ^
  (irb):10: syntax error, unexpected '}', expecting end-of- input
  foo {a: "b"}
            ^
   from /Users/bhuga/.rbenv/versions/2.4/bin/irb:11:in `<main>'
  irb(main):011:0> foo {params(a: "b")}
  NoMethodError: undefined method `foo' for main:Object
   from (irb):11
   from /Users/bhuga/.rbenv/versions/2.4/bin/irb:11:in `<main>'
  irb(main):012:0> 

The `sig` syntax has gone through multiple iterations; within the boundaries of Ruby syntax this is the best we've had.

The parser thinks that's a block not a hash.

Right, so why not implement the sig as a block and keep the syntax concise - the Ruby Way.

The sigs are implemented as blocks.

We had them as hashes for a while, but it meant that code in all sigs was loaded as the code was loaded, even if runtime typechecking was disabled. We were forced to load all constants in any signature in a file, an effect which cascades quickly. It had a big impact on the dev-edit-test loop.

For example, if we're testing `method1` on `Foo`, but `method2` has a sig that references `Bar`, we'd have to load `Bar` to run a test against `method1`.

Now sigs are blocks and lazy, and we pay that load penalty the first time the method is called and a typecheck is performed.


Instead of:

   sig {params(name: String).returns(Integer)}
... why not simply:

   sig [String]=>[Integer]
Yes, that's just ruby - see https://github.com/s6ruby/ruby-to-michelson/blob/master/cont... for example for live running code (in secure ruby) :-)

At the very least, sigs need to be in blocks so they can be lazy and not require that all constants in any sig be loaded at require time.

It was a design decision that all type annotation arguments be named as opposed to positional. As one example why, it makes the error messages better. You can always say "You're missing a type declaration for parameter 'foo'" as opposed to "You have four positional arguments and 3 types".

We could probably still bikeshed our annotations inside the `sig { ... }`. I'm not sure we'd make constants with unicode like BigMap‹Address→Account› for generics, though, how do you even type that? :)


Ruby has named parameters right? In theory signature needs parameter name and wouldn’t be sufficient for all cases to with a simple String in Integer out I think.

How would you write the type of a function that takes a parameter called `returns`?

Simple - make 'returns' a reserved word.

It looks like they've conflated type with class. If so, that's the antithesis of duck typing. The impedence mismatch to Ruby seems to me an overwhelming contraindication.

Not sure you can call yjis conflation. From what I've read that was a deliberate thought out decision and a nominal type system is as valid a choice as a structural one and generally better understood in research and industry.

Having said that as far as I understand, type support in Ruby 3 will not prescribe which type checker is used and what limitations exist. Some of the mentioned projects are structural and I think even Sorbet might add support for it at some point.


> It looks like they've conflated type with class.

Classes are types by default, but you can define non-class types as well: https://sorbet.org/docs/abstract


Well, classes are types in a language where everything is an object. It's the same in Smalltalk, no?

Do you have any reference to any documentation of how they implemented types?

The docs say "Every Ruby class and module doubles as a type in Sorbet" and it was explicitly described as a nominal type system in a talk at Strange Loop 2018.

FYI: You can add the missing Bool type today :-), use the safebool library / gem - https://github.com/s6ruby/safebool

Nice! Reminds me of crystal[0], the LLVM-compiled ruby-alike language.

0: https://crystal-lang.org


Except crystal's type system seems much more capable & powerful.

My concern about all of this is that it might lead to basically two ruby communities; Rails and Rails devs will mostly keep writing type free code (dhh has always indicated he's not a fan of types), but a lot of other rubyists will gradually introduce types into their code. This could create two different ecosystems with different gems, best practices, blogs etc etc etc. We will see how it plays out but I'm quite conflicted about this one. The good thing is that it's optional.

It’s not in the tweet but we specifically covered that it’s possible to type check Rails in our talk actually:

- https://sorbet.run/talks/RubyKaigi2019/#/53

- https://sorbet.run/talks/RubyKaigi2019/#/55

So I don’t think that the divide will be at Rails. And more than that, I think there will be very little divide at all. Sorbet is designed to be gradual, so it works 100% fine with untyped code:

https://sorbet.org/docs/gradual


Hi thanks for this! Could you shed more light on the last part where they show parts of Rails, Gitlab etc are already typed? How is this possible?

Sorbet has multiple Strictness Levels[1]. The two most relevant ones are `typed: false` and `typed: true`. `typed: false` is the default level and at this level only errors related to constants are reported, like this one:

https://sorbet.run/talks/RubyKaigi2019/#/14

But we'd like to catch more than just errors related to constants, like those related to missing methods, or calling a method with the wrong arguments. Errors like these are only reported in files marked `typed: true`:

https://sorbet.run/talks/RubyKaigi2019/#/19

Sorbet doesn't need to have method signatures to know whether a method exists at all, or what arity that method has.

But more than that, Sorbet ships with type definitions for the standard library. So you don't even need to start annotating your methods to type check the body of your methods, because most of the body of your methods are calling standard library things (arrays, hashes, map, each, etc.).

The statistics in those slides are sharing "out of the box, what's the highest strictness level that could be added to a file without introducing errors?" So ideally an entire project be made `typed: true`, but Sorbet can be adopted gradually, so a project can exist in a partial state of typedness. We wanted to see how painful it would be to adopt Sorbet in a handful of large, open source rails projects, and it turned out to be not that bad.

[1]: https://sorbet.org/docs/static#file-level-granularity-strict...


Can you comment something about the possibility of Ruby getting faster because of Sorbet ? Can it be combined with DragonRuby or other compilers that would produce more optimized Ruby programs?

Yes it is optional until it gets hard to find a job with typeless Ruby. And indeed split Ruby communities just as with Javascript. The bad thing is that static typing in dynamic languages is HOT, which means if you don't move over to the typed camp you will look old and stupid.

typescript, es6, es5....

perl6 and python3 were my first thought. I think this is great though, but maybe they should change the naming of this new version completely so that they can make a clean cut. Rather have less backward compatibility and clean design as opposed to forcing a square peg in a round hole

I don't use Ruby day-to-day other than a few small tools, but why not focus efforts on evolving Crystal [1] to make it more suited for rapid web development? It already has a powerful type system and incredible performance, and should be an easy transition for rubyists.

[1] https://crystal-lang.org/


Because it is about Rails and tons of useful gems which would need to be ported 1:1 to Crystal, plus keep compatibility with CRuby for some time. Too much effort which nobody would pay for.

I agree with this sentiment. I like the type checking in Crystal, and it is pretty much the newer, younger brother to Ruby. I don't see the issue of leaving Ruby pretty much 'as is' so that legacy code does not break, and focus on making Crystal a much better evolution of Ruby.

Why should the people who built and maintain Ruby focus their efforts on a different language?

Why is everything moving to types?

Generally no one uses dynamic typing for the abilities it gives you. Do you declare string variables to later assign them to numbers? Do you dynamically add new functions and properties to objects? Do you ever really need the flexibility that dynamic typing is giving you?

If not then why are you using a dynamically typed language? If you're not using it's abilities then it doesn't sound like the right tool for the job.

It's like a cost/benefit analysis where none of the benefits you're using, and the cost is the total inability to validate, refactor, and navigate your code base.


> Do you declare string variables to later assign them to numbers? Do you dynamically add new functions and properties to objects? Do you ever really need the flexibility that dynamic typing is giving you?

Yes, yes, and no. I do most of my work in languages that prevent the first two, but when I do have access to this kind of runtime trickery I do use it when useful.


> Do you declare string variables to later assign them to numbers? Do you dynamically add new functions and properties to objects? Do you ever really need the flexibility that dynamic typing is giving you?

The issue is not "Do you purposefully do those things?", but rather "Do you have a call stack where you can't guarantee it won't happen by accident?" Type checking is not relevant when you know what will happen and want the dynamic/ducktyping behaviour.

Another issue is: I'd use a different framework which doesn't use Ruby, but this was the most productive framework at the time the codebase was started, and nobody will port that many lines of code to a non-dynamic language now. So the best course of action is to validate the current code is not overly-dynamic.


I think most rubyists do benefit from dynamic types. How easy would it be to build rspec and Rails in java? The whole dependency injection thing in Spring is in part a by product of types making it way harder to test things. That's just one example.

I believe it depends on the use case. If you notice, Stripe and Coinbase are the first few companies that use the type system. They are both dealing with financial systems and numbers in general where having types would help a lot in catching errors and bugs earlier. I've worked on financial systems before in a dynamic language, JavaScript, and from my experience there would be cases where a number would be passed from a place where it's a string (in a textfield) that then needs to be passed around as an integer at times. Type systems would help catch bugs here or in similar situations.

It's a sad state of affairs. Every programming language is just copying the 'next cool' feature from another language. Duck typing, deconstruction, functional stream-like constructs you name it. I guess this ends when every language features is copied and we get X omni languages with Y omni SDK's all having same features with different syntax. The thing is that I only really need 1 omni language, not a dozen of them, so I feel that all the feature stealing in the end will be detrimental to all but the best supported omni language.

I guess some companies started fast with Ruby/Python and similar and instead of rewriting to static/typed languages they pushed forward features that would allow them to just continue where they left off at the expense of having a more concise problem oriented programming language that's good for solving specific problems.


Because it's easier to deal with your CI telling you that you made a mistake before a deployment, than with Rollbar telling you that you're losing money due to a stupid bug in a case you forgot to test for.

It does seem like there is a fad around moving to types, mostly because of typescript's current popularity.

Will be interesting to see how ruby handles types vs duck typing etc 10 years from now, when the new best practices have been figured out.


There is benefit to future proofing code with basic static analysis for type checking.

But it is always an incomplete solution because a) old code needs to be retrofitted, see TypeScript's way of defining type maps for vanilla JS or b) more commonly you keep the code around that's using unsafe types, effectively passing void*|Object|"choose your poison" around.


I don’t know but I hate it. Not sure if I’m in the minority but it sure feels like it. In an ideal world. I feel that types are something that should be dealt with at the IDE level. In fact, there so many things that can be done at that level, but no one has really been brave enough to do so I suppose.

So, what, everyone standardizes around an IDE then? You really think that's gonna unite the vim and emacs camps?

I'm personally tired of staring at variables trying to figure out what they're supposed to be, then having to dive into source to see how its used. C/C++/C# solved that problem, why are we still dealing with it?


C had some typing, but I'm not going to call it "solved" until "numberOfHats = distanceInPixels + weightInKg" is considered a compile-time error due to the three "int" values being incompatible; but "numberOfHats = aliceHatCount + bobHatCount" is acceptable.

How does nobody(?) support this yet?

Python supports some parts: you can subclass int, and you get all of the int methods like addition and subtraction for free, but "distanceInKm + distanceInKm" gives you an int instead of a distanceInKm; and "distanceInKm + distanceInMiles" gives you an int instead of an error.

Rust also has partial support but from the other end: distanceInMiles and distanceInKm can be two distinct subclasses of int, and adding them together is a compile time error. But also adding distanceInMiles with distanceInMiles is a compiler error, because these are basically "completely new classes" rather than "subclasses of int", and so you have to implement add / subtract / stringify / etc for yourself for every type D: (I'm fairly new to Rust so if there is a shortcut there that I'm missing please do point it out)


It rarely happens to me that I stare at a variable and have to wonder what type it is. And yes, an IDE like Rubymine is becoming crazy good at autocomplete and method lookup. I think the experience of developing on Rubymine isn't that far behind from Intellij nowadays. Not everyone have to use the same IDE, the vim or emacs guys will have to find equivalent tools.

What do you mean by types being dealt with at the IDE level?

Depending on your type system, a well-typed program can eg run faster, because the compiler / interpreter can elide certain runtime safety checks that would be necessary in untyped code.

If your type system is crazy enough, you can even track the runtime complexity of your program at the type level, including whether your program runs in finite time. See eg Dhall (https://dhall-lang.org/) whose type systems only allows programs running in finite time.


I think what GP means is that the IDE for a theoretical programming language could automatically infer types and have you not type any code for that explicitly. It might even not show you types as code at all and by default and overlay/add this info only on request.

Generally, there is this huge disconnect between how code is expressed as text and how it is handled in as a graph structure inside the tooling. It is soon time to move beyond simple text files for code, I believe.


Ruby being so dynamic means that without type annotations you cannot infer the type (or types) within a variable statically, so you basically have to eval the program, which in Ruby means basically running the whole codebase.

So, please, be brave and evaluate a 100kloc codebase+deps that may contain a top level `rm -rf ~/`


In an ideal world, humans write bug-free code ;)

But honestly, if you're asking your IDE to do it, that means you're asking your IDE to do static analysis of your code - and type-checking in a lot of ways is just another static analysis technique. And for a lot of us (myself included) we prefer to catch as many of these bugs as possible using static analysis, instead of waiting for someone to get paged when it causes an outage.

Yes, there's a trade-off, and types can be obnoxious (Java imports being probably one of the worst offenders, C++11 introduced `auto` for a reason), but that's the cost we pay.


By IDE level, you mean compile level. Types are at compile level.

No, types can be at compile level. They can also be checked without compiling any time you like. Or automatically. By an IDE, for example.

Almost all good IDEs are essentially interactive compilers. The lines have blurred during the last two decades. For example, QtCreator and XCode use clang to provide code annotations in the editor. Eclipse is built around ECJ, its own Java compiler, which exists mostly to provide information back to the editor and refactoring tools (the editor maintains a complete bidirectional mapping between code as text and code as AST at all times). Code generation is almost only a byproduct there.

I come from Assembly and C, now working in Javascript. One of the reasons I made the move to JS is dynamic typing, getting rid of that administrative pain and now being able to create stuff much faster. Even in large JS apps I hardly ever have type related bugs at all, and when I have one I fix it mostly within minutes, don't need an entirely different language and ecosystem for that.

Now the JS fanboys discovered and moved (from Coffeescript to Babel ESxx) to Typescript they apparently think that they can write beautiful and bugfree software just because of static type checking! Let them please move to C++ or whatever statically typed language and shoot themselves in the foot by making all those mistakes that have nothing to do with static type checking at all! Oh, and of course hitting the wall because they are missing their precious 'any' keyword!

I totally agree that type checking for dynamic languages should be done in the IDE, tooling. But static typing in the dynamic language world is a hype at the moment, so we'll have to go through a wave static type checking frenzy. For my work I look at horrible code bases, perfectly typed and strictly formatted by tslint..


I started using TypeScript back when it was 0.8, before it even had generics. Does that make me a fanboy? I have a project with about 45k SLOC of TypeScript (using Knockout.js for presentation). There is really no way I would maintain that same project without types.

> For my work I look at horrible code bases, perfectly typed and strictly formatted by tslint.

There is no language that can stop people from producing horrible code.


C/C++ doesn't really have much static typing to speak of. I don't think you are realizing the power of real statically type languages, such as Haskell, OCaml, or Scala.

Harder to make bugs. Better documentation. Typed code is easier to optimize - just look at Crystal performance. Better IDE/Text editor tools. Simpler deploy / distribution - just copy a binary file. I really wish there will be optional type to prevent nil errors at compile time.

Because TypeScript has proven that a type system can be helpful without being clunky and annoying.

I thought the ML family of languages showed that long ago? I guess TypeScript popularized the notion.

ML family has "type inference", which means the compiler figured out the type even if not explicitly written into the code. However, the language spec is still statically typed - an int will not turn into a string and vice versa (ex: "1").

Javascript and ruby, the underlying types can change depending on where the code is in execution - a variable holding a 1 can turn into a "1" and back (implicit type conversion - try 3 * "3"). This leads to a whole class of bugs not possible in a statically typed codebase where explicit conversion needs to happen - I have no hard data, but I remember debugging this type of stuff far too often and far too many times when I could've spend my time better elsewhere. (but I actually like ruby a lot!)

Type checking is not the same as being statically vs. dynamically typed!


This is super cool. I would expect the same support for Rails after Ruby 3 release

It's an interesting turn of event that Ruby, Python and JavaScript are all getting types.

Meanwhile, I've gotten myself more and more into Clojure. Which now that other dynamic languages seems to move closer to types, seems to be in a niche in that Clojure is moving further away from types.

It'll be interesting to see what happens at both extremes and in the happy middles.


>Clojure is moving further away from types

What about clojure.spec?


Why not a standard Common Lisp istead? Or even Scheme/Racket?

when Ruby 3.0 will be released? 2022 Christmas?

Not necessarily. There are certain things the core team wants to add to Ruby 3.0 and once all goals are reached, the next release will be called 3.0 (so we might possibly see Ruby 2.8, 2.9, 2.10 etc before).

The earliest possible date (and somewhere I read it's a probable one, but I can't find it right now) is Christmas 2020.


2019?

2019 is 2.7. GP is counting as if version numbers were decimals (2.8 in 2020, 2.9 in 2021, 3.0 in 2022 when it could just as well be 2.10)

Types will be optional right? Otherwise I am gonna have to jump ship sadly.


Ah yes, a last ditch effort to claw back an inferior language into the popularity again. This is nothing more than a knee-jerk reaction to loss of market-share to TypeScript / Python / Name your other buzz-language here (R)

Ruby inferior to Javascript and Python? What are you smoking? Python's BDFL begrudgingly added lambda to Python but amputated it to single-line expressions because he didn't want to "encourage" functional programming. By contrast Ruby is an artistically-curated blend of the best of Smalltalk, Lisp and Perl fully embracing functional programming. No contest.



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

Search: