Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby.next

 Ruby.next

Slide-deck from my presentation at Grill.rb 2018 in Wroclaw, Poland.

Bozhidar Batsov

August 12, 2018
Tweet

More Decks by Bozhidar Batsov

Other Decks in Programming

Transcript

  1. Божидар

    View full-size slide

  2. Sofia, Bulgaria
    Sofia, Bulgaria

    View full-size slide

  3. Ruby, RSpec & Rails
    style guides

    View full-size slide

  4. Not on Ruby’s Core Team

    View full-size slide

  5. Ruby is now mature

    View full-size slide

  6. We’re aware of all of our
    mistakes

    View full-size slide

  7. Compatibility is important

    View full-size slide

  8. Most ideas for changes will be
    discarded

    View full-size slide

  9. Ruby has survived for 24
    years

    View full-size slide

  10. Ruby is dead every year.

    View full-size slide

  11. People are still making a
    living with Ruby

    View full-size slide

  12. People are still making a
    living with COBOL

    View full-size slide

  13. Build the things your users need,
    instead of the things they want.

    View full-size slide

  14. The track record
    of
    recent Ruby innovation

    View full-size slide

  15. 3.times do
    puts "Ruby Rocks!"
    end

    View full-size slide

  16. •keyword arguments
    •%i
    •UTF-8 is now the default source file encoding
    •Refinements (experimental feature)

    View full-size slide

  17. •Rational/Complex Literal
    •defs return value
    •Refinements are no longer experimental feature

    View full-size slide

  18. •frozen string literals pragma
    •safe navigation operator (&.)
    •squiggly heredocs (<<~)

    View full-size slide

  19. •Unify Fixnum and Bignum into Integer
    •Support Unicode case mappings

    View full-size slide

  20. •Top-level constant look-up is removed
    •rescue/else/ensure are allowed inside do/end blocks
    •refinements take place in string interpolations


    View full-size slide

  21. Java innovates more!

    View full-size slide

  22. JavaScript innovates way
    more!

    View full-size slide

  23. Ruby.NEXT:
    Live Long
    and
    prosper
    by Bożydar Batsov

    View full-size slide

  24. •endless ranges (1..)
    •begin/else/end is now a syntax error (it used to be a
    warning)
    •some core lib methods now take optional keyword
    arguments (e.g. system(), Integer(), Float())
    •a first stab at MJIT
    •built-in AST module

    View full-size slide

  25. There’s no easy way to express
    an infinite loop with index in
    Ruby

    View full-size slide

  26. Float("foo", exception: false)

    View full-size slide

  27. Float("foo", exception: false)

    View full-size slide

  28. pry(main)> Ripper.sexp('alias :some :test')
    => [:program,
    [[:alias,
    [:symbol_literal, [:symbol, [:@ident, "some", [1, 7]]]],
    [:symbol_literal, [:symbol, [:@ident, "test", [1, 13]]]]]]]

    View full-size slide

  29. each(:method_add_arg, sexp) do |s|
    next if s[1][0] != :call
    receiver = s[1][1][1]
    method_name = s[1][3][1]
    if receiver && receiver[1] == 'Array' &&
    method_name == 'new' && s[2] == [:arg_paren, nil]
    offences.delete(Offence.new(:convention,
    receiver[2].lineno,
    ERROR_MESSAGE))
    add_offence(:convention,
    receiver[2].lineno,
    ERROR_MESSAGE)
    end
    end

    View full-size slide

  30. What about Ruby 3.0?

    View full-size slide

  31. Little is known about it…

    View full-size slide

  32. Little concrete
    is known about it…

    View full-size slide

  33. –Matz
    “We’ll aim to release Ruby 3 for the Olympic
    Games in Tokyo in 2020.”

    View full-size slide

  34. Duck inference?

    View full-size slide

  35. Better support for concurrent
    & parallel programming

    View full-size slide

  36. GIL -> Global Interpreter Lock

    View full-size slide

  37. GIL -> Guild Interpreter Lock

    View full-size slide

  38. https://olivierlacan.com/posts/
    concurrency-in-ruby-3-with-guilds/

    View full-size slide

  39. 3 times faster performance?

    View full-size slide

  40. (3 times faster performance
    than Ruby 2.0)

    View full-size slide

  41. Ruby 2.5
    is 154% faster than
    Ruby 2.0

    View full-size slide

  42. Getting rid of some quirky
    features?

    View full-size slide

  43. We’re not going to repeat the
    Python 3 mistakes!
    — Matz

    View full-size slide

  44. And what about the Perl 6
    mistakes?
    — Bożydar

    View full-size slide

  45. I’ve got a “secret” for you…

    View full-size slide

  46. There’s no real plan for
    Ruby 3

    View full-size slide

  47. Ruby 3
    is not a real release!

    View full-size slide

  48. Ruby 3
    is an idea!

    View full-size slide

  49. –Zach Tellman
    There has been a consistent migratory pattern
    from Ruby to node.js to Go, Rust, and Elixir. At
    first, each community is defined by its potential.
    But as that potential is realized, the community
    begins to be defined by its compromises. That
    change is felt most keenly by the people who were
    there first, who remember what it was like when
    anything seemed possible. They feel fenced in and
    so they move on, in search of their golden city…”

    View full-size slide

  50. Good artists copy; great artists steal.
    — Pablo Picasso

    View full-size slide

  51. We looked for “inspiration”
    everywhere…

    View full-size slide

  52. Visual Basic Script

    View full-size slide

  53. The Future of Java and the JDK
    Who’s in charge?
    https://www.youtube.com/watch?v=HpbchS5kmio

    View full-size slide

  54. Stewardship:
    The Sobering Parts
    https://www.youtube.com/watch?v=2y5Pv4yN0b0

    View full-size slide

  55. Maintainer vs Programmer

    View full-size slide

  56. Long-term vs short-term

    View full-size slide

  57. Foresight vs short-sightedness

    View full-size slide

  58. Key take-aways

    View full-size slide

  59. You need a clear strategy

    View full-size slide

  60. You need a detailed game-plan
    (roadmap) for implementing
    your strategy

    View full-size slide

  61. Additive changes, instead of
    destructive ones

    View full-size slide

  62. It’s better to deprecate than to
    remove

    View full-size slide

  63. Small increments

    View full-size slide

  64. Guiding principles

    View full-size slide

  65. Ruby Next,
    the language

    View full-size slide

  66. Design principle #0

    View full-size slide

  67. Continuous thoughtful
    innovation

    View full-size slide

  68. Design principle #1

    View full-size slide

  69. Continue to optimize for
    happiness

    View full-size slide

  70. Add some useful new features

    View full-size slide

  71. Make deprecating things easy

    View full-size slide

  72. class Foo
    # DEPRECATED: Please use useful instead.
    def useless
    warn "[DEPRECATION] `useless` is deprecated. Please use `useful` instead."
    useful
    end
    def useful
    # ...
    end
    end

    View full-size slide

  73. class MyFile
    extend Gem::Deprecate
    def no_more
    close
    end
    deprecate :no_more, :close, 2015, 5
    def close
    # new logic here
    end
    end

    View full-size slide

  74. Immutable data structures

    View full-size slide

  75. v = @[1, 2, 3]

    View full-size slide

  76. immutable hash

    View full-size slide

  77. m = @{one: 1, two: 2}

    View full-size slide

  78. immutable set

    View full-size slide

  79. s = @${1, 2, 3}

    View full-size slide

  80. s = ${1, 2, 3}

    View full-size slide

  81. [1,2] - [1,2,3] => []
    [1,2,9] - [1,2,3] => [9]

    View full-size slide

  82. ${1,2} ^ ${1,2,3} => [3]
    ${1,2,9} ^ ${1,2,3} => [9,3]

    View full-size slide

  83. .to_immutable

    View full-size slide

  84. Pattern Matching

    View full-size slide

  85. class Struct
    def deconstruct; [self] + values; end
    end
    A = Struct.new(:a, :b)
    case A[0, 1]
    in (A, 1, 1)
    :not_match
    in A(x, 1) # Syntactic sugar of above
    p x #=> 0
    end

    View full-size slide

  86. class Struct
    def deconstruct; [self] + values; end
    end
    A = Struct.new(:a, :b)
    match A[0, 1]
    in (A, 1, 1)
    :not_match
    in A(x, 1) # Syntactic sugar of above
    p x #=> 0
    end

    View full-size slide

  87. https://bugs.ruby-lang.org/
    issues/14912

    View full-size slide

  88. Design principle #2

    View full-size slide

  89. Simplicity is the ultimate
    sophistication.

    View full-size slide

  90. Less is more

    View full-size slide

  91. Simplicity leads
    to happiness.

    View full-size slide

  92. Let’s deprecate some stuff

    View full-size slide

  93. deprecate != remove

    View full-size slide

  94. Let’s deprecate some
    useless
    stuff

    View full-size slide

  95. for name in names
    puts name
    end

    View full-size slide

  96. names.each do |name|
    puts name
    end

    View full-size slide

  97. flip-flops

    View full-size slide

  98. DATA.each_line do |line|
    print(line) if (line =~ /begin/)..(line =~ /end/)
    end

    View full-size slide

  99. block comments

    View full-size slide

  100. =begin
    comment line
    another comment line
    =end

    View full-size slide

  101. Must be placed at the very
    beginning of a line

    View full-size slide

  102. class SomeClass
    =begin
    This is a top comment.
    Or is it?
    =end
    def some_method
    end
    end

    View full-size slide

  103. class SomeClass
    =begin
    This is a top comment.
    Or is it?
    =end
    def some_method
    end
    end

    View full-size slide

  104. Character literals

    View full-size slide

  105. pry(main)> ?a
    => "a"

    View full-size slide

  106. https://bugs.ruby-lang.org/
    issues/8468

    View full-size slide

  107. Refinements

    View full-size slide

  108. Let’s fix some stuff!

    View full-size slide

  109. and & or have the same
    precedence

    View full-size slide

  110. So many nils floating around

    View full-size slide

  111. pry(main)> "TOP".upcase
    => "TOP"
    pry(main)> "TOP".upcase!
    => nil

    View full-size slide

  112. Optional keyword param?

    View full-size slide

  113. pry(main)> 0.zero?
    => true
    pry(main)> 1.zero?
    => false
    pry(main)> 0.nonzero?
    => nil
    pry(main)> 1.nonzero?
    => 1

    View full-size slide

  114. Mutable strings

    View full-size slide

  115. Even JavaScript got this
    right…

    View full-size slide

  116. Frozen string literals are a
    step in the right direction

    View full-size slide

  117. ImmutableString

    View full-size slide

  118. Frozen strings?

    View full-size slide

  119. Reassignable constants

    View full-size slide

  120. Reassignable constants

    View full-size slide

  121. pry(main)> A = 5
    => 5
    pry(main)> A = 6
    (pry):39: warning: already initialized constant A
    (pry):38: warning: previous definition of A was here
    => 6
    pry(main)> Class = 3
    (pry):40: warning: already initialized constant Class
    => 3
    pry(main)> Class
    => 3

    View full-size slide

  122. Class variables

    View full-size slide

  123. class Parent
    @@class_var = 'parent'
    def self.print_class_var
    puts @@class_var
    end
    end
    class Child < Parent
    @@class_var = 'child'
    end
    Parent.print_class_var # => will print "child"

    View full-size slide

  124. Poorly named methods

    View full-size slide

  125. Kernel#println, anyone?

    View full-size slide

  126. Kernel#print

    View full-size slide

  127. [1] pry(main)> defined? 10
    => "expression"
    [2] pry(main)> defined? Test
    => nil
    [3] pry(main)> defined? TrueClass
    => "constant"

    View full-size slide

  128. Enumerable#include?

    View full-size slide

  129. Enumerable#includes?

    View full-size slide

  130. File.exists is deprecated in
    favour of File.exist…

    View full-size slide

  131. Perl-style special global
    variables

    View full-size slide

  132. $FIELD_SEPARATOR

    View full-size slide

  133. JRuby defines the English
    aliases by default

    View full-size slide

  134. Why can’t we do this as soon
    as Ruby 2.6?

    View full-size slide

  135. Why can’t we do all (most) of
    this as soon as Ruby 2.6?

    View full-size slide

  136. WTF? Global variables?

    View full-size slide

  137. Even Java doesn’t have
    globals…

    View full-size slide

  138. One more thing…

    View full-size slide

  139. –Matz
    “Ruby is no longer my project.
    It’s the Ruby community’s
    project.”

    View full-size slide

  140. File tickets

    View full-size slide

  141. Send patches

    View full-size slide

  142. Blog about the issues

    View full-size slide

  143. Speak about the issues

    View full-size slide

  144. Let’s make Ruby better
    together!

    View full-size slide

  145. Thanks!
    twitter: @bbatsov
    github: @bbatsov
    http://batsov.com
    http://emacsredux.com
    Grill.rb 2018
    Wroclaw,
    Poland
    11.08.2018

    View full-size slide