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

Design of everyday functions

Hadley Wickham
September 18, 2018

Design of everyday functions

Hadley Wickham

September 18, 2018
Tweet

More Decks by Hadley Wickham

Other Decks in Technology

Transcript

  1. The DESIGN 

    of EVERYDAY 

    FUNCTIONS
    Hadley Wickham

    @hadleywickham

    RStudio
    September 2018

    View full-size slide

  2. Practitioner Programmer

    View full-size slide

  3. Interactive
    Easily detect & resolve problems
    Packaged
    In production
    You hear your code Things break and
    people at you
    Practitioner Programmer

    View full-size slide

  4. Notebook IDE
    https://yihui.name/en/2018/09/notebook-war/
    The First Notebook War
    Data analyst Engineer

    View full-size slide

  5. Me
    You
    Practitioner Programmer

    View full-size slide

  6. Code is a conversation
    Ambiguity can be tolerated
    early and often
    Practitioner Programmer
    Implicit Explicit

    View full-size slide

  7. Practitioner Programmer
    Implicit Explicit

    View full-size slide

  8. What makes a
    good door?
    https://99percentinvisible.org/article/norman-doors

    View full-size slide

  9. “When you have trouble with things—whether
    it’s figuring out whether to push or pull a door or
    the arbitrary vagaries of the modern computer
    and electronics industries—it’s not your fault.
    Don't blame yourself: blame the designer...”
    — Donald A. Norman

    View full-size slide

  10. https://twitter.com/irismwang/status/994349937944158208

    View full-size slide

  11. https://twitter.com/BrockTibert/status/1009543843690278920

    View full-size slide

  12. https://twitter.com/mattfrost/status/768078660200898560

    View full-size slide

  13. https://twitter.com/gshotwell/status/675344503566417921

    View full-size slide

  14. https://twitter.com/PetrelStation/status/1038043993387552768

    View full-size slide

  15. https://twitter.com/NateApathy/status/1030263775205707776

    View full-size slide

  16. https://twitter.com/scottmccain5/status/986275394692272129

    View full-size slide

  17. “Rule of thumb: if you think
    something is clever and
    sophisticated, beware — it is
    probably self-indulgence.”
    — Donald A. Norman

    View full-size slide

  18. WAT makes a bad
    function?
    https://www.destroyallsoftware.com/talks/wat

    View full-size slide

  19. c(factor("a"), factor("b"))
    What happens when you combine two factors?

    View full-size slide

  20. c(factor("a"), factor("b"))
    #> [1] 1 1
    What happens when you combine two factors?
    WAT!

    View full-size slide

  21. today <- as.Date("2018-09-18")
    lunch <- as.POSIXct("2018-09-18 12:00",
    tz = "Europe/Belgrade")
    c(today, lunch)
    What happens when you combine a date and a date-time?

    View full-size slide

  22. today <- as.Date("2018-09-18")
    lunch <- as.POSIXct("2018-09-18 12:00",
    tz = "Europe/Belgrade")
    c(today, lunch)
    #> [1] "2018-09-18"
    #> [2] "4210927-01-24"
    What happens when you combine a date and a date time?
    WAT!

    View full-size slide

  23. today <- as.Date("2018-09-18")
    lunch <- as.POSIXct("2018-09-18 12:00",
    tz = "Europe/Belgrade")
    c(lunch, today)
    What happens when you combine a date and a date-time?

    View full-size slide

  24. today <- as.Date("2018-09-18")
    lunch <- as.POSIXct("2018-09-18 12:00",
    tz = "Europe/Belgrade")
    c(lunch, today)
    #> [1] "2018-09-18 12:00:00 CDT"
    #> [2] "1969-12-31 22:56:32 CST"
    What happens if you touch a date-time the wrong way?
    WAT!

    View full-size slide

  25. lunch <- as.POSIXct("2018-09-18 12:00",
    tz = "Europe/Belgrade")
    lunch
    #> [1] "2018-09-18 12:00:00 CEST"
    c(lunch)
    c(NULL, lunch)
    What happens if you look at a date-time the wrong way?

    View full-size slide

  26. lunch <- as.POSIXct("2018-09-18 12:00",
    tz = "Europe/Belgrade")
    lunch
    #> [1] "2018-09-18 12:00:00 CEST"
    c(lunch)
    #> [1] "2018-09-18 05:00:00 CDT"
    c(NULL, lunch)
    #> [1] 1537264800
    What happens if you look at a date-time the wrong way?
    WAT!
    WAT!!

    View full-size slide

  27. What makes a good
    function?
    one aspect of
    ^

    View full-size slide

  28. c(, ) ->
    c(>) ->
    c(NULL, >) ->
    Types can give us a high-level overview of a function
    I’ll put types in angle brackets to make
    clear that this is not real R code

    View full-size slide

  29. To do that we need to review some foundations
    Atomic
    Numeric
    Logical Integer Double Character

    View full-size slide

  30. c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    c(, ) ->
    For atomic vectors, the rules are simple

    View full-size slide

  31. For atomic vectors, the rules are simple
    Logical Integer Double Character
    Logical logical integer double character
    Integer integer integer double character
    Double double double double character
    Character character character character character

    View full-size slide

  32. For atomic vectors, the rules are simple
    Logical
    Integer
    Double
    Character
    Even if you’re never explicitly
    learned this, I think you
    internalise it quickly.

    View full-size slide

  33. Unfortunately c() breaks down when we get to S3 vectors
    Atomic
    Numeric
    Logical Integer Double Character
    factor POSIXct Date
    S3 vectors

    View full-size slide

  34. Figuring out the rules is the goal of the vctrs package
    http://vctrs.r-lib.org

    View full-size slide

  35. mutate() ->
    filter() ->
    select() ->
    arrange() ->
    summarise() ->
    group_by() ->
    The types of the primary dplyr functions are simple

    View full-size slide

  36. if_else(, , ) ->
    if_else(, , ) ->
    if_else(, , ) -> ???
    if_else(, , ) -> ???
    if_else(, , ) -> ???
    if_else(, , ) -> ???
    But there are a few that are more complex

    View full-size slide

  37. x <- runif(6)
    if_else(x > 0.5, x, NA)
    #> Error: `false` must be type double,
    #> not logical
    Which leads to this annoyance

    View full-size slide

  38. x <- runif(6)
    if_else(x > 0.5, x, NA)
    #> Error: `false` must be type double,
    #> not logical
    if_else(x > 5, x, NA_real_)
    #> [1] NA 0.700 0.557 NA NA NA
    Which leads to this annoyance
    You’re currently forced to learn
    about the “typed” NAs

    View full-size slide

  39. if_else(, , ) ->
    vec_c(, ) ->

    if_else(, , ) ->
    vec_c(, ) ->

    I think I'm starting to see the principles

    View full-size slide

  40. Practitioner Programmer
    Implicit Explicit
    Interactive
    Easily detect & resolve problems
    Packaged
    In production
    Code is a conversation
    Ambiguity can be tolerated early and often

    View full-size slide

  41. https://adv-r.hadley.nz/vectors-chap.html
    http://vctrs.r-lib.org
    https://www.destroyallsoftware.com/talks/wat
    https://99percentinvisible.org/article/norman-doors
    WAT!
    http://bit.ly/everyday-functions

    View full-size slide