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.

1be785d1d788b82929e55fc83a9f0aaa?s=128

Bozhidar Batsov

August 12, 2018
Tweet

Transcript

  1. None
  2. Hello!

  3. Божидар

  4. Bozhidar

  5. Bozhidar

  6. Bożydar

  7. Bożydar

  8. Bożo cool

  9. @bbatsov

  10. Sofia, Bulgaria Sofia, Bulgaria

  11. None
  12. None
  13. None
  14. None
  15. bbatsov

  16. Ruby, RSpec & Rails style guides

  17. None
  18. None
  19. None
  20. None
  21. I’m back!

  22. None
  23. None
  24. None
  25. None
  26. None
  27. None
  28. None
  29. Not on Ruby’s Core Team

  30. Matz on Ruby

  31. Ruby is now mature

  32. We’re aware of all of our mistakes

  33. Compatibility is important

  34. Most ideas for changes will be discarded

  35. Ruby has survived for 24 years

  36. None
  37. Ruby is dead every year.

  38. People are still making a living with Ruby

  39. People are still making a living with COBOL

  40. Build the things your users need, instead of the things

    they want.
  41. None
  42. The track record of recent Ruby innovation

  43. Ruby != MRI

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

  45. Ruby 2.0

  46. •keyword arguments •%i •UTF-8 is now the default source file

    encoding •Refinements (experimental feature)
  47. Ruby 2.1

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

    feature
  49. Ruby 2.2

  50. Nada

  51. Ruby 2.3

  52. •frozen string literals pragma •safe navigation operator (&.) •squiggly heredocs

    (<<~)
  53. Ruby 2.4

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

  55. Ruby 2.5

  56. •Top-level constant look-up is removed •rescue/else/ensure are allowed inside do/end

    blocks •refinements take place in string interpolations

  57. None
  58. Java innovates more!

  59. JavaScript innovates way more!

  60. None
  61. Ruby.NEXT: Live Long and prosper by Bożydar Batsov

  62. Ruby 2.6

  63. •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
  64. arr[1..-1]

  65. arr[1..]

  66. arr.drop(1)

  67. There’s no easy way to express an infinite loop with

    index in Ruby
  68. 1.step …

  69. None
  70. Float("foo", exception: false)

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

  72. AST Module

  73. pry(main)> Ripper.sexp('alias :some :test') => [:program, [[:alias, [:symbol_literal, [:symbol, [:@ident,

    "some", [1, 7]]]], [:symbol_literal, [:symbol, [:@ident, "test", [1, 13]]]]]]]
  74. 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
  75. What about Ruby 3.0?

  76. Little is known about it…

  77. Little concrete is known about it…

  78. –Matz “We’ll aim to release Ruby 3 for the Olympic

    Games in Tokyo in 2020.”
  79. Duck inference?

  80. Better support for concurrent & parallel programming

  81. Guilds

  82. GIL -> Global Interpreter Lock

  83. GIL -> Guild Interpreter Lock

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

  85. 3 times faster performance?

  86. (3 times faster performance than Ruby 2.0)

  87. Ruby 2.5 is 154% faster than Ruby 2.0

  88. Getting rid of some quirky features?

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

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

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

  92. There’s no real plan for Ruby 3

  93. Ruby 3 is not a real release!

  94. Ruby 3 is an idea!

  95. –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…”
  96. None
  97. None
  98. Good artists copy; great artists steal. — Pablo Picasso

  99. We looked for “inspiration” everywhere…

  100. PHP

  101. Visual Basic Script

  102. Java

  103. The Future of Java and the JDK Who’s in charge?

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

  105. Maintainer vs Programmer

  106. Long-term vs short-term

  107. Foresight vs short-sightedness

  108. Key take-aways

  109. You need a clear strategy

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

  111. Additive changes, instead of destructive ones

  112. It’s better to deprecate than to remove

  113. Small increments

  114. Guiding principles

  115. Ruby Next, the language

  116. Design principle #0

  117. Continuous thoughtful innovation

  118. Design principle #1

  119. Continue to optimize for happiness

  120. Add some useful new features

  121. Make deprecating things easy

  122. class Foo # <b>DEPRECATED:</b> Please use <tt>useful</tt> instead. def useless

    warn "[DEPRECATION] `useless` is deprecated. Please use `useful` instead." useful end def useful # ... end end
  123. class MyFile extend Gem::Deprecate def no_more close end deprecate :no_more,

    :close, 2015, 5 def close # new logic here end end
  124. Immutable data structures

  125. vector

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

  127. immutable hash

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

  129. immutable set

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

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

  132. arr1 - arr2

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

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

  135. .to_immutable

  136. .to_mutable

  137. .to_v

  138. Pattern Matching

  139. 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
  140. 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
  141. https://bugs.ruby-lang.org/ issues/14912

  142. None
  143. Design principle #2

  144. Simplicity

  145. Simplicity is the ultimate sophistication.

  146. Less is more

  147. Simplicity leads to happiness.

  148. Let’s deprecate some stuff

  149. deprecate != remove

  150. Let’s deprecate some useless stuff

  151. for loops

  152. for name in names puts name end

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

  154. autoload

  155. flip-flops

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

    end
  157. block comments

  158. =begin comment line another comment line =end

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

  160. class SomeClass =begin This is a top comment. Or is

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

    it? =end def some_method end end
  162. Character literals

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

  164. $SAFE

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

  166. None
  167. Refinements

  168. Let’s fix some stuff!

  169. and & or have the same precedence

  170. So many nils floating around

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

  172. Optional keyword param?

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

    => nil pry(main)> 1.nonzero? => 1
  174. x.non_zero?

  175. !x.zero?

  176. Mutable strings

  177. Even JavaScript got this right…

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

  179. ImmutableString

  180. Frozen strings?

  181. Reassignable constants

  182. Reassignable constants

  183. 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
  184. None
  185. Class variables

  186. 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"
  187. Poorly named methods

  188. Kernel#puts

  189. Kernel#println, anyone?

  190. Kernel#print

  191. defined?

  192. [1] pry(main)> defined? 10 => "expression" [2] pry(main)> defined? Test

    => nil [3] pry(main)> defined? TrueClass => "constant"
  193. None
  194. Enumerable#include?

  195. Enumerable#includes?

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

  197. None
  198. Perl-style special global variables

  199. $:

  200. $LOAD_PATH

  201. $;

  202. $FIELD_SEPARATOR

  203. $*

  204. $ARGV

  205. JRuby defines the English aliases by default

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

  207. Why can’t we do all (most) of this as soon

    as Ruby 2.6?
  208. WTF? Global variables?

  209. None
  210. Even Java doesn’t have globals…

  211. Felina

  212. One more thing…

  213. –Matz “Ruby is no longer my project. It’s the Ruby

    community’s project.”
  214. File tickets

  215. Send patches

  216. Blog about the issues

  217. Speak about the issues

  218. Let’s make Ruby better together!

  219. Ruby Ruby

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

    Poland 11.08.2018