Exercises For Programmers: Exercise 3- Printing Quotes

The purpose of this exercise is to display a quote and prompt the user for the person who said the quote. If the quote is correct, you output the answer and the speaker.

I think the stated goals for this exercise assume that you are using a language like Haskell that does not have strong user interface component. I adapted the requirements somewhat for iOS.

The UI elements I need for this exercise are a label asking who said the quote, a text view to hold the quote, a text field to accept the answer, a button to submit the answer, and another text view to display the response.

What you start off seeing when you launch the app.

What you start off seeing when you launch the app.

I briefly thought about how to create a label that would allow for multiple lines of text, when I remembered the best object for that is a text field.

I tried to make the layout adapt to different lengths of quotes. I thought if I just pinned my elements under one another but did not specify the height of each element that it could expand and contract according to how long the quote was. This does not quite work. The text field is stuck at one size and height. If the text is longer than the text field, the element adopts a scroll view to expose the hidden text.

It might be possible to use programmable constraints to get the effect I would like. I am interested in figuring this out in the future, but I will leave that challenge for another time.

There are a few challenges associated with this exercise:

  • Display a quote
  • Check the user input to see if there is an answer
  • If there is an answer, is the answer correct?
  • Customize the output depending on what the user submitted

Like the previous exercises, there are three different possible outputs. Unlike the previous examples, the three are not all connected. If there is no answer, then you have one output. If there is an answer, then you have to process it further to see if it is the correct answer.

I wanted to hard code as little in this application as possible. It was indicated that later in the book we will revisit this application and refactor it to pull multiple quotes and authors from a data structure. I could set the quote and the answer in the view controller, but then if the requirements change and it’s possible that there are more than one quote, I will have to change things. I want this to be set up for that possibility and I want the entire application to be testable, which means moving anything that is not view controller code into a helper functions class.

Since I believe I will later need to have access to multiple quotes, the first function I created was one to return the quote:

func quoteText() -> String {
    return "You can lead a horticulture, but you cannot make her think."
}

Right now we only have one quote, but in the future the requirements may change where we may possibly have more and this can be refactored to determine what that is without having to change any code in the view controller.

Next I want to determine if the response is correct or not. Since the answer is going to be used in multiple places and won’t be passed in from the UI, I made the answer a global variable.

Incorrect response.

Incorrect response.

I need to pass in the response from the user and check it against this answer. It is either correct or incorrect, which means we are returning a Bool:

let answer = "Dorothy Parker"

func isTheAnswerCorrect(response:String) -> Bool {
    if response == answer {
        return true
    } else {
        return false
    }
}

Depending upon whether the response is correct or not, the output string will change. If the answer is correct, we output a congratulatory message. If not, then we let the user know they were incorrect:

func responseOutput(isResponseCorrect:Bool, response:String) -> String {
    if isResponseCorrect == true {
        return "Correct! (response) said (quoteText())"
    } else {
        return "Sorry, (response) did not say that. Try again."
    }
}

Again, I want to future proof this function by not hard coding anything that might change. I am using the response as an interpolated String in both output messages because it will be the same either way. There’s no reason to hard code the correct response, thus making it more difficult to go back and change later.

Correct response

Correct response

So far we’re assuming that the user has entered a response. If they did not enter a response, I would like to handle that contingency as well.

I need to not only check to see if there are no characters in the string, but also to have an output message for the user if it is empty. I want this string to be optional because it is probable that there will be a response and I want this to be a fail-safe:

func isResponseEmpty(response:String) -> String? {
    if response.characters.count == 0 {
        return "Please enter a response!"
    } else {
        return nil
    }
}

Empty Response

Empty Response

My Helper Functions file is now complete. Each piece is small and testable. Now I need to put these pieces together to complete my functionality in the view controller:

@IBAction func answerQuestion(sender: AnyObject) {
    let response = answerTextField.text
        
    if let noResponse = isResponseEmpty(response!) {
        responseTextView.text = noResponse
    } else {
        let checkResponse = isTheAnswerCorrect(response!)
        responseTextView.text = responseOutput(checkResponse, response: response!)
    }
}

I need to pull in the response from the user and store it in a variable.

Since the failsafe for no response is an optional, I need to wrap it in an if-let statement. This puzzled me for a while because I kept getting a compiler error when I did this initially because I had an optional that was not unwrapped. I knew I didn’t want to force unwrap the return value from isResponseEmpty() because most of the time it would be nil. At that point I realized I was using response rather than response! The value from the text field is always presented as an optional. In the first exercise I realized that when you don’t enter anything in the text field, it doesn’t return nil, it just returns an empty string, so I knew it was safe to force unwrap the response.

After I check to verify that there is not an empty string, I need to check to see if the answer is correct. I run the isTheAnswerCorrect() function and pass that value into the responseOutput() function. That function returns a string and that string is set to the response text view.

I ran the code and it appears to work properly. Just to make sure, I went ahead and wrote a unit test for each function in the Helper Functions file. Since each function is small and does a very specific unit of work, it doesn’t take too long to verify each possible output.

Conclusion

I suppose it’s possible that I have overengineered this application. Some of the functions are probably overkill for the requirements as they are now, but I wanted to make this flexible for if those requirements change.

I probably could have shoved all my programming logic into one function, but I really like having everything spelled out and having each function do one small thing. When I was taking classes with Eric Knapp, he said that if you are talking about a function’s job and your description includes “It does this AND…” then you need another function. Each function should do one thing. I like this philosophy and I have been trying to implement it in my own code.

A link to this project can be found here.

Weight is a Number

I am entering my second year of living alone as an independent adult human. I am trying to sort out taxes and get my house cleaned to the point where I can have a party.

One thing I have been passively struggling with is my weight.

The last few years have been very difficult. I have commented on this blog before about the unstable food situation I have had. I have also dealt with a lot of stress and not knowing how to cook my own food. I thought that when all of those issues went away the situation would take care of itself. I didn’t want to try doing a diet and exercise plan because, honestly, I was having trouble just keeping my head above water so it wasn’t a priority.

I don’t think I have lost any weight since I started living alone. I think I had an unhealthy bloated look that has gone away and I feel like I look healthier, but I recently started buying all of my clothes a size larger to be comfortable while I am working.

I was very skinny as a child. The other kids would not go on the seesaw with me because I was so light that I would just hang up in the air. I was consistently ten pounds lighter than everyone else in my class up until puberty hit. Then I developed an eating disorder and I was mad that I didn’t lose any weight. I was freezing all the time and used to pass out, but I didn’t lose weight, so I was demoralized.

I feel a little like a failure because I feel like I had a natural body type that was not very heavy and I am now technically overweight. I don’t feel like doing all the stuff I would need to do to lose the 20 pounds I feel like I should lose to go back to being normal.

I remember being skinny.

You know what? Being skinny really sucked.

I do not remember a time in my childhood where I could tolerate any amount of physical activity.

The worst day of the school year for me was when we would have to run the mile. I would start out thinking I would try to run just this one time. Within a hundred feet I would be gasping for air clutching my side because I felt like I was being stabbed. I got used to my time just being over fifteen minutes because trying to do any better than that was just too hard. I had one year where I didn’t feel well and it was over twenty minutes and they had me do it again.

I hated athletics and sports because I totally sucked at anything physical.

I have noticed since moving out of my parent’s house that my eating habits have changed. My dad makes inedible food. The food he makes is somewhat nutritionally vacuous. He does a lot of bread and rice. One reason he and my ex would get into fights was because my dad wanted his meals to be mainly bread and cereals and my ex wanted his meals to be mainly of meat. Supposedly there should have been common ground between them to eat a lot of vegetables, but shockingly for some reason neither of them actually did that.

He has struggled with his weight most of his adult life. He likes to gorge himself and feel full, which means he tries to make a lot of watery soups that take up a lot of volume, but don’t provide calories or nutrients.

I think back to being a kid and eating turkey sandwiches on whole wheat bread with nothing else on them, not because I was picky, but because we didn’t have anything else to put on them. We had a lot of rice and steamed brussels sprouts and skim milk and iceberg lettuce salads with non-fat dressing washed down with cold glasses of Crystal Light Strawberry Kiwi Lemonade.

My dad had an aversion to fat and he replaced it with carbohydrates. We didn’t do a lot of vegetables and we didn’t have a lot of protein. Most of our food was nutritionally vacant. I am pretty sure my brother, who still lives with my parents, is suffering from scurvy.

I will cop to the fact that when I was starving myself I was making my body weak. I was working against myself by not taking care of myself properly. But as I have been angry with myself for abusing myself, I keep thinking back to the times when I wasn’t abusing myself. I think about how when I was seven I had to ask my friend’s mom for a ride less than a block because I would be winded trying to walk that far.

I might have been skinny, but I sure as hell wasn’t healthy.

I know I should do more than I am doing now. When it’s warmer outside I go for hour long walks and I find them enjoyable. I started running on and off the last few years and I find more joy in it that I ever thought I would because I associated it with feeling like I was going to die and being made fun of for being weak.

Recently I helped my 64-year-old mother move a mattress to the basement. She has arthritis and couldn’t grip the mattress, so I helped my dad do it. She didn’t want me to because she thought if she couldn’t handle the mattress there was no way that I could. Do you know how pathetic it feels to have your retired mother be shocked that you can do normal tasks because it’s something she doesn’t think she can do??

My dad keeps making passive aggressive comments about my “unhealthy” food that has “flesh” in it. He keeps trying to pawn watery lentil and squash soup on me. When I turn him down he keeps telling me that I picked up some bad habits from my ex and comments how skinny I was when I ate his food.

Yeah, starving people tend to be skinny. But being skinny isn’t the best tool that we have to gauge health. If I have to be overweight to be able to actually go hiking and running and not constantly feeling like I am going to die, then cool. I would rather deal with the ten or twenty vanity pounds I would like to lose than go back to how I felt when I was skinny but thought I was fat.

Exercises For Programmers: Exercise Two – Counting Characters

This is the second exercise in Brian Hogan’s book Exercises for Programmers. My solution for this exercise is on GitHub.

Since this is still relatively early in the book, we are still dealing with some simple concepts. This exercise is about asking for a string, repeating it back to the user, and telling the user how many characters are in the string.

countCharactersSuccess

This was supposed to be the first exercise where you set up a user interface, but I jumped the gun on that by setting one up with the first exercise.

The only changes between the first exercise and the second were that there was going to be another label to output the number of characters and that I needed to count the characters in the string.

I was able to complete this far more quickly than the first exercise because most of the road blocks I encountered with the first exercise were solved for the second. I already knew how to set up my auto layout. I remembered how to get the text from the UITextField. I already had most of my set up for the processing I needed to do for the labels.

Failure condition. Need to set both labels, including making sure the second label is an empty string.

Failure condition. Need to set both labels, including making sure the second label is an empty string.

I started out thinking that because I had two labels I needed to create two separate functions. I initially made a variable out of the text field input and passed that into my two functions. Then I thought more critically about it.

I was passing the same information into both functions and doing the same “if-else if-else” statement:

func yourInputString(input:String) -> String {
    
    if input.characters.count == 0 {
        return "You need to enter a string!"
    } else if Int(input) != nil {
        return "Please enter letters and not numbers!"
    } else {
        return "Your input string: (input)"
    }
    
}

func numberOfCharactersInString(input:String) -> String {
    
    if input.characters.count == 0 {
        return ""
    } else if Int(input) != nil {
        return ""
    } else {
        return "(input.uppercaseString) has (input.characters.count) characters."
    }
    
}

That is a lot of repeated code. There is probably a better way to consolidate this.

One of the things Brad and I talked about with Swift having an advantage over Objective-C is that it can return more than one thing. One reason that the NSError stuff is so screwy is because you can’t return more than one thing. You have to pass a pointer to the location in memory for the error because you can’t simply return the error.

I realized that I could cut down on a lot of code by simply returning a tuple that contained both label strings. This cut down on code in both my helper functions and in my main View Controller because I only had to call one function and then assign the result from that function to the labels in the UI.

func inputStringAndCharacterCount(input:String) -> (String, String) {
    
    let yourInputString:String
    let numberOfCharactersString:String
    
    if input.characters.count == 0 {
        yourInputString = "You need to enter a string!"
        numberOfCharactersString = ""
    } else if Int(input) != nil {
        yourInputString = "Please enter letters and not numbers!"
        numberOfCharactersString = ""
    } else {
        yourInputString = "Your input string: (input)"
        numberOfCharactersString = "(input.uppercaseString) has (input.characters.count) characters."
    }
    
    return (yourInputString, numberOfCharactersString)
}

I am finding this iterative approach of starting with something simple then adding complexity is a really good way to approach programming. You take lessons you learned doing something simple and you apply them as you do more and more complicated things.

Writing unit tests also forces you to think in ways to make it as easy as possible for yourself to be able to separate out as much functionality as possible in a way for it to be testable.

When Brad was telling me initially about using tuples I didn’t get how he came up with the solution. It was obvious once I saw it, but I didn’t get how he came up with it. I get it now. When I was writing my code and saw that I was repeating myself a lot, it forced me to think more critically about how I could make my code better.

I am happy I am doing these exercises because I don’t feel I get to code as much as I should. I am now seeing that coding things for myself helps me to learn things better than just being told what to do by someone who learned the way I am learning now.

We can read all the books we want to on clean code and so forth, but you really learn by doing and making mistakes and going back to refactor. I think a lot of people never go back and refactor and that is unfortunate for them. They are missing out on a great learning opportunity.

Exercises For Programmers: Exercise One-Saying Hello

A couple of months ago I bought Exercises for Programmers by my friend Brian Hogan. I was trying to find some mini challenges for myself like I had when I was a student when I would just work on a small, solvable problem.

When I think about programing, I usually get really overwhelmed by thinking about all of the components I need to make a minimum viable product. I start thinking about having to learn everything I have to do in order to put together a whole application. I wind up not doing anything because I feel like I have to learn twenty things before I can start coding rather than just diving in.

I have worked on other people’s projects and been given some rather explicit functionality that I have to have that is divorced from thinking about how to construct an actual program.

When I initially looked through this, I was disappointed because I felt like this was more targeted at people learning programming. There were tip calculators and Hello, World. So I got all sulky and emo teenager and decided this was not for me.

I was wrong.

I am planning to go through each exercise in this book and treat each exercise as a complete project. I am going to write unit tests for all of my code, make sure that the auto layout works, and try to think about what constraints I need rather than just trying to get something that works under specific circumstances.

User Interface and Autolayout

The first exercise in the book is a play on the usual “Hello world!” application. In this, you take user input and you output it to the screen.

To get user input from a user in iOS, you need to set up a bunch of UI elements: a label asking for your name, a text field for your name, a button to enter your name, and another label to display the message.

goodAutoLayout

This is a slightly embarrassing thing for me to admit, but I do not work much with user interface stuff. For the last two years I have worked exclusively on things like unit tests and network programming. The last time I worked a lot with user interfaces was around the time Storyboards were introduced. I have not mastered the Zen of Auto Layout.

Initially, I thought I had all of my elements laid out properly, but they didn’t show up where I wanted them to. I realized I had to go in and figure out a bunch of constraints to see what I wanted to on my screen.

autoLayoutFail

The top and bottom labels were easier because I knew I wanted them to be centered. The button and the text field were harder because I wanted them next to one another and I couldn’t center them the same way I did the labels.

autoLayoutFail2

I thought about giving up and just putting them on their own lines, but that kind of defeats the purpose of doing these exercises. I vaguely remembered that I can line things up by the leading or trailing edge. I liked the text field up with the leading edge of the top label and the button to the trailing edge of the top label. The text field rendered out to be about two characters wide, so I added one more constraint to maintain the spacing between the text field and the button.

HelloDelia

Programming Logic

Now that I have the layout working properly, I needed to think about what my failure cases are. Back when I was a student, I would just pull out whatever was entered in the text field and print it out on the screen. Since I want to write unit tests for this, I needed to put more thought into what would be a “bad” input.

The two that I could think about were either not entering anything at all, or entering in a number.

Since the text field is an optional, I needed to wrap it in an if-let. I thought about using a guard statement, but I didn’t feel like it would work in this case because I didn’t just want the result to be nil if you didn’t enter anything. I wanted to actually do something if it was nil, so I stuck with the if-let.

I thought that if there was nothing in the text field when you clicked on the button that it would be nil, so I had an else statement to state that if you just clicked on the button. That did not work because the text field returns an empty string. So that became a case I needed to check.

The last one was trying to figure out how check if the string contains a number. The ability to check a string for a number has changed a bit over the last two years in Swift. There used to be a toInt() function on the String class, but that was replaced with an initializer on the Int class. You pass a string into the Int initializer and if it can be converted to an int then you will have a value, otherwise, you get a nil.

Testing and Decoupling

I did my own testing on my application and I was able to trigger all three possible string outputs. But I want to get in the habit of writing unit tests for all of my personal applications. When I worked for Brad Larson, the main component of my job was to write unit tests for our code.

One way we were able to do that is because we made things very functional. We had very few classes. We had a lot of stand alone functions that could be tested thoroughly on their own. We created fake hardware objects in code.

That was harder to do with the view controller. I could make a function within the view controller to process the input from the text field, but I couldn’t do things as functionally as I wanted to.

Then I realized I could break my function up. Initially, I had this:

@IBAction func enterName(sender: AnyObject) {
    if let name = nameField.text {

        let myInt: Int? = Int(name)

        if name.characters.count == 0 {
            helloLabel.text = "You need to enter your name"
        } else if myInt != nil {
            helloLabel.text = "You entered numbers, not a name"
        } else {
            helloLabel.text = "Hello (name), how are you?"
        }
    }
}

This coupled the code in such a way that it was impossible to pull that code out and make it testable. Everything in this function was talking to parts of the class, so I couldn’t pull it out and make it stand alone.

So I rethought was I was trying to do. This function needed to do one thing: Set the helloLabel. I was making it do two things. I was also making it determine what the helloLabel was set to.

I realized I could make the output from the text field into a parameter that could be passed into a stand alone function.

I changed that function from what I had to this:

@IBAction func enterName(sender: AnyObject) {
        if let name = nameField.text {
            let nameString:String = nameFunction(name)
            helloLabel.text = nameString
        }
}

func nameFunction(name:String) -> String {
    
    let myInt: Int? = Int(name)
    
    if name.characters.count == 0 {
        return "You need to enter your name"
    } else if myInt != nil {
        return "You entered numbers, not a name"
    } else {
        return "Hello (name), how are you?"
    }
    
}

I pulled the nameFunction out of the View Controller and I put it in a Helper Function file. This function is the only part of this program that I need to unit test and I pulled it out from everything else. This makes testing my programming logic a snap.

    func testLabelOutput() {
        let emptyString = ""
        let numberString = "42"
        let normalString = "Delia"
        
        let firstTest = nameFunction(emptyString)
        let secondTest = nameFunction(numberString)
        let thirdTest = nameFunction(normalString)
        
        XCTAssertEqual(firstTest, "You need to enter your name")
        XCTAssertEqual(secondTest, "You entered numbers, not a name")
        XCTAssertEqual(thirdTest, "Hello (normalString), how are you?")
    }

Conclusions

I am a little embarrassed that this took me longer than I thought it would. I have my name on a few programming books and I “know” this stuff. The Apple ecosystem is an incredibly vast and complex system of knowledge. If you don’t work with something for a while, it takes a while to remember how to do things and shake the cobwebs off.

There are a lot of considerations I put into this exercise that I would not have bothered with when I was a student. I would have been like, why bother making this testable? It works. No one is going to be stupid enough to post numbers and if they do, who cares?

That isn’t a good way to think.

It doesn’t matter what kind of application you are doing. You should try to make everything you code the best that it can be.

This was a good exercise for me to think about this differently than I would have, especially knowing I was going to write unit tests. I rewrote that function a few times and almost thought I couldn’t decouple it until I thought about it for like an hour.

I could have had this working in ten minutes, but the UI would have been screwed up and it would not have been safe.

I am still not happy with the final version of my code, but I feel better about it than I did before. I hope that someone will code review this and tell me how I could have done it better.

All in all, this was a really interesting thought experiment. There are lots of dark corner in my brain of things that I don’t know I don’t know. Shining some light into those corners and airing them out is a good thing to do every once and a while.

I am making a GitHub repository for my exercise if people have any interest in looking them over and comparing notes.

Catch you next time!

Also, if anyone can give me some suggestions about how to get code to format reliably in WordPress I would appreciate it. Sometimes it works and sometimes all of my formatting is gone.

Are you a Developer or an Engineer?

Last month my boss, Daniel Pasco, posted this thought on Twitter:

developerEngineer

Developers focus on making great code.
Engineers focus on making great things.

This really struck a chord with me. I have observed a few behaviors that I didn’t really have any context to express and I feel like this quote sums up a lot of things that trouble me about the programming community.

Hipster Coding

“Nobody goes there anymore. It’s too crowded.”
– Yogi Berra

I went back to school in earnest to learn programming in 2012. I wasn’t sure what I wanted to do, but I knew I wanted to find whatever would work best for me in the long run. I initially went for Java because I knew there was a lot of demand for it, but I didn’t realize there was also a lot of supply and it was difficult to find an entry level Java job because most of them demanded 3-5 years of experience. I couldn’t break through the layers of bureaucracy and I just stopped trying.

I initially got involved with the Ruby community. I knew a lot of people who were active there and it seemed like it was the new up and coming thing.

I would talk to people about how to get into Ruby and I would be asked what open source projects I worked on. I didn’t really understand open source and would ask for help about how to get into open source. Their looks would immediately change to a combination of disdain and pity and they would stop talking to me because I wasn’t a contributor.

I struggled with this a bit trying to break into Ruby, only to discover that all the people who had been doing Ruby had moved on to Clojure. Then they moved on to Haskell. I think they were interested in Swift for a bit, but I have lost track of whatever the new hot language is. Might be Go…

I think a lot of people feel like they missed out on the Gold Rush of the iPhone. I know that I do. By the time I started taking iOS programming classes in 2012, the whole point of having an app out on the store was to use it as a resume builder to find an actual job. We were being prepared for the world as it exists now/over the next few years where there is less contracting and more enterprise development.

I feel a sense of chasing after something that doesn’t exist anymore. We still have the dream of writing a killer app and making mad bank, but that is growing more and more difficult. I feel like any time Apple releases a new piece of hardware, like the Apple Watch or the Apple TV, people feel like they need to immediately mark their territory on it because they think that if they get there first, they can strike gold and move on before everyone else gets there.

This has created a situation where we have platforms that seem to be abandoned by developers because there is something newer and shinier that has come out and everyone wants to be the first one there.

I Have a Screwdriver and Everything is a Screw

My introduction to programming was back in 2008. I was kind of loafing around unemployed because I had no idea what I was doing with my life. My dad would take me to work and I would go and hang out with the weird IT guy. My nickname for this guy was Jesus because he looked like Jesus if Jesus wore a shirt and tie.

He was really into programming and told me that learning programming was a valuable skill. He set me up with a book and a laptop in the corner. He showed me where the Terminal was and taught me how to write code in TextEdit and compile it on the command line.

All of this was done in Perl.

The book he gave me was the Llama O’Reilly book from I think 1998. He told me that the language was stable and didn’t change, so it was okay that the book was old.

I started telling people that I was learning Perl and I got horrified looks from people telling me no one uses it anymore. I was told to learn PHP because that was the future.

I talked to Jesus about that, and he told me not to bother learning PHP because everything that I want to do I can do in Perl. Perl does everything.

Replace “Perl” with “JavaScript” and that is exactly what we have now for a fairly large portion of the programming community.

I am not going to get into an argument about whether JavaScript is “real” code or not. That isn’t the point I am trying to make. JavaScript is a tool. It has its uses. If I want to write a website, I can’t do that in Swift with the Cocoa frameworks.

What worries me is that I see a lot of people treating JavaScript the way my friend Jesus treated Perl. It’s the thing they know, so they want to make it work for every single possible thing that exists.

There was a great blog post I read recently saying that the state of web development is static right now. Large companies like Yahoo are basically rewriting their websites over and over again in whatever the new hot JavaScript framework is.

I think I read recently that someone created a framework on top of JQuery, which is it’s a framework on top of JavaScript. I think someone tried to create a JavaScript framework to do server back end work. It’s a web language! It was designed to do one thing and one thing well. It’s being convoluted into weird, abstract shapes because people don’t want to learn new things.

Fleeting Fame

fleetingFame

“ObjC culture carriers were people who’d been building products for years using it. Swift culture carriers see a chance for fleeting fame.”
– Graham Lee

When Swift first came out, there were a lot of prominent members of the programming community that were incredibly anti-Swift. They had invested 15 years in Objective-C and saw no reason to pick up this goofy new language and get knocked back the the beginning of the board with everyone else.

A lot of us scoffed at these people and told them to get with the program because Swift wasn’t going anywhere.

It’s nearly two years later, and we’re now seeing that a lot of these people have come to terms with the fact that this language isn’t going anywhere.

This doesn’t mean that they are sitting back and figuring out the language. On the contrary. Many of them are just as loud and opinionated about it as they ever were, but now they’re actually trying to use it.

I have noticed a shift in the last six months or so where the people talking about Swift aren’t the early adopters who were coming from Haskell backgrounds who wanted to share their functional programming knowledge. Instead, we’re getting people who feel like they need to have an opinion about Swift to feel important.

Lots of people want to post tirades about how Swift should be done. They don’t want to listen to people who have been working with it for the last few years. That defeats the purpose. They want to be the one who can go and write a convoluted piece of code to break the compiler and have everyone tell them how clever they are.

A lot of the sense of community that I felt back when we had Objective-C has evaporated. Back then, new people could enter the community and have seasoned professionals give them a hand with understanding things. Now, everyone feels like they have to establish themselves as an expert and no one is willing to ask actual questions that would make them better Swift programmers. Their shouting is drowning out everyone else’s thoughts and opinions and making it even more difficult for beginners to actually learn Swift.

How We Should Be Doing Things

I worked for Brad Larson for a year. We spent that year porting a legacy code base from Objective-C to Swift. There were two important reasons for doing this:

  1. The code base was fragile and at a point where we could not go in and add or change anything without breaking it.
  2. There were problems that we had encountered over the years that would not have happened if we wrote the code base in Swift.

There was a point when I was working with Brad where he showed me this crazy code that was full of functional programming stuff. I felt very depressed because I didn’t think I could ever come up with something that interesting or complex. It bothered me, so I kept talking to him about it.

After doing this for a while I figured out the right question: What problem is this code solving?

When he started to tell me about how unsafe our previous code was because of the constraints of Objective-C. He had spent years trying to figure out a better solution for his problem and he understood what needed to be done intimately.

Brad is an engineer. He didn’t set out to use all the new toys in Swift because he was looking for an excuse to use them. He had problems he needed to solve and wanted to find the most elegant way of solving them. That solution just happened to include a lot of functional programming concepts. I think he actually rewrote the code a few times because he realized there was a better way to solve the problem.

Code exists as a tool to solve problems. It isn’t an end in and of itself. You can write the most insane Rube Goldergian piece of code imaginable that will work, but why bother?

Writing an app or an open source framework or anything is a little like adopting a puppy. It’s a long term commitment. I don’t think that the people who released the first apps for the iPhone realized they might be on the hook for supporting them for close to a decade. No one anticipated that.

Now that we have a better understanding of that, it’s important to spend time thinking about what your app will solve and how to maintain it long term when it stops being cute and starts peeing on your floor.

One of my goals this year is to release an app. I have done other projects like books and talks, and as such you can take what I say with as many grains of salt as you want. I have been hesitant to produce anything because I worry about the long term maintenance of what I am doing. I know I should just put something out there and learn from my mistakes. We’ll see.

I want to find one, solid piece of functionality that I want to see out in the world. I want to start with whatever the smallest bit of that is and work out from there. I want to keep the scope small and make sure that each piece works and can be built off of to add functionality.

I know that I want to be an engineer. I want to solve problems. I don’t care if no one buys my app or if it is just a tree that falls in the woods where no one can hear it. I just want to know that designed and implemented something well. The problem I need to solve right now is getting over my fear of fucking up and to just do something.

Getting Metal Up and Running: Metal Template

Note: The code from this tutorial is based on this tutorial from Ray Wenderlich. This was written in 2014 and was not updated for Swift 2.0, so there are a few changes I have made to my template to make it up to date. I am also writing my own explanations about what each part of this process does. If you just want something that works, you can download to template. If you want something easier to skim, I suggest looking through the Ray Wenderlich tutorial.

Metal was announced at WWDC 2014. It was the most exciting announcement of WWDC for approximately five minutes until Swift was announced.

I was doing a high level Swift talk in 2014 when I didn’t know the framework very well yet and I just wanted to give people an idea about why Metal was important. People were understandably unhappy that I didn’t show them how to code Metal. I am rectifying that mistake.

As was the case when Metal was first announced, you can’t test Metal code in the simulator. You have to build on a device with an A7 chip or later. The most primitive iOS device you can use for this is the iPhone 5S.

The goal of this project is to create a template that can be used as a base to just get Metal up and running. This doesn’t do anything other than render a color to the screen. I will take this template and add vertex buffers and geometry in a later post to explain how that process works. I didn’t include those in this project because I didn’t want to include anything that would need to be deleted by the programmer before it could be used.

Let’s get started!

Create Project and Import Frameworks

If you want to walk through the process of building the template rather than just downloading it from GitHub, you can follow along with the directions.

Open Xcode and create a Single View Application. You can name it anything you want. If you are using this as a basis for a project, go ahead and name it whatever it will eventually be. Choose Swift as the language. I made mine Universal, but if you know it will only be on an iPhone, go ahead and just choose iPhone.

There are a few frameworks that you will need to import before you can get Metal up and running.

Add these import statements at the top of your ViewController:

import Metal
import QuartzCore

Metal is obvious. You need to import the framework to do anything with Metal. The QuartzCore is a little less obvious. We’ll get to that soon.

Most of the work we are doing will be in the ViewController class. Unless otherwise specified (as in the Shader code), add all code to the ViewController.

MTLDevice

First thing you need to set up for a Metal project is the MTLDevice. The MTLDevice is the software representation of the GPU. I go over the properties of MTLDevice in a previous blog post. We don’t need access to everything that MTLDevice does for this simple template.

At the top of the ViewController class, add the following property:

// Properties
var device: MTLDevice! = nil

You will be seeing and using the device property a lot in this project. The MTLDevice is the manager of everything going on with your Metal code. You will be instantiating this (and all other properties) in the viewDidLoad() method.

There is only one safe way to initialize your device property:

device = MTLCreateSystemDefaultDevice()

At this point in time, every Metal-capable device only has one GPU. This function returns a reference to that GPU.

CAMetalLayer

Note: You might see an error at some point in this code block that says CAMetalLayer not found. This drove me crazy for a really long time. I downloaded Apple’s template that utilized MetalKit that does not have an instance of CAMetalLayer because it is implemented behind the scenes. I thought it was something that was phased out.

This is an ambiguous compiler error. At some point Xcode switched from saying the build device was a physical device to the simulator. Rather than saying the code won’t build on the simulator, it says the CAMetalLayer was not found.

If you ever get weird, ambiguous compiler errors while coding Metal that say something doesn’t exist, check the build target!

Remember back at the beginning of the blog post where I told you to import QuartzCore? You are importing that for one purpose: To get access to CAMetalLayer.

In iOS, everything you see on your screen is backed by a CALayer. Every view, every button, every cell is backed by a CALayer. CALayer is like the canvas you use to render things to the screen. If you want to know more about CALayer there are a few good tutorials on it here and here.

Since Metal is a different beast than a normal UIView, you need to create a special kind of CALayer: CAMetalLayer. This layer doesn’t live in the Metal framework, it lives in the QuartzCore framework, along with the special layer for rendering different flavors of OpenGL ES.

Create an CAMetalLayer property under your MTLDevice property:

var metalLayer: CAMetalLayer! = nil

Initializing the CAMetalLayer is a little more complicated than initializing the MTLDevice. There are four setable properties on the CAMetalLayer:

  • Device
  • Pixel Format
  • Framebuffer Only
  • Drawable Size

Device is self explanatory. It is simply the MTLDevice we created in our last step.

Pixel format is your chosen MTLPixelFormat. There are over a hundred items in the MTLPixelFormat struct, but there are only three options available on the CAMetalLayer: MTLPixelFormatBGRA8Unorm, MTLPixelFormatBGRA8Unorm_sRGB, and MTLPixelFormatRGBA16Float. The default pixel format is MTLPixelFormatBGRA8Unorm, so I am just going to leave it there unless I have some reason to change it.

Framebuffer only is an optimization option. There are two kinds of MTLResource types in Metal: MTLTexture and MTLBuffer. MTLTexture objects are less efficient because they need to be able to sample textures and do pixel read/write operations. If you don’t need those things you can make your code more efficient by telling the compiler this is something it never has to worry about.

Drawable size specifies how large your texture is. Since we are not currently using a texture, we don’t need to set this.

Add the following code to your viewDidLoad() method:

// Set the CAMetalLayer
metalLayer = CAMetalLayer()
metalLayer.device = device
metalLayer.pixelFormat = .BGRA8Unorm
metalLayer.framebufferOnly = true
metalLayer.frame = view.layer.frame
view.layer.addSublayer(metalLayer)

You’re initializing the metalLayer, then setting the properties on it that are relevant to this project. We’re leaving the pixel format to the default and since we don’t have any textures, we’re setting the optimization to true.

As with all layers, we’re setting the frame and adding it as a sublayer. Huzzah!

Command Queue

We will need an object that will organize the commands that we need to execute. In Metal, that object is the MTLCommandQueue. The MTLCommandQueue is our Space Weaver that keeps all of our command threads straight and running properly.

Add this property to the top of your View Controller class:

var commandQueue: MTLCommandQueue! = nil

This creates a command queue that is available to all of our methods within our View Controller. It will be used in a couple of different places and we want it to remain consistent and not go out of scope.

Up next, we need to set the command queue. Add this line of code into your viewDidLoad() function at the bottom:

// Set the Command Queue
commandQueue = device.newCommandQueue()

We’re almost done implementing all the code we need in our viewDidLoad() method. We just need to set up the functionality to actually draw to the screen. For that, we need a display link.

DisplayLink

We now have our CAMetal sublayer in place and we can draw to the screen. But how do we know when to trigger the screen to redraw?

It needs to redraw any time the screen refreshes. Since this is a common task in iOS, there is a built in class available to do this: CADisplayLink.

CADisplayLink exists to synch your drawing to the refresh rate of the display.

Add a new property to your ViewController class:

var timer: CADisplayLink! = nil

In order to set up your display link, you need to tell it what the target is and what code needs to be run every time the link is triggered. Since we are creating this for the view controller, the target is self. We just need the program to render, so I called this selector renderloop:

// Set the Timer
timer = CADisplayLink(target: self, selector: Selector("renderloop"))
timer.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)

After you initialize the display link, you need to register it with a run loop. We are just registering it with the main run loop on the default mode to get access to coordinate the redrawing of the screen.

You have specified renderloop as your selector, but it hasn’t been created yet. Go ahead and do that now at the bottom of the class:

func render() {
  // TODO
}
 
func renderloop() {
  autoreleasepool {
    self.render()
  }
}

So, we didn’t just create the renderloop method, we created another one as well. The renderloop method just calls a render method encapsulated within an autoreleasepool. We’ll be setting up that render method next.

Render Pipeline

Rendering is the process where the program takes all of the information it has about the scene and compiles it together to determine the color of each pixel on the screen.

This is a rich and immersive topic that I would like to explore more fully in time, but for now I am trying to make sure I include the most basic information necessary to understand the code needed to do the minimum here.

If you would like a better explanation of what rendering is and how it works, there is a great explanation of it and the math involved in Pixar in a Box on Khan Academy.

Now that we have our display link in place, we would like to be able set up the code necessary to take a bunch of numbers and small shader programs and turn them into something cool we see on the screen.

To do that, we need to set up a rendering pipeline. A rendering pipeline takes all the inputs you have (vertices, shaders, optimizations, etc…) and coordinates them to make sure that each vertex and fragment is produced properly on the screen.

This will require us to put a number of pieces in place. I will go over each one and explain its role in the process.

Render Pass Descriptor

We are going to go into that empty render method and start to fill it out. The first thing we are going to create in that method is the render pass descriptor. The render pass descriptor is a collection of color, depth, and stencil information for your renderer. In this simple template we are not concerned with the depth or the stencil properties, so we are focusing on the color properties.

Begin filling out your render() method with the following code:

func render() {
    let renderPassDescriptor = MTLRenderPassDescriptor()
    let drawable = metalLayer.nextDrawable()
    renderPassDescriptor.colorAttachments[0].texture = drawable!.texture
    renderPassDescriptor.colorAttachments[0].loadAction = .Clear
    renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 1.0)

First off, you’re creating a MTLRenderPassDescriptor(). You will need to set up the attachments for the render pass descriptor a little later. First you need to set up a property that you will need to hook up to the render pass descriptor.

The render pass descriptor needs a source for it to render. That source is maintained by the instance of the CAMetalLayer. The CAMetalLayer has a method on it called nextDrawable(). Internally, CAMetalLayer maintains a cache of textures for displaying content. This method grabs the next one in the queue available for use.

Our render pass descriptor needs to know a few things about its color attachments: texture, load action, and clear color. Our texture is whichever texture is up next in the CAMetalLayer’s pool of drawable textures.

We have three options for our load action: Don’t Care, Load, and Clear. Don’t care allows the pixel to take on any value at the start of the rendering pass. Load maintains the previous texture. Clear specifies that a value is written to every pixel. We want to use clear here because we want to over write the color that exists currently.

Lastly, we’re setting a clear color. I have arbitrarily set it to a nice magenta color. When you finally pull the switch on this application, you’ll know this succeeds when your screen turns a lovely shade of pink.

Create the Command Buffer

Everything that we do deals with buffers. You need to send commands to a buffer in order to get them to be executed and to see something happen on your screen.

In order to send your commands to a buffer, you need to create one. Let’s do that now.

Add the following code to the bottom of your render() method:

// Create Command Buffer
let commandBuffer = commandQueue.commandBuffer()

The MTLCommandBuffer, like the MTLDevice, is a protocol. It can’t be subclassed and there is only one way to instantiate a buffer object. That is calling the commandBuffer() method on and instance of MTLCommandQueue.

Earlier in this code we made MTLCommandQueue object that was available to the entire View Controller. This is why. We needed to be able to access the same command queue instance we created when the view loaded.

Render Pipeline State

We’re going to briefly jump back to our viewDidLoad() method to add one last piece that we need to set up our rendering pipeline. We need to monitor the pipeline state.

Create a new property at the top of the class along with the others:

var metalPipeline: MTLRenderPipelineState! = nil

Our pipeline state exists to interface with our shaders. Don’t worry, we will get to those.

In order to access our shaders, we are going to need some code:

// Set the Rendering Pipeline
let defaultLibrary = device.newDefaultLibrary()
let fragmentProgram = defaultLibrary?.newFunctionWithName("basic_fragment")
let vertexProgram = defaultLibrary?.newFunctionWithName("basic_vertex")

let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm
        
do {
    try metalPipeline = device.newRenderPipelineStateWithDescriptor(pipelineStateDescriptor)
} catch let error {
    print("Failed to create pipeline state, error (error)")
}

The first thing you will notice is that we are creating a default library.

In Metal, shaders are instances of MTLFunction objects. A Library is a collection of MTLFunction objects.

The purpose of your MTLRenderPipelineDescriptor is to look at your collection of shaders and tell the renderer which fragment and vertex shader your project is going to use.

We’re creating a new default library. After that, we are creating instances of MTLFunction objects by reaching into the default library and looking for them by name.

After we have our MTLFunction objects, we need to tell the pipeline state descriptor which vertex and fragment shaders we want to use.

Since creating a Metal Pipeline is a failable operation, we need to wrap it in a do-try-catch block.

At this point you might be wondering where those vertex and fragment shader functions came from. Good question, you’re about to generate them.

Metal Shaders

Note: I am creating both a vertex and a fragment shader even though this template has no vertex buffer. I am not sure if you need a vertex shader if there is nothing for it to shade, but it builds and this is something you would be adding later when you did have a vertex buffer. It might not be strictly necessary, but I am leaving it here anyway.

In GLSL, you need both a vertex and a fragment shader since they were two halves of the same program. If the Metal Shading Language follows the same paradigms as GLSL, then this is also the case and both a vertex and a fragment shader are necessary for every program you build.

This section is going to be disappointing. I haven’t had a chance to figure this out very well yet, so I apologize for the lack of detail about how I came up with these parts. This will be rectified later.

This is the one part of your code that is not going into the ViewController class. You get to create a new file now!

Create a new file and choose the “Metal File” template. Name it “Shaders.metal”.

The Metal Shading Language is based on C++. I am not as familiar with it as I would like, so sadly this section is going to be less in depth than I would like. I promise there will be many blog posts about this in the next few months.

You are going to create two different shaders: vertex and fragment. At this point you might be wondering how these get into your default library. The way the default library works is that it automatically includes any function that is included in a .Metal file. You could create hundreds of vertex and fragment shaders in various files and all of them would be accessible from the default library. I believe that you can create multiple libraries, but that is just one of the thinks I am going to explore more fully in the future.

This is the code for the vertex shader:

vertex float4 basic_vertex(const device packed_float3* vertex_array [[ buffer(0) ]], unsigned int vid [[ vertex_id ]]) {
    return float4(vertex_array[vid], 1.0);
}

This is the code for the fragment shader:

fragment half4 basic_fragment(){
    return half4(1.0);
}

This code comes directly from the Ray Wenderlich tutorial. I don’t know how it was generated. I don’t want to speculate about how this works because I don’t want to have something out there that I am completely wrong about, so just know this works and I will explain why in a later blog post.

Render Command Encoder

Now that we have a buffer, we need to add some commands to it.

We’ve been creating a bunch of different things that haven’t been applied anywhere yet. We’re ready to put those things to work.

Add this code to the bottom of the render() method:

// Create Render Command Encoder
let renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor)
renderEncoder.setRenderPipelineState(metalPipeline)
renderEncoder.endEncoding()

The command encoder needs to know about the render pass and the pipeline state. We already created both of these things and went into some depth about what they do. We’re simply adding these specifications to the render encoder. After we add those to the encoder, we need to let the render encoder know we’re done by ending our encoding.

Commit the Command Buffer

Almost done! Just two more lines of code:

// Commit the Command Buffer
commandBuffer.presentDrawable(drawable!)
commandBuffer.commit()

We are taking that top drawable texture from the CAMetalLayer and queuing it up in the command buffer to be processed by the render pipeline. Finally, we are committing the command buffer.

Bring it all Together

I have placed this code in a GitHub repository.

There are a lot of aspects of this project that I am looking forward to exploring in more depth over the next few months.

The purpose of this blog post was to try and flesh out some of the code a little bit. Most of the blog posts I have seen involving this kind of template don’t really get into the nuts and bolts about what each of these things does and why you need them in your project.

It would not be useful to delve into the nitty gritty of everything in the framework. This post was long enough as it is!

I hope that this was a little more helpful if you’re like me and you wonder what things do and why you need them instead of just being satisfied with having something that works.

This post took over a month for me to write. It’s possible there are aspects of this post that are disjointed or that I forgot to include. I would appreciate being made aware of any issues by being contacted on Twitter. I would also appreciate knowing if there are any specific topics in Metal that people are interested in hearing about.

Thanks for bearing with me through this incredibly long post!

The Space Weaver is busy rendering fragments and vertices.

The Space Weaver is busy rendering fragments and vertices.

What Happens After Burnout?

Over the last year or two Jaimee Newberry has been doing a series of talks about burnout. She talked about how she went through a period where work went from being her motivator and her escape to this thing that she just couldn’t tolerate doing without feeling sick. She had to take a step back and take some time off to recover from this.

What happens if you don’t do that? What happens if you work through burnout? Good question. I have the answer!!

Humans Are Not Unlimited Resources

I have been going at 150% since the middle of 2012. I figured out that if I just put a lot of time into learning something, I could get over a hump and actually figure out stuff that was confusing at first. This was a magical revelation to me. I knew that if I put enough effort into something, I could do anything. Nothing was impossible.

I had school through the end of 2014. I started coding 80 hours a week to try and speed up the process of learning things as fast as I could. I had time to make up for. Everyone else had been programming since they were 12. I was in my 30’s and I was a woman. I needed to make up for lost time so I could be on the same level as everyone else. I could back it off when I got a job.

I got my first job and we were encouraged/expected to work at least 60 hours a week. I was the oldest person at this company by a decade. I was surrounded by guys in their twenties who were all on Ritalin who could work 24 hours without sleep. I was the only girl. I had to prove that I could do what everyone else could.

About a week before I got fired, I was so stressed out from this job that I had a panic attack and had a car accident that nearly totaled my car. I knew that this was not good and started trying to figure out what I would do after this.

I wound up working on a contract with Brad Larson for Digital World Biology. I was working on an OpenGL project with two other programmers who had at least ten years of experience. I was the only person on this project who hadn’t gone to graduate school. I had to work really hard to try and keep up and not just be a burden on everyone.

After that I worked on a book. Then I worked for Brad for a year. Then I worked on another book. Then I took a part time job. Then in the same month I switched my full time job. I did conference talks. I traveled a lot. I kept thinking I could manage my time and do more and more things.

I also kept telling myself that I would eventually get a break.

“When I finish this book, I can take a break.”

“I just need to finish this one set of conference talks, then I can take a break.”

“This side project isn’t that hard. It will help me network and it’s almost like having a break because it’s not coding!”

I started falling apart around June.

I didn’t want to admit I was falling apart. I made commitments to people and I didn’t want to let them down. I didn’t want to get a bad reputation as someone who couldn’t be counted on. I have mental health issues and I didn’t want to say I can’t do something because I assumed that everyone else was able to do more than I can and I wanted to work twice as hard to prove that I could do what everyone else can.

Used to just have a day every month or two that I couldn’t function. It usually happened on weekends, so I would just get annoyed that I lost a day or two to work on my side projects.

This started happening more and more often.

A while ago I got really sick and it took me a month to get over it.

I could feel myself falling apart, but I was in denial over it. I did things like getting my subscription food service to deal with things that triggered my break downs. I worked around them. Until I couldn’t anymore.

Last week on the last day of the year, I had a total breakdown. I could not sit at my computer without falling over. I felt like my head was full of white noise. I was sent home early and told to relax the entire long weekend.

I expected the enforced vacation would fix me up like it usually does. It didn’t. I could feel myself not getting better. It was like the forced rest was a tourniquet on a limb that was cut off. I knew if I took the tourniquet off that the bleeding would start back up again.

I had to go through intensive guided meditation therapy yesterday for two hours to get stable enough to continue working today. I have to go back in two weeks. I have been told that this isn’t a magic bullet. If I keep doing what I have been doing for the last three years this will keep happening to me and it will get worse and worse and the therapy will be less effective.

I was told that I need to cut back on everything I am doing immediately. I can continue working, but anything beyond that is pretty questionable. I was told if I work at this I can be close to normal in three to six months.

I wrote recently about tech being a casino and how bad start up culture is. I want to emphasize right here that I do not work for a company like that. I work for Black Pixel. Everyone there has been incredibly supportive of me. My boss Janene saw that I was burning myself out and really tried to get me to take care of myself before things totally collapsed. I think it’s rather sad that so few companies in our industry treat their employees like people and actually care about what happens to them. I wanted to make sure I gave them a shout out for helping me through this difficult time.

I keep being asked how I have time to do all the things I do. I used to say that I could do this because I don’t have a family and I live in the middle of nowhere. I made this my life. But that’s not the whole answer. I have been overclocking myself for a long time and I haven’t done what I need to do to ensure I have a long and fruitful career.

I think that overclocking myself for the first bit of time was necessary. I needed to apply some lighter fuel to my barely smoldering career fire to get it to catch. After it caught, I needed to stop applying lighter fuel, but I didn’t know how. I was paranoid about the fire going out that I thought I had to keep poking it and feeding it and tending it at the expense of taking care of myself. There comes a point when you need to walk away. Not permanently, but long enough to sleep or take a shower or eat something. If you built your fire well, it will still be alive when you wake up the next morning.

Going through this total collapse has really frightened me. I felt like I was omnipotent a few years ago when I realized that I could do anything if I put enough work into it. I am realizing that I took things too far.

I think we need to be better about talking about burning ourselves out. With the pace that our world is changing, we are the weak element here. No one can keep up with all the changes. It’s impossible. As long as we keep thinking there is some mystical full stack developer out there that can keep up with every new framework, device, language, etc… that comes out, we will be causing a lot of unneeded suffering and mental anguish.

We are not infinite resources. There is no shame in stepping back for a while to recover from a sprint. A sprint is not a sustainable pace. It’s necessary to implement periodically, but know that at a certain point you need to slow down and take a break.

I had a lot of success in a short period of time. That came with a cost. I think the cost was worth it, but I need to stop for a while.

Adventures in Bread Making: Sandwich Bread

Note: I do not have Amazon affiliate links set up on my blog. I am too lazy and apathetic to figure out how they work. There are a lot of links to products on Amazon. I set up the links to thinks I have personally purchased just to make it easy for people to find if they are interested in doing so. I don’t want this to come across like me trying to sell a bunch of crap. I just hate leaving the house and I buy most stuff from there and wanted to give people suggestions for things.

When my dormant interest in cooking started emerging this past year, one thing that interested me was baking my own bread.

My dad is really into bread, but not the kind of bread I want. When I was a kid we always had whole wheat bread. It’s supposed to be healthier, but it’s like twice as caloric as crappy white bread, which I always thought was bullshit.

Around the time I turned twelve my dad got a bread maker. The only bread he could coax out of this monstrosity was some variety of supposedly French bread. This gummy mass could not be sliced thinner than an inch. He compounded this by microwaving cheese on it. He is of the opinion that anything he makes at home has to be better than anything you buy from somewhere else. I am not of this opinion.

My nightmares of my father’s bread making were one reason I was willing to try the Paleo diet with my ex. I never liked bread and didn’t think it would be a big deal giving it up. I realized that there are lots of different breads in the world and that many of them are heavenly.

I was really intimidated by the thought of making bread. I have never worked with yeast before. The idea of working with it and kneading it were a little scary to me. I figured it would be really complicated.

That was one reason I wanted to make it. It bothered me that it was this mysterious process that everyone I know seemed to muck up very badly. I know that baking anything takes practice and I was hoping that I would do well enough not to get discouraged.

There are a lot of kinds of bread, so I had to pick what I wanted to do first. I was going to try brioche, but I figured I should try something a little more basic before I tackled something fancy.

I knew I wanted to make sandwich bread. I didn’t want to make any of the rustic hearth loaves that my dad foists on us that he buys from the artisanal bread section of the grocery store. I wanted to try making bread with a fine crumb that I could slice finely enough to make grilled cheese sandwiches with. I knew making tearing bread was doable, but I never saw anyone make homemade sandwich bread that could actually be sliced properly.

Recipe and Process

One of the books I bought for my bread making endeavors was The Bread Bible by Rose Levy Beranbaum. I own a number of her books and I was slightly worried about the recipe being too complicated.

Bread Sponge

Bread Sponge

If you’re going to do any kind of baking, I strongly suggest investing in a kitchen scale. Baking is very touchy. A cup of flour can be many different amounts depending on if you sift the flour, how humid it is, if you pack it in, etc… It’s nice to just place a bowl on the scale and pour out the amount necessary. All decent baking books have an option of either cups or weighted measurements. It also dirties fewer utensils to not have to measure out flour. Just dump it out of the bag until you have the right weight.

I also recommend using King Arthur All Purpose Flour. All purpose flours have a certain percentage of hard and soft wheat in them. Some specialty flours like White Lily Flour have far more soft wheat with less gluten in them and are good for softer breads. I know Rose suggests using only White Lily flour for biscuits and America’s Test Kitchen radio gets at least one call a month from someone complaining that their biscuit’s aren’t like Grandma’s where the answer to the question is “Use White Lily Flour.” King Arthur flour should be readily available in most grocery stores or on Amazon. White Lily Flour is also available on Amazon. The flour makes a difference. Don’t save a buck buying generic flour on something like this.

I had one bit of trouble with the recipe. The first step of the recipe is to create a sponge. A sponge is similar to a starter. You take all the liquid ingredients and sugar and yeast along with some of the dry ingredients. You use these to give a head start to the yeast. It cultivates it and lets it get established.

Bread Sponge with Flour Blanket on Top.

Bread Sponge with Flour Blanket on Top.

The directions for the sponge were a little confusing. It said to let the sponge sit for one to four hours. It wasn’t clear if you were supposed to let the sponge sit and then add the remaining dry ingredients or if you dumped them on top immediately. After I stopped being stupid and read the beginning of the book, I saw that you’re supposed to dump them on top immediately.

The recipe says you can put the sponge in the fridge from eight to twenty four hours before being used. You do need to let the sponge sit out at room temperature for at least an hour before putting it in the fridge.

"Zombie" bread that came back from the dead after warming up a bit.

“Zombie” bread that came back from the dead after warming up a bit.

I have done this recipe twice. The first time I did not refrigerate the sponge, the second time I did. The directions said if you are taking the sponge out of the fridge and hand mixing it, to let it warm for an hour. It wasn’t clear if you should let it warm up if you were using a KitchenAid mixer like I was, so I didn’t let it warm up. It was difficult to get the butter incorporated and everything took an hour longer to happen. The bread took three hours to rise instead of two. So if you’re going to put the sponge in the fridge, I would suggest letting it come up to temperature before mixing the dough.

You mix the dough twice. The first time is only for a minute to bring it together. Then you need to let it rest for twenty minutes to give the gluten time to form. Then you do a more intensive kneading.

I have a “newer” KitchenAid mixer I got in 2009. I am pretty sure they are not as robust as they used to be. The action of kneading the dough shakes the mixer to the point that the locking lever shakes loose and the top of the mixer starts bucking like a mechanical bull. I have to hold it down for the kneading process. It’s only ten minutes, but it is still a pain.

After this, most of your labor is done. Now you just have to wait for things. After the kneading is done, you place the dough in a large oiled mixing bowl. It takes an hour and a half to two hours for the first rising. This part of the process took three hours when I didn’t let the sponge warm properly. I keep my house relatively cool, so I put the bowl in the oven with the light on.

Divided dough on its second rise.

Divided dough on its second rise.

If you are going to make bread, I suggest investing in a scraper. My recipe makes two loaves of bread. It’s important when you divide your dough to do as little tearing as possible. I tore my dough the first time. It felt really funny, like it was bubble wrap. You have spent a bunch of time building up bubbles and gluten and connective tissue within your bread that you want to traumatize it as little as possible. An oiled scraper is great for dividing the dough as efficiently as possible. You can also use it to scrape off the dough fairly easily.

Note: Make sure you oil all of your materials well. If you are cutting the dough, oil the tool you use to cut it. Oil the bowl you rise the dough in. Oil the pan you cook the bread in.

My ex used to buy those refillable oil misters, but they always get gummed up and break and never work super well, so I bought Pam spray oil and have been praising God ever since. I don’t care if the hydrogenated oil kills me five years early, I want something that fucking works.

At this point you’re supposed to form the loaves. The directions say to pull it and fold it on a floured surface and roll it up and seal it and a lot of other junk. I have no idea how to do this. I saw diagrams at the beginning of the book, but I just didn’t get it to work. The bread turned out okay. I will be interested to see if learning to do this properly actually makes that much of a difference or not, but for now if you mess up this up it won’t make the bread inedible.

You divide the dough into two loaves and place them in oiled pans to rise. I use these pans from Nordic Ware. Nordic Ware has really nice bakeware. They have a lot of creative cake pans. These loaf pans are pretty robust and seem built to last.

Bread after its second rise ready to be baked.

Bread after its second rise ready to be baked.

I put the dough back in the oven with the light on for an hour and a half. It needs to rise further than that, but at this point you need to preheat the oven forty-five minutes before you bake the bread.

If you have a sheet pan of some kind, you should put it in there as well. I have this one. You are going to throw some ice cubes in the oven along with your bread and this makes it easier to do that.

If you have a pizza stone, I recommend leaving the pizza stone in the oven all the time. Even if you preheat the oven, when you open the oven most of the hot air escapes. Pizza stones retain heat really well, so heating one for a long period of time in the oven before you bake anything will help keep your oven warm.

While the oven preheats I leave the bread near the oven so it can use the heat to rise. When it gets to the point that it’s ready to bake, I put it on the sheet pan and fill a glass with some ice cubes. I place the loaf pans as far away from one another as possible. I dump the ice between the loaf pans and shut the oven.

This is one of the few recipes I have used that has the time right on the button. It says to bake for fifty minutes and that works perfect.

Baked bread cooling before being consumed.

Baked bread cooling before being consumed.

As tempting as it is to dig into your warm, fresh bread, don’t do it! The bread needs time to cool and solidify. Make sure when you cut the bread that you use a good bread knife. I really like the Victorinox line of knives. I have a paring knife and a chef’s knife from them. America’s Test Kitchen highly recommends them and they are cheaper than a lot of other “good” knives.

Since homemade bread doesn’t have preservatives in it, it won’t last as long as grocery store bread. I have bought loaves of sandwich bread from the store that have been in my house for three weeks without spoiling. That is rather frightening to me.

I live alone and I can’t eat two loaves of bread before they go bad. I got around this the first time by giving one loaf to my mail man for Christmas. The second time I froze the second loaf. You can buy bread bags from Amazon to freeze your second loaf. Amazon also has Chinese take out containers and a lot of other industrial food service stuff, which I think is fantastic. Don’t get bored and look at this stuff or else you will wind up with a hundred plastic Egg Drop Soup containers and a hundred disposable sets of chopsticks.

Conclusion

Bread can be cut quite thinly.

Bread can be cut quite thinly.

The bread turned out perfect. I could cut very thin slices of bread after it had cooled. It makes really good toast. The crumb is fine. The flavor is good.

The recipe that Rose gave was pretty fool proof. You just do everything that it says to the letter. It doesn’t necessarily explain why you let the dough rest for twenty minutes. If you’re like my friend Nicki, you might just skip any step you think is superfluous. I think it would still be edible, but you won’t get optimal results.

A lot of success in cooking is just following directions. Letting things rest after they’re done, oiling things properly, etc… I know we all have trouble following directions sometimes, but when you get a good set and follow them properly it really demystifies the process of doing something complicated.

One of the simple joys in life: Toast made with fresh bread.

One of the simple joys in life: Toast made with fresh bread.

My Resolutions for 2016

I woke up on the last day of this year completely non-functional. I am used to having a day or two of non functionality, but I can usually target it for weekends so that I don’t have to tell anyone I don’t feel well or miss work. Wasn’t able to do that a few days ago.

I really tried to make it to the long weekend, but my body gave out on me before then. The wonderful people at my work told me to take off early and get some rest and not to do any work this weekend. It’s a good place and I am happy that I work for people who want me to take care of myself.

Since I am not supposed to code or do any work right now, I have been thinking about what my goals are this year. I know most people are resolving to work out more often or lose weight or whatever. My goals are going to be a little different.

  • I am not working on another book
  • I am going to release an app or an open source project
  • I am going to clean and organize my house
  • I am going to make more of an effort to entertain at my house
  • I am going to cook a complicated special meal once a month
  • I am going to make complicated special dessert once a month
  • I will go on a real vacation this year

I am not working on another book

I can’t do this any more right now. When I worked on my first programming book, I was between jobs and I was able to dedicate all of my time to working on it. There was a period of overlap, which was incredibly difficult. I wasn’t planning to work on one this year, but a series of events lead me to work on the Swift Apprentice.

Working on that broke me.

I would sit down to work on it and feel my head filling with white noise. Even thinking about going to work on my computer made me want to curl up in a ball and cry. I missed a lot of my deadlines and I felt horrible for not doing what I promised to do. I was supposed to do two chapters but I could only pull myself together enough to do one.

I don’t know why this project was the one that broke me. I had worked on other books and wrote articles for Objc-io, but this was the straw that broke the camel’s back. I have been trying to recover from it ever since.

Everyone on the Swift Apprentice was incredibly supportive and understanding. I do not want this to come off in any way like I am blaming anyone there. I had no idea what my limits were until I went over them. I actually wrote a long pitch to Ray about a Metal book on the way home from 360iDev. I had only gotten about three hours of sleep a night for a week and a few hours after I wrote him that pitch my body gave out and I nearly passed out several times on my trip home. I slept for two days after that.

I think when I am about to crash I go into denial and try to add even more work to myself because I don’t want to admit that I am spent. It’s taking me longer and longer to recover from a crash and they are happening more and more often.

So I am not going to work on anything extra this year. I just can’t. I will keep blogging and doing other writing for myself, but I am not taking on anything with a deadline for someone else this year. I just can’t do it right now.

I am going to release an app or an open source project

Going along with the previous resolution, I need to do some work for myself this year.

Most job postings require you to have published an app to be hired. I have gotten around that by working on books and talks and working for very intelligent people.

So far in my career I have never done anything for myself or on my own.

I found it hard to justify working on my own things when I had so many opportunities presented to me. It astonishes me that I have written a book with Chris Adamson and worked for Brad Larson and have had the incredible privilege of joining the Ray Wenderlich team. I keep waiting for someone to tap me on the shoulder and tell me that I am living someone else’s life and it’s time to go back to my actual one.

It bothers me that I have not finished something of my own. I pushed it off to the side while I tried to establish my career. I know that doing something of my own would establish it further, but stuff kept coming up. I kept thinking I would work on it when this current thing was over, but then another thing would come along and another.

I know this is totally a first world problem that I have too many good opportunities. I took a lot of them because I found it hard to say no. I need to do that this year because I need to focus on what I want to do and be known for.

I did the writing and the speaking because I wasn’t super comfortable with my programming skills. I was a beginner and I needed to find a job to support myself. Doing things I already had experience with helped me jumpstart my career. It was the right move to make at the time.

Now I want to focus on showing that I can code. I want to find something that hasn’t been done before and I want to figure it out. I want to do this for me. I don’t care if an app I write makes a penny, I want to make it because I want to know I am capable of doing so.

I am not putting this off any longer. I am doing something for me this year.

I am going to clean and organize my house

I have written in the past about my house. I started organizing and cleaning it a month or two ago. I noticed over the last week or two that it’s been sliding back into chaos. That should have been a warning to me that I was heading for a crash.

One problem I have is that I don’t have an organizational structure. I can’t put anything away because there is nowhere to put anything away to. I have been boxing things up and storing them in the basement.

2015 was the first year where I had to actually pay bills and budget stuff. I was terrified of running out of money, so I didn’t really invest in things for my house for a while. I was also gone most of the time and it was easier to just not think about it. I had two rooms in my house I never went into because I was never home.

Now that I work from home, it bothers me to see how messy everything is. I have never gotten to decorate my home before. I didn’t think of this as my home until recently and I have started to become mentally unfrozen about it.

I am hoping to budge out an amount for shelves for my books and my geeky toys. I want to pain the rooms of the house in colors I like. I want to organize the kitchen and finally figure out what stuff my ex left for me.

I don’t want to sleep walk through my life anymore. I want to be actively engaged in world around me, including the place I call my home.

I am going to make more of an effort to entertain at my house

I live in the middle of nowhere. I also like to plan things and cook. I always wanted to have parties, but neither my father nor my husband would let me do that. It also wasn’t like I had anyone to invite over anyway.

I don’t want to get too isolate out here on my own. I would like to be able to have people come over here and enjoy themselves. The idea of being able to actually plan out a menu and feed people and have people come over here makes me really happy.

I don’t want to be ashamed of the place that I live. I would like to have people come here and enjoy themselves. I would like to have an excuse to dress nicely and have a good time with people. This also gives me an incentive to make sure I clean my house properly periodically and not let it slide into chaos.

I am going to cook a complicated special meal once a month

I wrote recently about having a subscription food service. I like to cook, but I find grocery shopping to be overwhelming.

My weekly subscription is really awesome for feeding myself every day, but the meals are by its nature simplified for busy people who don’t have a day to prepare a meal.

There are a bunch of things I want to figure out how to make that are complicated.

I want to actually organize myself by choosing one complicated thing a month that I will make. I will have a targeted list of ingredients so I don’t just randomly start buying things with the idea that I could make a lot of different things.

I think by planning a day, like the second Saturday of every month, to do something special and to have a targeted list of things I want to do, that I can organize myself enough to do something special.

I could try to coordinate this with the entertaining resolution. I would love to have a dinner party. I know no one does that anymore, but I want to do it and I think it would be fun.

I am going to make complicated special dessert once a month

One thing that has disappointed me as an adult is not being able to bake things. My ex took up the Paleo diet, which doesn’t allow for any kind of baking at all.

This sounds totally stupid, but I grew up thinking that I would be able to bring cookies and stuff to work for my co-workers. I haven’t had a job like that since I worked in the call center. Right now I work from home so I don’t have an office to bring things to. At my last office I was discouraged from bringing food in. I brought in doughnuts once and no one would eat them.

I am bothered by how touchy everyone is about food. Everyone is on a perpetual diet. Everyone thinks that if you eat a brownie you are a bad person with no willpower. It really fucking sucks.

So I am going to make something every month. Hopefully I can find people to pawn it off to. If not, I just want to make it for myself. Hopefully I can freeze it. Hopefully I can serve it at something.

It sucks investing time in making something to have people turn their noses up at it and feel virtuous because somehow they are better than you are because they don’t indulge in things that are bad for them. I made stuffed mushrooms for my parents for Christmas Eve and my dad would not keep the leftovers because I put bacon in them. He talked down to me about how I was going to die before I turned forty because I eat bacon a few times a year.

Life is short. Eat cake. Not every day, but sometimes.

I will go on a real vacation this year

The last vacation I went on was in 2013. I went on a cruise during my winter break between semesters at school. My ex and I spent most of the cruise drinking. He discovered that he loved scuba diving. I discovered that the idea of putting my head underwater threw me into a panic attack.

I wanted to spend the whole time laying around the adults-only pool area relaxing and reading programming books. I was forced off the boat at each port. I didn’t get to do anything that I wanted. I got screamed at at least three times. It would have been a wonderful vacation if I had been alone.

I want a real vacation.

I have gone on trips to conferences. I sing for my supper and they’re all working trips. I have gotten to see a lot of amazing places and met a lot of amazing people. It’s been great, but it’s also been exhausting. The last trip I went on I was awake for 24 hours straight.

I wanted to speak at conferences so I could afford to attend a lot of them, but most of the conferences I went to in 2015 were so overwhelming that the only session I attended was my own. I would spend long periods of time hiding out in my room because I was too spent to leave and see others speak.

I have thought about doing vacations before, but the effort for planning one and the cost have been overwhelming to me. I don’t know how people do cheap vacations. If anyone has advice I would be happy to hear it. The cheapest flights I have been able to book are $350. Then it’s hard to find a hotel for less than a hundred bucks a night. If you are gone a week, it’s at least a grand to just get there and be there. I am sure there are cheaper alternatives, but I have been too mentally exhausted to deal with it, so I haven’t looked into alternatives. I have just written off the idea that this is something I can do.

I would like to either do a cruise or an all-inclusive resort. I want to step off the plane someplace warm and not have to think about anything for a week. I want to not worry about feeding myself. I don’t want to worry about finding alcohol. I just want to be able to set somewhere I can relax and do whatever I want when I feel like it. I want no friction. I don’t want to feel bad that I am not going out and visiting historical places or going to museums. I don’t want to have to figure out where I am getting food. I just want to relax and do whatever I feel like.

If anyone has any suggestions for resorts or cruises they liked, I would appreciate it, especially if it’s targeted at singles. A cruise would be twice as expensive for me to travel as a single person. It might still be the best option, but I am open to suggestions that are different.

Rest and Renewal

I am figuring out the hard way that I can’t work all the time. I have been running myself into the ground for the last three years. I needed to do that for the first couple, but I can’t keep doing it anymore.

I have been afraid of backing off at all. I saw people who have been doing the same thing for fifteen years and have gotten complacent that things will never change. They think their jobs will always be there. They don’t try to push to move up or evolve their jobs.

I picked the handle Red Queen Coder because the Red Queen had to run as fast as she could just to stay in one place. If she wanted to get anywhere, she would have to run twice as fast as she was. I have been running twice as fast for the last three years. It’s time to step back to just running and staying in one place. I need to rebuild my energy for the next sprint.

Halt and Catch Fire

I have a bunch of TV I keep meaning to watch that I tend to “save” because I know it’s going to be a good show and I don’t want to waste it on times when I just want junk food.

One of those shows is Halt and Catch Fire. It’s like Mad Men, only it’s set in the 80’s and it’s about the computer revolution.

I am generally attracted to anything computer related, but there tends to be a few stereotypes you encounter when dealing with technology. You wind up with things like Silicon Valley where the only female programmer you see is a girl dressed in pink whose business is “Cupcakes as a Service” who is wandering the crowd asking if anyone knows Java. You also get the main character, Cameron Howe, in HaCF who is the female super genius hacker chick who drinks and swears like a man.

Cameron is a cool girl. She lives off of pizza and orange soda while managing to weigh ninety pounds. She doesn’t wear a bra. When she gets stuck on a bug she sleeps around with people to get unstuck. She wants to name the operating system after Ada Lovelace and has people telling her she is the next Grace Hopper. She’s a manic pixie dream girl.

The second stereotype is a lot more flattering than the first stereotype. However, it is a stereotype. It is somewhat damaging. There is this idea that if you’re a girl in technology you have to follow a certain mold. You have to be cool. You have to be a nerd and play video games. You have to be attractive in a certain way. Above all else, you have to be better than everyone else. There is more scrutiny paid to you if you are a girl who is a programmer and you can’t just be a good generalist and blend in to the background. You have to be a super star. You have to be flashy.

I benefit from these stereotypes. I happen to enjoy geek culture. I am interested in hard things like OpenGL that most people don’t try or don’t make time for. I am a red headed extrovert who likes to generate attention for myself. I fit a certain mold and I benefit from the positive stereotype.

If Cameron was the only female character in HaCF, then I would not be writing about it. There is another female character in HaCF who I think is far more revolutionary than Cameron: Donna Clark.

tumblr_n7pz8huk9J1qfdofwo1_250The main hardware engineer in the show is her husband Gordon. They met while both of them were going to Berkley studying engineering. She wrote her thesis on data recovery. Donna works for Texas Instruments and is a kick ass engineer in her own right.

She is also a mom. She and Gordon have two daughters.

Donna is a character you never see on TV. She is a working mom in an intense field.

Even though Gordon is a main character on the show, it spends a lot of time from Donna’s perspective. While Gordon is complaining about how hard his job is, he is coming home to a hot meal that his wife made after an equally hard day at work. Except when she gets done with her job, work is not over. She keeps working after coming home. She has to care for the kids and keep her family afloat. Her parents lend her husband money and set him up with business connections to allow him to pursue his dream even though it is tearing their family apart.

Excuse me, I need to call someone to make sure my house is still standing.

Excuse me, I need to call someone to make sure my house is still standing.

At one point in the first season, Donna has a business trip. She will be gone for one night. She leaves lasagna for the family and does everything she can to make things as easy as possible for everyone while she is gone. She comes back to find blood all over the floor, the sink completely disassembled, her children unattended, and her husband digging a giant hole in the back yard.

Compare Donna Clark to Skyler White from Breaking Bad. Even though Walter White is a murdering drug dealer, the show is designed for you to root for him. Skyler is vilified by fans of the show for being a killjoy bitch for cramping Walter’s style.

Someone has been hitting the lead based solder a little hard recently.

Someone has been hitting the lead based solder a little hard recently.

Compared to Skyler, we see a lot of what Donna has to put up with. We see her spinning plates trying to keep the family together while her husband throws the family into chaos. Gordon isn’t seen as this wunderkind genius whose every whim should be indulged and pampered. He is seen as an unstable, sometimes pathetic man who is being used by the people around him for gifts he has that he can’t control on his own.

We need more Donna Clarks on TV.

Back before everyone started playing the start-up lottery and tech became a casino, you had women who were engineers and mothers. It was a solid nine to five job. You had to be stable and reliable and it was possible for women to be mothers and engineers. That is far less tenable now.

There was a company board member I talked to at one of my previous jobs who I feel exemplifies the problems we are currently seeing in tech.

This guy was married with daughters. He also worked in the Bay area while his family lived elsewhere. He was telling me about how he only sees his family one day every week or two because he’s traveling all the time. I was upset for his wife and asked if it was hard. He told me he was used to it. I was annoyed and clarified I meant was it hard on his wife and kids. He smirked at me and said, “Well, they got used to it.”

I got the impression from this person that he figured I was doing programming as a hobby. I mentioned how one morning I made frozen pizza for breakfast and he said, “Hey, enjoy that while you can before you get married and have some kids.”

It was just assumed that I was going to get married and have a family. This was just something I was doing to keep a roof over my head until that happened.

I felt that this person saw no point in cultivating me. I think he saw doing anything to cultivate me would be a waste because I was just going to marry someone and fulfill my purpose of being a caretaker.

This attitude really fucking sucks, and not just for me.
worldPossible
I sacrificed a lot to be a programmer. I decided I wanted to be a programmer because it was something I didn’t understand and it bothered me. If I found a job that paid me to do it, cool. That was icing on the cake. I wanted to learn it and master it because I wanted to know it. I sacrificed my marriage and my mental health and my social life to push myself to get where I am right now. This isn’t some hobby that I am doing while I am waiting around to find some guy to give me children.

I would like to get married again and have a family, but I don’t want to do those things if it means I am lobotomized. I don’t want to be an effective single mom because the father of my children is never home. I don’t want to be with someone who assumes I will just give up on all of my hopes and dreams to make theirs possible.

Let’s say I found someone who would respect me for my hopes and dreams. Let’s say I find someone who wants to split the parent teacher conferences fifty fifty and will watch the kids while I go and speak at conferences. They won’t be able to do that.

Programming isn’t a job anymore. It’s a lifestyle. It’s a cult.

After people figured out that four people in a basement could create companies that are worth ten billion dollars, suddenly tech became a cult. You don’t just have a job, you are working on something that will change the world. You are expected to dedicate body and soul to this grand and noble scheme that will result in millions of dollars for other people.

It’s not okay for you to tell your boss that you are leaving in the middle of the afternoon to take your child to the doctor. You can’t say that you don’t want to fly to China for two weeks because you want to be home to tuck your kids into bed.

hacf-s1-kerry-bishe-QA-120One reason everyone wants young guys as programmers is because they don’t care about this stuff yet. People say it’s because they are more up to date with the technology or that they are prodigies or whatever else, but it’s all bullshit. It’s about finding the most exploitable people you can to get as much out of them as you can until they break.

It’s just assumed that you either will never get married or if you do that your wife will make this life possible. Your wife will watch your children while you are gone 300 days out of the year. If you are a woman and you have kids, people will assume that you are going to be the one to care for them and you’re not cultivated because you’re not going to be okay with being gone 300 days out of the year.

This system sucks. It sucks for everyone. It sucks for the women who don’t have opportunity because everyone assumes you are on the mommy track. It sucks for guys that they spend most of their lives working to support a family they never get to see. This system only benefits sociopaths.

As long as mothers are invisible, then no one has to bother thinking about how fucking broken this system is. Everyone goes along with it and won’t question it because they’re afraid of being cut off from it or seen as a trouble maker.

Bill Watterson, the creator of “Calvin and Hobbes”, was notorious for refusing to sell out. He never licensed Calvin and Hobbes. No one had little stuffed Hobbes dolls next to their Dogbert dolls in their cubicle. No one has mugs with Calvin on them. He didn’t care about making a bunch of money. He didn’t care about being famous or being a public figure. He wanted to do the work that fulfilled his soul. He had an amazing quote about how he chooses to live his life:

Creating a life that reflects your values and satisfies your soul is a rare achievement. In a culture that relentlessly promotes avarice and excess as the good life, a person happy doing his own work is usually considered an eccentric, if not a subversive. Ambition is only understood if it’s to rise to the top of some imaginary ladder of success. Someone who takes an undemanding job because it affords him the time to pursue other interests and activities is considered a flake. A person who abandons a career in order to stay home and raise children is considered not to be living up to his potential — as if a job title and salary are the sole measure of human worth.

You’ll be told in a hundred ways, some subtle and some not, to keep climbing, and never be satisfied with where you are, who you are, and what you’re doing. There are a million ways to sell yourself out, and I guarantee you’ll hear about them.

To invent your own life’s meaning is not easy, but it’s still allowed, and I think you’ll be happier for the trouble.

Take the trouble.
halt-and-catch-fire-episode-103-pre-980x551