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

Why Static Typing Matters

Why Static Typing Matters

(or How to Solve All Your Runtime Errors With This One Neat Trick)

Eli Perkins

October 13, 2017
Tweet

More Decks by Eli Perkins

Other Decks in Programming

Transcript

  1. Why Static Typing Matters (or How to Solve All Your

    Runtime Errors With This One Neat Trick)
  2. Why Static Typing Matters (or How to Solve All Your

    Runtime Errors With This One Neat Trick)
  3. function sum(x: number, y: number) { return x + y;

    } const foo = sum(2, 3); number
  4. function sum(x: number, y: number) { return x + y;

    } function multiply(x: number, y: number) { return x * y; } function square(x: number) { return x * x; } const x = square(multiply(sum(2, 3), 2)); number
  5. function greet(greeting: string) { console.log(greeting + ', world!'); } const

    greeting: ?string = null; greet(greeting); Error: This type is incompatible
  6. type User = { name: string, username: string, email: ?string,

    }; function sendEmail(email: string) { … } const eli: User = { name: 'Eli', username: 'eliperkins', email: null, }; sendEmail(eli.email); Error: This type is incompatible
  7. type User = { name: string, username: string, email: ?string,

    }; function sendEmail(email: string) { … } const eli: User = { name: 'Eli', username: 'eliperkins', email: null, }; if (eli.email != null) { sendEmail(eli.email); } No errors!
  8. function sum(x: number, y: number) { return x + y;

    } function square(x: number) { return x * x; } const x = s sum (x: number, y: number): number square (x: number): number
  9. function sum(x: number, y: number) { return x + y;

    } const x = summm(2, 3); Error: identifier `summm` Could not resolve name
  10. type Props = { id: number, name: string, email: string,

    }; class UserComponent extends React.Component<Props> { ... } <UserComponent id={123} name={"Eli"} />; Error: property `email` not found in props of React element `UserComponent`
  11. [C]

  12. [C]

  13. [client fetchFriendsFeed:^(NSArray *events) { // lol wtf is `events` //

    Maybe VENEvent objects? // Maybe VENFeedEvent objects? // Maybe null? }];
  14. let user = User( name: "Eli", username: "eliperkins", email: nil

    ) setEmail(user.email) Error: value of optional type 'String?' not unwrapped; Did you mean to use '!' or '?'?
  15. Elm

  16. NoRedInk has 80k+ lines of Elm, and after more than

    a year in production, it still has not produced a single runtime exception. “
  17. -- TYPE MISMATCH ---------------------------- The argument to function `increment` is

    causing a mismatch. 5| increment "wat" ^^^^^ Function `increment` is expecting the argument to be: Int But it is: String
  18. type Primary = Red | Green | Blue mixedUpCaseBranches primary

    = case primary of Red -> "red" Green -> "green" Blue -> False
  19. type Primary = Red | Green | Blue mixedUpCaseBranches primary

    = case primary of Red -> "red" Green -> "green" Blue -> False
  20. The 2nd and 3rd branches of this `case` produce different

    types of values. 9| case primary of 10| Red -> 11| "red" 12| 13| Green -> 14| "green" 15| 16| Blue -> 17|> False The 2nd branch has this type: String But the 3rd is: Bool
  21. -- TYPE MISMATCH --------------------------------- The right side of (==) is

    causing a type mismatch. 3| ["Alice"] == [True] ^^^^^^ (==) is expecting the right side to be a: List String But the right side is: List Bool Hint: With operators like (==) I always check the left side first. If it seems fine, I assume it is correct and check the right side. So the problem may be in how the left and right arguments interact.
  22. Based on the version number listed in your elm-package.json file,

    it will run a diff and figure out the magnitude of the changes. It will then tell you your new version number! “
  23. Elm

  24. type schoolPerson = | Teacher | Director | Student string;

    let greeting stranger => switch stranger { | Teacher => "Hey professor!" | Director => "Hello director." | Student anyOtherName => "Hey, " ^ anyOtherName ^ "." };
  25. type schoolPerson = | Teacher | Director | Student string;

    let greeting stranger => switch stranger { | Teacher => "Hey professor!" | Director => "Hello director." | Student anyOtherName => "Hey, " ^ anyOtherName ^ "." }; greeting (Student “Eli”); /* “Hey, Eli.” */
  26. type schoolPerson = | Teacher | Director | Student string;

    let greeting stranger => switch stranger { | Teacher => "Hey professor!" | Director => "Hello director." | Student anyOtherName => "Hey, " ^ anyOtherName ^ "." }; greeting Teacher; /* “Hey professor!.” */
  27. type schoolPerson = | Teacher | Director | Student string;

    let greeting stranger => switch stranger { | Teacher => "Hey professor!" | Director => "Hello director.” | Student "Richard" => "Still here Ricky?" | Student anyOtherName => "Hey, " ^ anyOtherName ^ "." }; greeting (Student “Richard”); /* “Still here Ricky?” */
  28. type schoolPerson = | Teacher | Director | Student string;

    let greeting stranger => switch stranger { | Teacher => "Hey professor!" | Director => "Hello director.” }; Warning 6: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: Student
  29. type schoolPerson = | Teacher | Director | Student string;

    let greeting stranger => switch stranger { | Teacher => "Hey professor!" | Director => "Hello director.” }; Warning 6: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: Student
  30. Why Static Typing Matters (or How to Solve All Your

    Runtime Errors With This One Neat Trick)
  31. Flow: https://flow.org TypeScript: https://www.typescriptlang.org/ Swift: https://swift.org/ Elm: http://elm-lang.org/ Reason: https://reasonml.github.io

    Dan Grossman, Programming Languages course: https://www.coursera.org/learn/ programming-languages Brandon Williams - Proof in Functions: https:// vimeo.com/121953811