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

Philip Potter on Equal Rights for Functional Ob...

Philip Potter on Equal Rights for Functional Objects by Henry G. Baker

Equal Rights for Functional Objects, or, The More Things Change, the More they Stay the Same

There are many ways of defining equality, particularly in a language which has both object-oriented and functional aspects. There's reference equality, numerical equality, shallow list equality, deep list equality, string equality, and even "fuzzy" floating-point equality. Which is the right to choose in any given situation? Which should i use for my equals() method on my custom object?

This paper answers all of these questions, by taking a seemingly complex problem and revealing an underlying simplicity. It does this by defining one equality operation that works in any situation.

The paper makes use of lisp syntax, but the ideas are applicable to most modern languages.

Papers_We_Love

May 14, 2014
Tweet

More Decks by Papers_We_Love

Other Decks in Technology

Transcript

  1. Table of Contents introduction problem: many types of equality oops

    oops ==, eql?, or equal? lists in java.util.List terms… object identity what do we really want from equality? ONE equality operator! equivalence relation not too fine, not too coarse solution: egal numbers immutable lists mutable lists
  2. introduction The Joy of Clojure, Michael Fogus and Chris Houser

    And if two objects aren't equal forever, then they're technically never equal (Baker 1993).
  3. problem: many types of equality Lisp EQ , EQL ,

    EQUAL , EQUALP , STRING= , CHAR= … Smalltalk = , == Java == , .equals() Perl == , eq Python == , is Ruby == , eql? , equal?
  4. oops # Python x = 1 y = 1 x

    is y True x = 500 y = 500 x is y False
  5. oops public class Foo { public static void main(String[] args)

    { if (Integer.valueOf(200) == Integer.valueOf(200)) { System.out.println("Hooray!"); } else { System.out.println("Oh noes!"); } } } Oh noes!
  6. ==, eql?, or equal? # ruby h1 = { "a"

    => 100, "b" => 200, :c => "c" } h1["a"] 100 h1 = { "a" => 100, "b" => 200, :c => "c" } h1.compare_by_identity h1["a"] nil
  7. lists if x = [1,2,3], and y = [1,2,3]: are

    they equal? are they the same? can we answer this without resorting to "it depends"?
  8. object identity sugababes = Set.new [:mutya, :keisha, :siobhan] sugababes.delete(:siobhan); sugababes.add(:heidi)

    # 2001 sugababes.delete(:mutya); sugababes.add(:amelle) # 2005 sugababes.delete(:keisha); sugababes.add(:jade) # 2009 new_band = Set.new [:mutya, :keisha, :siobhan] # 2011
  9. solution: egal Key idea is that of object identity: Objects

    which behave the same should be the same. Related to "identity of indiscernibles"
  10. immutable lists [1,2,3] = [1,2,3] [a,b,c] = [a,b,c] more generally,

    iterate over elements and recursively call egal
  11. mutable lists compare eq-cons on p3 of the paper def

    same?(x,y) saved_head = x[0] x[0] = "My super-sekrit value" x[0] == y[0] ensure x[0] = saved_head end x = ["a"]; y = ["a"] puts "x=x: #{same?(x,x)}" puts "x=y: #{same?(x,y)}" x=x: true x=y: false
  12. in summary: compare simple values by value compare mutable objects

    by reference compare immutable objects by recursively comparing their components (this is the one key idea of this paper)
  13. numeric conversions does Integer 1 = Long 1? does BigDecimal

    1.0 = Long 1? does BigDecimal 1.0 = BigDecimal 1.00?
  14. remember this rule? for arbitrary (= [1 2 3] '(1

    2 3)) ;; true (conj [1 2 3] 4) ;; [1 2 3 4] (conj '(1 2 3) 4) ;; (4 1 2 3)
  15. fin