Download - Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Transcript
Page 1: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Emerging

Best Practicesin Swift

Ash Furrow

Page 2: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward
Page 3: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

AfraidI was

Page 4: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

FineEver

ythi

ng tu

rned

out

Page 5: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Best Practices in Swift

Page 6: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

What do they look like?

Also, how do we find new ones?

Page 7: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Agenda

• We’ve been here before

• Learning is forever, deal with it

• Never throw ideas away

• How to force yourself to think

• Always be abstracting

Page 8: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Let’s go!

Page 9: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

This looks strangely familiar…

Page 10: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

—Lots of people, for hundreds of years

“Those who don’t study history are doomed to repeat it.”

Page 11: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Wow, that’s depressing.

Page 12: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

—Me, today

“Those who don’t understand the past can’t make informed decisions about the present.”

Page 13: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

iOS 5 or earlier?

Page 14: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Before Object Literals

NSArray *array = [NSArray arrayWithObjects: @"This", @"is", @"so", @"tedious", nil];

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"Who would do this?", @"Not me", nil];

NSNumber *number = [NSNumber numberWithInt:401];

Page 15: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Before Object Literals and ARC

NSArray *array = [[NSArray arrayWithObjects: @"This", @"is", @"so", @"tedious", nil] alloc];

NSDictionary *dictionary = [[NSDictionary dictionaryWithObjectsAndKeys: @"Who would do this?", @"Not me", nil] alloc];

NSNumber *number = [[NSNumber numberWithInt:401] alloc];

Page 16: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

😪

Page 17: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

After Object Literals

NSArray *array = @[ @"This", @"is", @"much", @"better" ];

NSDictionary *dictionary = @{ @"Who likes this?": @"Me!" };

NSNumber *number = @(401);

Page 18: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Object Literals

• Clearly way better

• Adopted by everyone almost immediately

• Became a “best practice”

Page 19: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

^{

Page 20: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Blocks & GCD

• Introduced in iOS 4

• Adopted slowly, but surely

• Required new ways of thinking

• Did using blocks became a “best practice”?

• Sort of…

Page 21: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

EnableBlocks

other best practices

Page 22: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

^{Functional Reactive Programming

Futures

PromisesCollections Operations

Callbacks

Inline Network Operations

Generic Datasource Objects

Deferred Customization

Contextual Code Execution

Page 23: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

EmbraceChange

Page 24: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Swift 2

Page 25: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Swift 2

• Lots of new syntax

• New syntax lets us do new things

• However! Syntax is only a tool

• Like blocks, Swift 2 syntax is most useful when it enables new ideas

Page 26: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Swift 2

• guard

• defer

• throws

• etc…

Page 27: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Should I use guard?

Page 28: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

What can I do with guard?

Page 29: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Examples

Page 30: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Pyramid of Doom

if let thing = optionalThing { if thing.shouldDoThing { if let otherThing = thing.otherThing { doStuffWithThing(otherThing) } } }

Page 31: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Clause Applause

if let thing = optionalThing, let otherThing = thing.otherThing where thing.shoudDoThing { doStuffWithThing(otherThing) }

Page 32: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Avoid Mutabilityfunc strings( parameter: [String], startingWith prefix: String) -> [String] {

var mutableArray = [String]() for string in parameter { if string.hasPrefix(prefix) { mutableArray.append(string) } }

return mutableArray } ಠ_ಠ

Page 33: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Avoid Mutability

func strings( parameter: [String], startingWith prefix: String) -> [String] {

return parameter.filter { $0.hasPrefix(prefix) } }

Page 34: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Currying

• One of those weird words you avoid because people who say it are sometimes jerks

• It’s actually a pretty straightforward concept

• Currying is a function that returns another function

• Useful for sharing code that’s mostly the same

Page 35: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Before Currying

func containsAtSign(string: String) -> Bool { return string.characters.contains("@") }

...

input.filter(containsAtSign)

Page 36: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Currying

func contains(substring: String) -> (String -> Bool) { return { string -> Bool in return string.characters.contains(substring) } }

...

input.filter(contains("@"))

Page 37: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Currying

func contains(substring: String)(string: String) -> Bool { return string.characters.contains(substring) }

...

input.filter(contains("@"))

Page 38: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Extract Associated Values

• Use Swift enums

• Attach associated values

• Extract using a case

Page 39: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Extract Associated Values

enum Result { case Success case Failure(reason: String) }

switch doThing() { case .Success: print("🎉") case .Failure(let reason): print("Oops: \(reason)") }

Page 40: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Extract Associated Values

enum Result { case Success case Failure(reason: String) }

if case .Failure(let reason) = doThing() { print("😢 \(reason)") }

Page 41: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

SyntaxThat’s all just

Page 42: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

IdeasWhat matters are

Page 43: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Protocol-Oriented Programming

Page 44: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

… just go watch the WWDC video.

Page 45: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

OthersLet’s ask

Page 46: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Syntax vs Idea

• How to tell if something is universally a good idea, or just enables other ideas?

• You can’t

• It’s a false dichotomy

• I lied to you

• I’m so sorry

Page 47: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Try stuffYou’ve just got to

Page 48: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

IdeasNever throw away

Page 49: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Never Throw Away Ideas

• Swift was released

• We treated Swift like object literals instead of like blocks

• Some of us thought Swift was universally better

• My fault, oops 😅

Page 50: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

MeritOlder ideas have

Page 51: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

A lot

iOS developers throw things away

Page 52: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Why?

Page 53: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Beginner learns thing

Is bad at thing

Blames thing

Thing must be bad

Page 54: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Beginner gets more experience

New thing comes out

Learning new thing is easier than old thing

New thing must be good

Page 55: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

AppealingNew ideas are

Page 56: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Always a fresh supply of old APIs for us to blame

iOS is constantly changing

Page 57: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

RefactoringLet’s talk about

Page 58: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward
Page 59: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

What is Not Refactor?

• Refactoring does not add new functionality

• Refactoring does not change a type’s interface

• Refactoring does not change a type’s behaviour

Page 60: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Changing a unit test?

Refactoring Rewriting

No Yes

Page 61: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

BadRewrites are

Page 62: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward
Page 63: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Favour incremental change

Page 64: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Code isn’t necessarily valuable

But throwing it away is dangerous

Page 65: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Things to never throw away:

CodeIdeas&

Page 66: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

ChangeUnit tests will help

Page 67: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Unit Testing & Thinking

• So, uhh, unit testing

• Controversial in iOS

• Not so much everywhere else

• Why?

• We’ll get to that

Page 68: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Benefits of Testing

• (Let’s presume that unit testing is a good idea)

• I really don’t care that much about the tests

• I care more about how writing tests makes me think about what I’m writing

Page 69: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Benefits of Testing

• Limited object scope is good

• High cohesion, low coupling

• How to limit scope?

• Controlling public interface and dependencies

Page 70: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Dependency injection?

💉

Page 71: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Dependency Injection

• €5 word for a ¢5 idea

• Your things shouldn’t create the things they need

Page 72: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Example

Page 73: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Without Dependency Injection

class ViewController: UIViewController { let networkController = NetworkController()

func viewDidLoad() { super.viewDidLoad() networkController.fetchStuff { self.showStuff() } } }

Page 74: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

With Dependency Injection

class ViewController: UIViewController { var networkController: NetworkController?

func viewDidLoad() { super.viewDidLoad() networkController?.fetchStuff { self.showStuff() } } }

Page 75: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Dependency Injection

• Rely on someone else to configure your instance

• Could be another part of your app (eg: prepareForSegue)

• Could be a unit test

• Protocols work really well for this

Page 76: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Dependency Injection

protocol NetworkController { func fetchStuff(completion: () -> ()) }

...

class APINetworkController: NetworkController { func fetchStuff(completion: () -> ()) { // TODO: fetch stuff and call completion() } }

Page 77: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Dependency Injectionprotocol NetworkController { func fetchStuff(completion: () -> ()) }

...

class TestNetworkController: NetworkController { func fetchStuff(completion: () -> ()) { // TODO: stub fetched stuff completion() } }

Page 78: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Dependency Injection

• Use of protocols limits coupling between types

• Adding a method to a protocol becomes a decision you have to make

• Dependency injection can als be used for shared state, like singletons

Page 79: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Without Dependency Injection

func loadAppSetup() { let defaults = NSUserDefaults.standardUserDefaults()

if defaults.boolForKey("launchBefore") == false { runFirstLaunch() } }

Page 80: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

How would you even test that?

Page 81: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

With Dependency Injection

func loadAppSetup(defaults: NSUserDefaults) { if defaults.boolForKey("launchBefore") == false { runFirstLaunch() } }

Page 82: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Don’t be an ideologue

Page 83: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Cheat with Dependency Injection

func loadAppSetup( defaults: NSUserDefaults = .standardUserDefaults()){

if defaults.boolForKey("launchBefore") == false { runFirstLaunch() } }

Page 84: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Cheat with Dependency Injection

loadAppSetup() // In your app

loadAppSetup(stubbedUserDefaults) // In your tests

Page 85: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Cheat with Dependency Injection

class ViewController: UIViewController { lazy var networkController: NetworkController = APINetworkController()

func viewDidLoad() { super.viewDidLoad() networkController.fetchStuff { self.showStuff() } } }

Page 86: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

—Mackenzie King (Canada’s Winston Churchill)

“TDD if necessary, but not necessarily TDD.”

Page 87: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Unit Testing• Don’t test private functions

• Also, start marking functions as private

• Remember, we want to avoid rewriting

• Don’t test the implementation

• Don’t use “partial mocks”

• See @searls post on partial mocks

Page 88: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Unit Testing

• So why don’t iOS developers do unit testing?

• It’s unfamiliar and no one forces us to do it

Page 89: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

BetterTesting code makes me a

Developer

Page 90: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

EverythingAbstract

Page 91: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Two or more lines of repeated code?

Find a better way

Page 92: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

(╯°□°)╯︵ ┻━┻

Page 93: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Look for Abstractions

• You’re already learning new syntax

• Look for new abstractions along the way

• Not all ideas will work out

• But you should still do it

• Experiment!

Page 94: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

No such thing

Failed experimentas a

Page 95: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward
Page 96: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

LearnAlways opportunities to

Page 97: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

Wrap Up

• We have a history of being awesome, let’s keep it up

• Learning isn’t just for when Xcode is in beta

• Ideas are more valuable than code, but throwing away either is dangerous

• Effective unit tests make it easy to change code

• Operate at the highest level of abstraction you can at any given time

Page 98: Emerging Best Practices - GOTO Conference€¦ · Currying • One of those weird words you avoid because people who say it are sometimes jerks • It’s actually a pretty straightforward

MakeTomorrowBetter Mistakes