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

A Nil Device, A Lonely Operator, and a Voyage t...

Eric Weinstein
September 09, 2016

A Nil Device, A Lonely Operator, and a Voyage to the Void Star

Slides for my RubyKaigi 2016 talk on... nothing!

Eric Weinstein

September 09, 2016
Tweet

More Decks by Eric Weinstein

Other Decks in Technology

Transcript

  1. A Nil Device, a Lonely Operator, & a Voyage to

    the Void Star # Eric Weinstein # Ruby Kaigi 2016 # Kyoto, Japan # 9 September 2016
  2. About Me eric_weinstein = { # エリック・ワインスタイン employer: 'Hulu', github:

    'ericqweinstein', twitter: 'ericqweinstein', website: 'ericweinste.in' } 30% off with KAIGI30!
  3. Agenda • A Nil Device: What is nil? What is

    it for? • A Lonely Operator: &. in Ruby 2.3 (and how other languages handle their versions of nil) • A Voyage to the Void Star: A history of nothingness • Summary and takeaways • Questions!
  4. Nil in C VALUE rb_cNilClass; // &c rb_cNilClass = rb_define_class("NilClass",

    rb_cObject); rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0); rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0); rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0); // More of these, we’ll see them again soon!
  5. Nil as a Value #if USE_FLONUM RUBY_Qnil = 0x08, /*

    ...0000 1000 */ #else RUBY_Qnil = 4 // Then, later on... #define Qnil ((VALUE)RUBY_Qnil)
  6. Nil in Ruby (cont'd) > NilClass.instance_methods(false).sort => [:&, :^, :inspect,

    :nil?, :rationalize, :to_a, : to_c, :to_f, :to_h, :to_i, :to_r, :to_s, :|]
  7. Nil as an API "The underlying problem is that Animal.find

    returns objects which conform to different APIs." — Sandi Metz http://www.sandimetz.com/blog/2014/12/19/ suspicions-of-nil
  8. Schrödinger’s Black Box • We could get something (a value)

    or nothing (nil) • We don't know what's in the box until we open it (!)
  9. Nil Means Something • No value • No meaningful value

    • Neutral value • Failure • Error
  10. Why is Nil Dangerous? • What do we mean by

    "safe" and why is nil unsafe? • Should we protect ourselves from nil, or stop nil in the first place? Do we need nil at all? • If we don't handle nil, it infects everything
  11. How We Handle Nil Now • Active Support's Object#try •

    Null object pattern • &. • Whack-a-mole (are you nil? Are you nil?)
  12. Null Object class Fox attr_reader :foods, :name def initialize(name, foods)

    @name = name @foods = foods end end fox = Fox.new('Fox small', ['Chunky bacon']) fox.name # => "Fox small" class NullFox attr_reader :foods, :name def initialize @name = 'No name' @foods = [] end end faux = NullFox.new faux.name # => "No name"
  13. &. foxes = { fox_small: { mood: 'Nonplussed' }, fox_tall:

    { mood: 'Fussy', food: 'Chunky bacon' } } foxes[:fox_tall][:food]&.upcase # "CHUNKY BACON" foxes[:fox_small][:food]&.upcase # nil
  14. Comparative Literature • How other languages think about... well, nothing!

    • Clojure: nil and nil punning • Haskell: the case for Nothing • Java: Optionals (new in Java 8)
  15. Nil in Clojure (def foxes {:fox-small "small" :fox-tall {:mood "Fussy"

    :food "Chunky bacon"}}) (get-in foxes [:fox-tall :food]) ;; "Chunky bacon" (get-in foxes [:fox-small :food]) ;; nil (get-in foxes [:fox-medium :food]) ;; nil
  16. Nothing in Haskell import Prelude hiding (lookup) import Data.Map foxFoods

    = fromList([("Fox small", "chunky bacon"), ("Fox tall", "a single quail egg")]) foodMoods = fromList([("chunky bacon", "satisfied"), ("a single quail egg", "still hungry")])
  17. Nothing in Haskell (cont'd) foxMood :: String -> Maybe String

    foxMood name = do food <- lookup name foxFoods lookup food foodMoods
  18. Nothing in Haskell (cont'd) main = do putStrLn $ "Fox

    small " ++ (show (foxMood "Fox small")) putStrLn $ "Fox tall " ++ (show (foxMood "Fox tall")) putStrLn $ "Fox medium " ++ (show (foxMood "Fox medium")) -- Fox small Just "satisfied" -- Fox tall Just "still hungry" -- Fox medium Nothing
  19. &. Now for Something a Little Trickier • Nothing: no

    cached result for the search. • Just Nothing: we’ve done the search, but not found a record for the person. • Just (Just Nothing): we’ve done the search, and the result was: the database doesn't know person’s age! (Age is NULL) • Just (Just (Just 42)): we’ve found who we’re looking for and they’re 42 years old. • More @ http://bit.ly/2c5YSXQ (Luke Plant) and http://bit.ly/ 1gXXCEp (James Coglan)
  20. Null in Java private static final HashMap<String, String> FOXES =

    new HashMap(); public static void main(String[] args) { FOXES.put("Fox tall", "Tallish"); FOXES.put("Fox small", "Smallish"); System.out.println(FOXES.get("Fox tall").toUpperCase()); System.out.println(FOXES.get("Fox small").toUpperCase()); System.out.println(FOXES.get("Fox medium").toUpperCase()); // NPE! }
  21. The Ocho™ public static String safeGet(String k) { return Optional.ofNullable(FOXES.get(k)).orElseGet(()

    -> "No Value"); } public static void main(String[] args) { System.out.println(safeGet("Fox tall").toUpperCase()); System.out.println(safeGet("Fox small").toUpperCase()); System.out.println(safeGet("Fox medium").toUpperCase()); }
  22. Brought to You by the Letter “C” Speaking of C:

    why do we have nil/NULL at all?
  23. “I call it my billion-dollar mistake.” “It was the invention

    of the null reference in 1965... My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement.” — C.A.R. Hoare, 2009
  24. A Little History • Invented by Tony Hoare in 1965

    for ALGOL W • ALGOL influenced C (-> MRI) & Java (-> JRuby) • Most, if not all, ALGOL-influenced languages have null pointers (e.g. C, C++, Java, JavaScript, Rust)
  25. A World Without Nil • Meaningless states wouldn't be representable!

    This is great... • ...but meaningless states show up all the time
  26. Summary • What is nil? What is it for? •

    Nil in Ruby (and ways to handle it) • Comparative literature • History of nil and NULL
  27. Takeaways (TL;DPA) • Nil is powerful, dangerous, and ubiquitous •

    We probably need nil, but we might not need null pointers! • Don't be a lonely operator! Ruby is a community—we're here to learn from each other • You can and should use the lonely operator (&.), but as with all tools, use it with care
  28. Questions? eric_weinstein = { # エリック・ワインスタイン employer: 'Hulu', github: 'ericqweinstein',

    twitter: 'ericqweinstein', website: 'ericweinste.in' } 30% off with KAIGI30!