Ruby 3 - what do you want from it?

Don’t think we have a Ruby 3 thread - so here it is :023:

Matz talks about Ruby - the past the present and the future in this changelog episode :003:

Ruby 3 released before 2020

Matz is also asking for suggestions for the future of Ruby - what are yours?

My suggestion:

Matz, don’t just make breaking changes - make catastrophic ones. Rewrite Ruby 3 as if it was a new language. I’d be totally fine that it is incompatible with previous Rubies - I’m sure others would be fine rewriting their apps/libraries etc too - people are already doing that, by looking at other languages such as Elixir, Crystal, etc #FutureRuby :003:

Too crazy? :lol:

Current Ruby 3 goals are.

My hope for Ruby 3 is for Refinements to be fixed (2) and made more usable. I’d like refinements to be usable in any scope with block syntax just like Rust’s use syntax.

I also want Ruby 3 to give more howto documentation and especially cover vague areas like threading and their standard library (dRuby, http etc).

1 Like

I think your idea will properly need to wait for Ruby 4 at least :stuck_out_tongue:

1 Like

I’d only want static type checking if it could be done with type inference.


I don’t mind that - 4 is my favourite number after all :003:

Ruby is pretty good. So good that only fantastic things come to mind:

  1. Simpler syntax. A parser extendable in Ruby(to make Ruby a programmable programming language). Something alike to Lisp but with objects instead of lists.
  • Ability to save a Ruby program state to a file at any point, and then resume it from any computer having Ruby installed. Something alike to Smalltalk images.
  • Only these names starting with a lowercase letter should be allowed for methods(to be able to distinguish them from constants easily).
  • ‘ends’ should be optional(‘dos’ probably should be optional too if the block takes no arguments). The parser should infer all the things from indentation if necessary.
  • Ability to use lazy recursion like in Haskell and don’t get stack overflow for that.
  • AOT-compiler to native code capable of generating static binaries
  • And, of course, static typing(naturally following as a prerequisite for the many previous wishes). But users should never be required to specify anything. The compiler should infer structural types by itself.
  • Reasonable backward compatibility with Ruby 2.
  • Oh, almost forgot that one, concurrent execution on all CPU cores with sequential code. Something alike to:
require 'socket'

server = '/tmp/my.sock'

loop do
  client = server.accept
  go { communicate with client }

Can any of these be done(theoretically, at least)?

1 Like

I’ve done both tail call recursion and lazy enumeration in Ruby so I don’t see why you can’t do both. Danny Gunther has written some very in depth articles on tail call recursion optimization in Ruby: Tail Call Optimization in Ruby: Deep Dive & Tail Call Optimization in Ruby: Background . Combine it with Enumerator::Lazy and I think you’re golden.

I’m not familiar with Lisp, but the Crystal language is pretty much a compilable Ruby-esk language written in Crystal so you can program the language itself in itself. Perhaps this covers number 6 as well? Crystal does your number 7 and 8.

I don’t understand your numbers 3, and 4. And as for the second part of four

I really don’t like this as Ruby infers nothing from indentation other than multi-line comments. That sounds like pure Python to me.

Ruby already handles concurrency with forks and multiple processes. Threading is the only thing that has an issue with the GIL (global interpreter lock). Threading works up to point and has no issues where IO is concerned. So threading works better for web servers rather than gaming at the moment. In Ruby 3 their aiming to fix the GIL issues.

Here’s a great writeup on Ruby concurrency and threading: Ruby Concurrency and Parallelism: A Practical Tutorial


Oh! There’s a really nice gem call hamster which provides thread safe collections. You should check it out! :smile:


Thank you for your response and the links. It is very detailed look into MRI internals.

I cannot, however, honestly say that tail recursion is quite satisfying for me. What I really want is a Ruby implementation which can deal with something like this:

class Array
  def reverse
    if empty?
      head, *tail = self
      tail.reverse << head

(Thank you for your other comments and suggestions as well. I hope it’s fine if I respond to them later, because I have no time for that right now.)


Your code example works up to the 10,035th array length. You can go way beyond that with the following implementation.

class Array
  def reverse
    self.reduce([]) {|sum,item| [item] + sum }

But I get your point. Some languages have optimizations and can get past the seemingly infinite internal loop pattern. That would be nice.

1 Like

Hrm… I don’t think I’d like a Ruby with haskell-y lazy eval everywhere. It might be interesting to be able to explicitly opt-into lazy eval though. I’m not sure how that wold look syntactically. I once created an “infinite” fizz buzz in Ruby using the lazy enumerable and I ended up simulating thunks using procs.

1 Like

I really want macro-based metaprogramming, like Crystal.

I also really want lightweight actor model for concurrency, like Crystal.

I’d like to have better performance, and to utilize the efforts behind LLVM, like Crystal.

I’d like to distribute my program at the object level across multiple or many machines. I’ve heard of dRuby, but I have never tried it, and at this point it’d be more effort to pick it up than it would to just use Celluloid’s DCell or some such similar offering.

I’d like a higher level of modularity in what gets dragged along with my program. I don’t want/need ObjectSpace, I don’t want/need a bunch of extra classes that I never even called. When I build a release, only the classes that I utilize should be included. Java’s Project Jigsaw does this.

I’d like to get rid of globals. I don’t mean don’t ship any globals, I mean NO GLOBALS, ever, at all, under any circumstance.

I agree that these should all be big breaking changes. Other people are writing their programs in other languages, and if Ruby is going to live onwards, we’re not only going to have to capture new programmers but we’re going to have to recapture old ones that have been scorned.

Frankly, I’m content to let Ruby die and let the Crystal crew keep moving forward. They’ve made tremendous progress and I foresee nothing but good things from them. On top of that, Crystal is already blazing fast, conceptually very easy to use, and seems to only be gaining steam on the development front. Documentation is a bit lacking for now, but I’m sure it’ll pick up once the project gains more steam and especially once Crystal starts approaching some sort of 1.0.

I want to drop the mic with one last remark: Rails killed Ruby and I won’t feel bad when Rails crashes and burns.

1 Like

You seem to have some very harsh opinions. Ruby won’t die that I’m sure of.


Sure do, buckaroo. I’m not sure that it will die or not. There’s certainly quite a bit of junk Rails code floating around to work on, it’ll probably linger around like Perl. Unlike Ruby however, Perl has seen the next generation of computing problems and has put together the foundations for another twenty years with Perl 6.

We’ve learned a lot from Ruby, and without a total teardown and rebuild, I don’t think it’s really worth it moving forward. If Ruby 3 is just Ruby 2 with a couple more modules and sugar, I think my point will end up proving itself in the years after.

1 Like

If I wanted to remove anything from Ruby it would be no global variables and no attr helper methods. Many of the people I’ve seen use attrs don’t get their purpose or use.


Yeah let’s definitely focus on removing functionality. Good idea

The language will work the same without global variables or attr helpers. Just use constants and be declarative with your setter and getter methods.

What are the “attr helpers”?

It’s shorthand for writing setter and getter methods for instance variables.

class Example
  attr :a 
  attr_reader :b
  attr_writer :b
  attr_accessor :c
  def initialize
    @a = 42

e =
# => 42
e.b = 7
# => 7
e.c = "a"
# => "a"