Rules for Engagement on Twitter

Hi.

Today I blocked several people for the first time ever on Twitter. These are people I have known for a long period of time and one of whom I have met in person and know to not be a sociopath. Here is why.

I have Post Traumatic Stress Disorder. When I was in college a stranger held me hostage in my dorm room and raped and tortured me for two and a half hours. For those of you fortunate enough to not have PTSD, one of the delightful aspects of having it is dealing with flashbacks. Flashbacks happen when you are in a situation that is reminiscent in some way of the circumstances that caused your trauma. It’s your brain’s way of protecting you. It senses that you are in a similar situation to one where bad things happened to you, so it tries to force you to flee from that situation to protect yourself.

I recently certified Delia as an Emotional Support Animal because one thing that triggers flashbacks is being trapped in an enclosed metal tube with a bunch of men I don’t know. I can fly without her, but the efforts it takes for me to calm myself down for several hours drains every ounce of energy I have. I get to my destination exhausted and it can take me up to a month to recover.

Another thing that triggers flashbacks is dealing with aggressive males who do not listen to me and continue to engage me when I want to be left alone.

There have been multiple times this year on Twitter where I have made a comment or asked a question and have been bombarded with well meaning but obnoxious advice from men. It ranges from speaking to me like I am a toddler and couldn’t possibly have considered the most obvious solution that they are giving me or trying to force me to use their preferred mode of whatever in spite of my pleas saying that I already considered it and it won’t work for reasons I don’t want to articulate in 20 tweets.

When this happens, I start to feel overwhelmed. I feel personally attacked and unsafe. It causes me tremendous amounts of emotional distress. I start to have flashbacks and experience all the emotions I experienced when I was being raped. I have had at least a half dozen times this past year where I have gotten so distressed from these interactions that I have had to make emergency appointments with my therapist and spend money I don’t have trying to recover to the point that I am able to work. I have been in constant fear of not being able to work and earn money and destroying my career this year because these well meaning but clueless men have insisted upon trying to be “helpful.”

I have tried multiple times over the last year to explain to people that what they are doing is causing me real harm and damage. Every time I have attempted to engage in a dialog in explaining where I am coming from, I get a bunch of defensiveness and people telling me that they’re engineers. They want to solve the problem. They’re not intending to cause me psychological damage and therefore I don’t have the right to be upset by their behavior.

I don’t give a shit what you intend. It’s the result of your actions that matters.

If you are driving around and you get distracted by your phone and run someone over who is paralyzed for life, it doesn’t matter that you didn’t intend to run them over. They’re still damaged. You don’t get to hide behind your intensions when what you are doing is causing me actual harm.

I am tired of being responsible for having to do the emotional legwork that men are unwilling to do. I have told them many times how to avoid causing me harm and I am being told it’s my problem and they won’t change because their desire to avoid hearing that they’re doing something harmful is greater than my need to be able to earn a living.

I don’t want to be a massive bitch and make people feel like they can’t talk to me without getting bitched out, so I am establishing my rules so that I can protect myself psychologically while still being able to engage with people on Twitter:

First Strike: I Ask You to Back Off

I understand that on Twitter things can escalate very quickly and tempers can flare. At this point something will have happened and I will start to feel overwhelmed but I can still avoid a total shutdown, but only if you stop engaging with me.

I will tell you that I am feeling overwhelmed and ask you to back off.

At this point, if you back off, we’re good. You can feel good about being an engineer and know that you have made a situation better. If you still want to make this point to me later, please wait a day. Ask me for my email and send me an email or give me a chance to engage in a better forum of communication.

Second Strike: I Send You a Link to this Blog Post

It’s possible you’re reading this because I sent you a link to this blog post. I am trying to explain to you why I can’t continue to engage with you. I am not trying to blame you or tell you that you’re an asshole. I am assuming that you mean well and I am trying to find some way to let you know that was you are doing is causing me harm with the hope that you will respect my need to be left alone. Again, if you read this post and you back off and leave me alone, no harm, no foul.

Third Strike: I Will Block You

If you have gotten to this point and you are still continuing to engage with me, then I will block you. I am doing this out of emotional self defense. You have shown that you are not willing to respect my need to feel safe. You are leaving me no other option than to block you to protect myself.

If you’re someone that I know personally and have invested in a relationship with, I will try to remember to unblock you later. I will emphatically ask you to please stop doing things that cause me psychological trauma.

I do not want to block people, but I also do not want to spend a hundred dollars seeing a therapist to be able to keep working. My need to be able to work supersedes your desire to feel helpful. If you want to be helpful, please back off if I tell you that you are forcing me to shut down. If you respect that, we’re cool.

Thank you.

Special Announcement: The Metal Programming Guide

Hello all. For the last few weeks I have been hinting that I have a new project that I had not yet announced yet. I wanted to make this announcement at MacTech, which I did yesterday, so I am now publicly announcing this.

I am working on a new book: The Metal Programming Guide. If you are familiar with the OpenGL series of books like the OpenGL Red Book and the OpenGL Blue Book, this is going to be The Red Book for Metal. The publisher for this project will be Pearson/Addison Wesley, so this is not a self-publishing effort on my part. I will have technical editors and people breathing down my neck if I miss deadlines!

Back in 2014, when Metal was announced, it excited me tremendously. I did a series of conference talks on it throughout that year, but a little thing called Swift kind of got in the way of my learning path for Metal.

This year has been something of a disaster for me on a personal level and I didn’t get to accomplish what I had hoped to this year. Being given an opportunity to finally get to master Metal and write a book about it has given me hope for the future. I have always felt like Metal was something I was meant to do, but I wasn’t really ready to tackle it until now.

Right now I am trying to balance doing some short term contract work with attempting to work on the book. I hope to not run out of money before I finish the book, but I also want to avoid doing full time work that would prevent me from making progress on the book. We are very early in the process right now, but I am giving it everything I have to try and get this done in a reasonable amount of time.

I am hoping to be able to make weekly posts on here and my podcast about various aspects of Metal programming that I am not able to include in the book due to lack of time/space/things being out of scope.

Even though I have been a co-author on a number of programming books already, it has always been my dream to do an immersive book on a topic such as Metal. I am excited to learn this amazing framework and share that knowledge with everyone else.

I’m announcing it here on this blog because I have absolute confidence that this project will be successful. I’ve been waiting to do this for a long time. I do not plan to drop the ball on this. Bring it on!

The Cost of Complacency

This is another cross post from my podcast Janie Rants. I will record this script later today and post it to that site as well.

Yesterday I, along with half of our nation, watched in growing horror as we saw the election results come in. Last year we laughed at the Republicans as they saw their establishment candidates knocked out one by one by an orange con man. We shook our heads in disbelief that any woman would vote for a man who was on tape talking about grabbing women by the pussy. He went on rants at 3:00 in the morning calling an ex-beauty queen a pig and an eating machine. Surely no one would trust this man with codes that could start a nuclear war?

I want to rewind everyone back a few weeks to October 27, 2016.

This feels like a lifetime ago, but this was when Apple announced their update to the new Retina MacBook Pro.

People like me have been waiting anxiously for an update to this line of computers. I have wanted to buy a new laptop for a while but I wanted to really max out the processor and the ram.

What did we get?

We got the same RAM. Close to the same processor. And a touch bar. Oh, and all of our ports are now gone and we have to spend an extra hundred bucks or two to buy all the dongles we need to plug our new iPhone 7s into our laptops.

A lot of people were really angry about this. Most people dismissed them because every time Apple announces something, everyone is angry. Everyone is angry that their pet thing didn’t get featured with an upgrade.

Most people who complained about the new Macbook Pro were chastised by the community. We’re told that Apple has a reason for doing what they’re doing and a lot of us didn’t like certain changes made to iOS but that after we got used to them we realized they had a purpose and Apple knew what it was doing, so we should have faith that there is a reason behind all of this too. Even if there isn’t a reason behind everything, what are you going to do about it? Apple is still the best choice even if it’s not as much better as it used to be.

I feel like those people who are telling us to stop complaining are like the establishment politicians from both the Republican and Democratic parties.

People in the Apple community are upset. We remember ten years ago when we saw all these amazing innovations coming from Apple. I recently received a vintage blueberry iBook from someone to decorate my living room. When I saw the computer for the first time, I laughed out loud with delight. The design of the computer was like nothing I have seen in such a long time. It was different and unique. It made me smile.

Nothing Apple has produced over the last five years has made me smile.

I got an aluminum Mac Book in 2004 that was nice. It looked modern. It was well built. It had a neat track pad. It was light enough that I could carry it places. It felt like a modern machine.

When I look at every computer that has come out since that one, they’re all variations on the same tune. Same with the iPhone.

Every year the devices get thinner and more fragile. There are more bugs in the tools and the frameworks. There is less time to create innovative applications because by the time you learn the new ropes, the system changes. The changes people actually want to see never get done. But there is an assumption that people will just keep buying Apple products because we’re locked into an ecosystem and we’re obligated to do so.

I feel like this is similar to the attitude we saw from the Democratic party in regards to Hillary Clinton.

I want to say I like Hillary Clinton. I think she would have been a solid president and I am incredibly sad that she lost. I think that thirty years of gas lighting and fake scandals and constant investigations turning up nothing have tarnish her reputation and it saddens me that an orange troll can be on tape talking about grabby women by the pussy and be taken more seriously than a religious woman who has dedicated her life to public service.

That being said, this election was about change. The election in 2008 was about change too. The Great Recession hit and destroyed our economy. The Democrats rode to the White House on the shoulders of Barack Obama, the great hope of our generation. He promised to close Guantanamo Bay and to stop sending our soldiers to die in the Middle East. He promised to clean up the corruption that resulted in the Great Recession.

He didn’t do any of these things.

He passed the Affordable Care Act, which is a landmark piece of legislation. One of the only reasons I can be an independent consultant is because of the Affordable Care Act.

But no one went to jail over the corruption that caused the Great Recession. Gitmo is still up and running.

We can rightfully make the argument that Obama was hamstrung by Congress for the last six years, but the biggest reason that we wound up with the Tea Party just two years after Obama’s historic election is because people felt betrayed that he didn’t do what they thought he would do. He didn’t clean up corruption. He didn’t throw the bankers in jail. He created a giveaway to the insurance industry to allow them to have a blank check for health care. We rejected Hillary in 2008 because Obama promised us hope and change and we got more of the same.

The health insurance marketplace opened on November 1st. My health insurance went up nearly a hundred dollars a month. I saw classmates who work on family farms show that the cost of insuring their wife and child in the most bare bones package available was a thousand dollars a month with a twelve thousand dollar deductible. That’s completely bogus.

Obama continued to get advice from the same corporate people that crashed the economy in the first place. He didn’t enact the bold action people elected him for because he trusted the advice he got from the people with the same college education and background that he had. I used to think Hillary would have been different, but now I am not so sure.

There is an economics experiment called the Ultimatum Game. In this game, there are two players. One player is given ten dollars and is told that they can split it any way they want to, but the other player can either approve it or deny it. If the player approves, the money is split accordingly and each player takes their money and leaves. If the player denies it, then no one gets anything.

A common way most people split the money is to take nine dollars and offer one to the other player. If you think about this rationally, the second player should approve of this deal because it gives them a dollar they would not otherwise have. But we’re people and we don’t think rationally. We don’t think it’s fair for the first player to get nine dollars when we only get one just because they got to choose the split. They have more to lose than we do if we reject the offer and we feel better about denying the other person their nine dollars than we do about losing our one dollar.

For the last several decades the American political system has been an ultimatum game. The establishment politicians have used social issues like abortion and civil rights to try and bludgeon us into agreeing to their deal. We’re supposed to vote for Hillary to avoid a future dictated by people like Paul Ryan wanting to enact his Ayn Randian vision of America where he will destroy our safety nets and let everyone die in a state of unmitigated poverty.

People who are shocked by this are not familiar with the ultimatum game. They thought everyone would nicely go along with the status quo because the status quo is better for them than the probable hell the next four years are going to be. But they’re going to be a lot worse for us than they are for them. It’s going to be worst of all for our Muslim brothers and sisters out there.

I consistently see people earning ten dollars an hour fighting against a fifteen dollar an hour minimum wage because they don’t think people working at McDonalds deserve fifteen dollars an hour when they’re only earning ten. They don’t care that they would increase their own wage by fifty percent by supporting a fifteen dollar and hour minimum wage, they just want to make sure that no one underneath them manages to get ahead of them. They want everyone to be brought down rather than being brought up.

A lot of anger and ill will right now at the Democratic party is reminiscent of a lot of the arguments I have been making about the tech industry. The party wanted Hillary because Hillary was a good culture fit. She would support their interests. They all met at the Christmas party and sent their kids to the same schools. They wanted someone they were comfortable and familiar with.

And that is exactly what everyone is angry about.

They don’t want to take their dollar while the banks get nine. They don’t like being told that they should be happy with their dollar because if Donald Trump is president then they won’t get any dollars.

Right now in the tech industry we have a massive glut of wealth that is going to a small group of people who are all in their early twenties who all went to Stanford or MIT who are all pitching the exact same shitty product that already exists in ten different forms somewhere else. Nothing innovative is happening because it’s a giant echo chamber where the same people are starting companies doing the same things and selling them off to the same other larger companies. No new ideas or people or perspectives can get in because they’re uncomfortable and we’re on the verge of a collapse because of it.

You can’t keep producing the same product over and over again that people aren’t interested in buying. You can skate by for some period of time on that apathy, but eventually a disruptive force will come and shake things up.

IBM didn’t take the PC market seriously. They didn’t think a small company like Apple could completely change the way we live our lives. Now Apple is falling into the same complacency trap that sucked up IBM and Xerox. They think everyone is locked into their ecosystem and that no one wants to buy Android phones because they’re inferior, so they aren’t listening to what we’re saying we actually want because they think we have no choice but to accept what they’re producing.

Let’s imagine that another company creates a fantastic competitor to the iPhone. It could be Google. It could be some upstart we’ve never heard of. Their products are innovative and exciting. You’re not trapped in a proprietary ecosystem where you must own an underpowered Mac to write applications for this new device. You can buy cheaper and better devices that are genuinely exciting and not just more of the same.

Or pretend that there is a customer rebellion and everyone refuses to buy iPhones. Some change is made and the customer base leaves out of spite.

It might not happen tomorrow, but it will happen. People don’t like being backed into a corner and told they have no choice. It happened to other companies and it is happening to Apple. Apple can listen to the rumblings of discontent coming from its user base and make a decision to embrace the things that made it great, but I don’t think they will. It’s easier to be complacent and keep doing the things your comfortable with that have always worked before, especially when you’re surrounded by people who all think the same way you do.

One of Steve Jobs’s favorite songs was “The Times, They Are A’Changing“ by Bob Dylan. I suggest that in the wake of this election we all take a deep look at our society and we stop blaming people who have been telling us for decades that they’re angry but were ignored because we assumed they would all just go away and die. The signs were there, but we didn’t want to see them. We didn’t want to fix things that were broken because they worked good enough, and now we’re facing a reckoning.

Come gather ’round people
Wherever you roam
And admit that the waters
Around you have grown
And accept it that soon
You’ll be drenched to the bone.
If your time to you
Is worth savin’
Then you better start swimmin’
Or you’ll sink like a stone
For the times they are a-changin’.

Primitive Drawing and Assembly in Metal

One of the main reasons I got interested in iOS was because I wanted to learn graphics and audio programming.

I got really interested in OpenGL, but after a year of trying to learn it I wasn’t making any progress.

Anyone who has tried to learn OpenGL have gone through the same frustrating experience I have. You find a tutorial on Ray Wenderlich and you write a bunch of code and at the end you have a spinning multicolored cube. That’s really cool!!

But then you realize that you have absolutely no idea how to do anything else.

For a really long time, I thought that I had to enter all of my vertices by hand because every tutorial I saw had you write your vertices by hand. My brain was scrambled by the idea of trying to create a large, complex 3D model by hand coding the vertices. It’s hard enough coding things with auto complete, what if you miss a value?! Do you have to keep building it and keeping track of the vertices and try to figure out which one needs to be moved when there are a thousand of them?!

Eventually I was told that you import a pattern file into your application, but until the release of Model/IO in iOS 9, you had to write your own parser from scratch to import a file from Blender or Maya.

So I faced an incredible amount of frustration trying to figure out how you get vertices into an application and how they work together to create something. I kept being told that those projects of the spinning cube introduce you to all the things you need to know in order to make OpenGL work, but it was something that was not intuitive.

I am seeing people go through similar frustration while trying to learn Metal. I am hoping to do a series of blog posts over the next few months about aspects of Metal and 3D graphics programming that I don’t feel I have seen explained very well in other places. This stuff is complicated and difficult to explain, so no judgement on anyone who produces technical materials on Metal or OpenGL.

Star Project

I decided to do a project that was slightly more complicated than a triangle or a cube but not as complicated as a 3D pug model. I want to figure out how to explain this stuff in a way that the reader can extrapolate and scale the complexity while still understanding how the fundamental concepts work.

I decided to try and draw a two-dimensional star. It’s slightly more complicated than a triangle but it’s still simple enough for a person to sit down and conceptualize.

Yes, I screwed up the vertex labels at the bottom.

Yes, I screwed up the vertex labels at the bottom.

I really hoped that I could find a simple CAD program to generate a pattern file for my 2D star, but after multiple frustrating conversations with various people, I decided to bite the bullet and just plot out the vertices by hand.

The Metal rendering space is slightly different than what one expects coming from something like Core Graphics. I am used to the idea that the phone has a normalized coordinate space where the height is one unit and the width is one unit.

Metal still utilizes a normalize coordinate space, but it’s two units high and two units wide, so the center of the screen is coordinate (0,0,0). So the upper left corner of the screen is at coordinate (-1, 1, 0). The lower right corner is (1, -1, 0). It’s not complicated to understand, but it’s slightly counterintuitive for someone coming from the idea that everything is a value between 0 and 1.

I created my coordinate space using graph paper. I made each square on the paper worth 0.2 units and made the space ten squares by ten squares.

I understand that because the phone screen is not perfectly square that the star is not going to look like this when it’s finally rendered. One of the things I want to do later is figure out how to constrain the drawing area to be square so that the star renders properly, but that’s a task for a later time.

Writing out vertices by hand like a savage.

Writing out vertices by hand like a savage.

In Metal and OpenGL, shapes are composed of triangles. All the big scary 3D models that make up a Pixar movie are composed of meshes of triangles. Everything can be broken down into triangles.

So let’s think about a star. It’s obvious that the points are composed of triangles, but what about the middle? The middle is a pentagon. This pentagon can be composed of five triangles by drawing out from the center to each of the vertices between the points.

So if you think about how to describe the star to the renderer, you are going to describe ten triangles using eleven vertices. There are five vertices at the points, the five between the points, and finally one in the middle.

Metal Primitives

When you package and pass your vertices to the vertex buffer, you need to describe to the vertex buffer what type of shape it’s drawing. I know I just went off on how everything can be broken down into triangles, but there are a few flavors of shapes you can draw with Metal.

Metal has a enum of Metal Primitive Types. There are five different primitives available to you:

  • Point: Rasterizes a point at each vertex. You have to define a point size in the vertex shader.
  • Line: Rasterizes a line between a pair of vertices. These lines are separate and not connected If there are an odd number, then the last vertex is ignored
  • Line Strip: Rasterizes a line between a bunch of adjacent vertices, resulting in a connected line.
  • Triangle: For every separate set of three vertices, rasterize a triangle. If the number of vertices is not a multiple of three, either one or two vertices is ignored.
  • Triangle Strip: For every three adjacent vertices, rasterize a triangle.

So the easiest way to think about how to describe the star to the vertex shader is to hand enter ten sets of three vertices that describe a triangle.

let vertexData:[Float] =
    [
        // Internal Triangles
        0.0, 0.0, 0.0, 1.0,
        -0.2, 0.2, 0.0, 1.0,
        0.2, 0.2, 0.0, 1.0,
        
        0.0, 0.0, 0.0, 1.0,
        0.2, 0.2, 0.0, 1.0,
        0.3, 0.0, 0.0, 1.0,
        
        0.0, 0.0, 0.0, 1.0,
        0.3, 0.0, 0.0, 1.0,
        0.0, -0.2, 0.0, 1.0,
        
        0.0, 0.0, 0.0, 1.0,
        0.0, -0.2, 0.0, 1.0,
        -0.3, 0.0, 0.0, 1.0,
        
        0.0, 0.0, 0.0, 1.0,
        -0.3, 0.0, 0.0, 1.0,
        -0.2, 0.2, 0.0, 1.0,
        
        // External Triangles
        0.0, 0.6, 0.0, 1.0,
        -0.2, 0.2, 0.0, 1.0,
        0.2, 0.2, 0.0, 1.0,
        
        0.6, 0.2, 0.0, 1.0,
        0.2, 0.2, 0.0, 1.0,
        0.3, 0.0, 0.0, 1.0,
        
        0.6, -0.4, 0.0, 1.0,
        0.0, -0.2, 0.0, 1.0,
        0.3, 0.0, 0.0, 1.0,
        
        -0.6, -0.4, 0.0, 1.0,
        0.0, -0.2, 0.0, 1.0,
        -0.3, 0.0, 0.0, 1.0,
        
        -0.6, 0.2, 0.0, 1.0,
        -0.2, 0.2, 0.0, 1.0,
        -0.3, 0.0, 0.0, 1.0
]

I want my star to be kind of flashy. I would like to set a pseudo-radial gradient on the star where the tips are red, but the middle is white. So I need to set up another array of floats describing the color data as it correlates to the positional data.

let vertexColorData:[Float] =
    [
        // Internal Triangles
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        // External Triangles
        1.0, 0.0, 0.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        1.0, 0.0, 0.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        1.0, 0.0, 0.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        1.0, 0.0, 0.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        
        1.0, 0.0, 0.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, 1.0
]

Over in the view controller, you need to create a buffer to hold the position data and one for the color data for your vertices:

var vertexBuffer: MTLBuffer! = nil
var vertexColorBuffer: MTLBuffer! = nil

Now you need to connect those buffers to the arrays of vertex data. The buffers don’t know how much data they need to store, so you have to calculate how large these vertex arrays are so the buffers know how much space they need to allocate for the vertex data.

let dataSize = vertexData.count * MemoryLayout.size
vertexBuffer = device.makeBuffer(bytes: vertexData, length: dataSize, options: [])
vertexBuffer.label = "vertices"

vertexColorBuffer = device.makeBuffer(bytes: vertexColorData, length: dataSize, options: [])
vertexColorBuffer.label = "colors"

img_5660Since the vertex position and color arrays are the same size, you can reuse the data size variable for both buffers.

At the end of the process, this data is scheduled by the render encoder to be sent to the vertex shader and be processed by the GPU.

renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0)
renderEncoder.setVertexBuffer(vertexColorBuffer, offset:0 , at: 1)
renderEncoder.drawPrimitives(type: .triangle,
                                   vertexStart: 0,
                                   vertexCount: vertexData.count)

Build and run the app on a phone and you get a nice star! Huzzah!

Wrap Up

I created a GitHub repo for this project here. Honestly, most of this project was basically me just using what comes in the template but changing the vertex data.

Looking this over, it seems kind of inefficient. The middle set of triangles feel like they could be a triangle strip. I would like to add a nice outline to the star to make it look nice and neat. I also would like the star to not be morphed by the screen.

I am planning to update this project periodically to make it more efficient and customizable.

At the very least, I hope this adds some understanding to how Metal breaks down larger shapes into triangles and how it’s able to go through and build the shapes back up again.

Refactoring the Blog 2016

This is why you don’t make long term plans, kids. They never work out.

So a few weeks ago I started a blog series on a game that I am making. Then I got derailed by the brief fling with algorithms. I had hoped to get my focus back on completing this game. I haven’t published an app out on the store yet and I really wanted to write a program on my own all the way through to being shipped.

Sadly, this is going to stay on the back burner for a while longer.

I have a new project I am working on that I will announce soon that will be absorbing most of my time and attention.

I don’t like to abandon the blog (and now the podcast) when I have a project I am working on. The last year has been rather sparse during times I have been consumed with projects and I don’t want to do that.

I am going to try to integrate the new project into both the podcast and the blog. The whole point of both of them is to talk about all the new stuff I am learning, so I am hoping to continue to do that with the new project.

I feel bad because I really wanted to hold myself accountable to getting a project completed. I would like to continue to do that and come back to this later.

My understanding is that a lot of people besides me have pet projects and the ruins of previous hobbies fossilizing in their basements.

I need to spend a little bit of time figuring out how to approach integrating my new project into my long term projects.

So, goodbye Godori. I will get back to you eventually. I hope.

Why I am Discontinuing my Algorithms Series

I have spent the last week doing some soul searching and I have decided I am going to discontinue the planned algorithms and data structures series I was going to do on this blog.

My calculation was if I attempted to solve one problem in Cracking the Code interview each day it would take me about six months to get through the whole book. That was before I encountered several road blocks with attempting to implement a custom data structure that was not really intended for this use and required me to greatly extend its functionality.

I made the mistake of reading the beginning of Cracking the Code Interview and to my horror, found a lot of the same things I was saying in my post about the algorithms of discrimination, except they were being touted as features and not bugs.

The author indicated that companies know you probably won’t use algorithms on a day to day basis, but that they’re being used as a proxy to see if you got a computer science degree. They’re assuming if you got a computer science degree you’re a good programmer.

I am a hacker. I love to build things. I love to wander off into unexplored areas of our field to figure out how something works because I enjoy doing it. I love to craft code and make things work. I am fascinated by how to actually grow a complex code base in a way that is sustainable. I am interested in figuring out how to break up a seemingly insurmountable task into pieces that can be accomplished. I am interested in figuring out how to make my code better and I am willing to write absolutely terrible code initially that I know I will go back and fix to get to that point. I am interested in how my user interacts with my code and making sure it’s seamless and intuitive.

I know that not all companies are the same, but my experience of interviewing at companies that use algorithms screening is quite bad. I feel like I am being treated like a criminal whose guilt is assumed and I have to prove my innocence but I don’t get a chance to call a lawyer.

I have never had an interview at a company doing an algorithm screen where anyone has bothered to read my resume. Most of them ask me how they’re supposed to know if I know how to code or not without this screen. Well, I have written books that are published and available. I write about code on this blog. I speak about code at conferences. I post code on GitHub.

A lot of these companies are also ones where they expect relocation. Relocating is a massive deal for me. I have a stable and cheap living situation at the moment. I have parents to watch my second pug while I take the first pug with me to conferences. I have issues with depression and other mental health that are exacerbated by being in urban areas.

If a company is going to demand that I uproot my life, greatly increase my cost of living, and give up the stability of working from the place I feel most comfortable, I want them to not treat me like a criminal. At the very least read my resume. Don’t put me in a situation where I don’t get to speak to an actual human being until I jump through some hoop to prove that I got a computer science degree.

I heard a lot of people telling me that I am shitty developer because I am refusing to spend a few months learning data structures and sorting algorithms.

I disagree.

I feel learning this stuff without context is yak shaving. It’s future engineering. It’s learning something before you need to know it. It’s important to know it is out there, but it is not vital to learn it before you need it. If you spend all your time learning things before you need them, then you won’t build anything.

I learned so much about my code after I started implementing it. I wrote what I thought were solid data structures until I tried to work with them in my code. I found I had underlying assumptions about it that were wrong and I had to go back and add functions and properties to correct for my assumptions.

We like to think that the world can be simplified with algorithms in text books, but they rarely account for the complexity of the real world. You wind up adding bits and pieces to deal with edge cases and your artfully crafted algorithm turns into a house with pieces tacked on. Why not go into it knowing that you’re doing something complex and ugly rather than simple and elegant but imaginary?

There is the argument that I won’t understand how programs work if I don’t learn data structures and algorithms. Again, I disagree.

There are so many things we could use as a proxy for actual engineering knowledge. Why not ask candidates to write things out in assembly language? Why not ask them about computer architecture? Why not ask them how they would break out a large project into smaller pieces? Why not ask them about how they would test their code?

How many people have used a disassembled on their code to look at what the machine is actually doing? I just found out this is something I can do and it’s magical to me. It’s far more interesting to me than memorizing the difference between a bubble sort and a quick sort when I will always just use the sort() function on collection types in Swift anyway.

For whatever reason, this is the thing that we use as a proxy for being a good developer and I am not doing it.

I am interviewing companies and ones that behave like this are ones I don’t want to work for. If this is a small component of a larger hiring process, I am willing to engage in it, but not as a barrier to entry to even get to talk to a human being.

So instead of trying to please large companies and shave all my edges off and submit to conformity, I am going to build things. I am aware that there are algorithms and solutions out there that could make my code cleaner and work better. Once I get something working I will go back and refactor it to resolve many of the issues that I know are there. My understanding was that refactoring was part of being a great developer too. If you disagree with that, then I really hope I am not stuck maintaining your legacy code.

I have faith that if I keep learning and working on cool projects and contributing to the programming community that there is a place for me somewhere. It may not be one of those big companies on the West Coast, but I think the world is big enough to accommodate a lot of different kinds of people.

Code Interview Concepts: Swift Linked List Enhancement

The current project I am working on is to work my way through Cracking the Code Interview creating a Swift implementation of each algorithm and data structure problem listed.

I decided to tackle the Linked List structure first because it was really annoying me how many people told me this was something I MUST learn how to do.

Fortunately the Swift Algorithm Club had an implementation I could look over. I really didn’t see the point in trying to reinvent the wheel, so I figured I could just drag and drop their implementation into a Playground and create a linked list so I could just focus on completing the questions.

(I strongly recommend reading through the tutorial they published recently explaining how to implement this yourself. It’s a great read!)

One issue I encountered was when I attempted to drag and drop the file into a playground. I recently discovered you can have multiple files in Playgrounds and was super excited about it.

I got a compiler error. I looked up the issue and found I needed to import the sources file. No worries. I added it then I got an additional error:

Playground execution failed: error: RemoveDuplicates.playground:8:12: error: 'LinkedList' initializer is inaccessible due to 'internal' protection level
let list = LinkedList()

Huh. That was weird.

I looked over the class and I didn’t see anything that was private. The class and most of the methods were listed as public.

I reached out to the Algorithm Club and they indicated that it was missing a public initializer.

I forked the repository and added a public initializer:

public init() {}

So cool. I should be able to access things now. Huzzah.

I went to go and figure out how to start working on implementing my code questions. The first one talks about iterating through a linked list to remove duplicate values.

I went to start working on this. I realized that there wasn’t a way to simply pass in an already existing data structure to turn into a linked list. I would have to add each node to the linked list one by one.

This seemed like an inconvenience, so I reached out to them again to ask if there was an easier way to do this. They helpfully suggested that I add an extension to the linked list class to let me do this.

Because they did such a great job setting up the class, creating an extension to do this was pretty easy:

extension LinkedList {
  public convenience init(array: Array) {
    self.init()
        
    for element in array {
      self.append(element)
    }
  }
}

I wanted to make sure this actually worked and would be this easy, so I created a test case in their Playground for the Linked List:

let fibonacci = [1, 1, 2, 3, 5, 8,]
let arrayList = LinkedList(array: fibonacci)
print(arrayList)

I forked the repository and submitted this as a pull request.

Conclusion

I really wanted to do an algorithms post every day. I am glad I was able to do one today. It was frustrating to encounter some road blocks, but it was incredibly awesome that the Algorithm Club was around to answer my questions and that I am able to contribute some enhancements to this to make it more useful.

It’s also nice that I was able to use this in a project and find things that were not considered by the original creators and to be able to make it more useful.

Even though I didn’t get to work on my problem set for the evening, it was nice to have a team to work with to solve a problem with code. That’s what I like about programming and I don’t get to do this as much as I would like.

Code Interview Concepts: Linked Lists Overview

This is a new series of posts of me going out and learning common data structures and algorithms that you are asked to implement in code interviews. I am not writing this series of posts because I have gone to the Dark Side. I still think this is stupid, but I care about trying to help self-taught people navigate the waters of finding employment and sadly this is a hoop people have to jump through.

I want to give people resources and to also try to give them hope that if they learn this one last thing they can break through the bureaucratic walls keeping them out. I don’t want them to give up or feel like there is an endless number of things they are required to do. We all know this sucks and it’s bullshit. If you bomb one interview, remember what you were asked, study hard, and keep trying.

Figured since I complained so much about this stupid thing, I may as well start with it.

Honestly, if you want the best explanation of this data structure, check out the explanation in the Swift Algorithm Club repository. I have had a lot of people helpfully suggest I read Wayne Bishop’s book, but I honestly think that Ray’s Algorithm Club is a better resource and it has the additional benefit of being free.

The value in a set of posts like this will be seen later. There are lists of sample questions asked during code interviews that use data structures and algorithms to solve problems. I am going to generate posts going over these common problems and try to show how they can be done in Swift.

I am not writing up this series of posts as a resource for other people, but it could still be of some use for someone. I am writing this up because the best way that I have to be engaged with learning something is to attempt to explain it to someone else in a coherent manner.

Overview

A linked list is simply a series of items that connect to one another. A singly linked list goes only one way. A doubly linked list points both backwards and forwards.

led_strips_strip-direction

If you look at the image of the NeoPixel strip, this kind of illustrates the idea of how a linked list might work. Each pixel is wired in and connected to the ones around it. The data flows in one direction. You can’t skip one pixel to get to the next one. The color starts with the head of the strip and is passed through to each of the pixels in series. Every pixel has a pixel it receives data from and one that it passes data to. It’s like the game Telephone from when you were a kid.

Linked List vs Array

Arrays are faster than linked lists, but they are less flexible than linked lists. Linked lists are not indexed like arrays, so in order to navigate to a node in a linked list, you have to iterate all the way through the list to get where you want to. This means if you want to add things to a linked list, you should add it towards the beginning of the list to make sure you can get to it faster.

Pointers

Linked lists use pointers to elements rather than indexing. This is one reason that this data structure makes me crazy.

One of the big reasons I am grudgingly doing this series of posts is because I know we got to the point a while ago where basically all languages were based on concepts from C. One reason we are asked about linked lists is to prove that we understand the concept of pointers.

Except Swift is a hybrid functional language.

Swift has to work with C and Objective-C and has unsafe mutable pointers, but you’re not really supposed to implement them directly in production Swift. Yes, you can force the issue and use things like pointers when you don’t have to, but that’s really bad programming.

Another reason I am grudgingly doing this is because I want to gain a better understanding of which these fundamental data structures honestly don’t work well with things like Swift. I would argue that creating a data structure based on pointers in Swift is a bad implementation decision. There are probably ways around using pointers, but why bother implementing something like this then?

Should You Implement This in Production Code?

No. There are a lot of other better ways to do this stuff. This is a really simple thing to implement, which is one reason this stupid question gets asked a lot.

Swift 3 Linked List

Here is a brief overview of the code put out by the Swift Algorithm Club:

public class LinkedListNode {
  var value: T
  var next: LinkedListNode?
  weak var previous: LinkedListNode?
  
  public init(value: T) {
    self.value = value
  }
}

public class LinkedList {
  public typealias Node = LinkedListNode
  
  fileprivate var head: Node?
  
  public var isEmpty: Bool {
    return head == nil
  }
  
  public var first: Node? {
    return head
  }
  
  public var last: Node? {
    if var node = head {
      while case let next? = node.next {
        node = next
      }
      return node
    } else {
      return nil
    }
  }
  
  public var count: Int {
    if var node = head {
      var c = 1
      while case let next? = node.next {
        node = next
        c += 1
      }
      return c
    } else {
      return 0
    }
  }

I am impressed that The Algorithm Club created an implementation of a linked list without throwing around mutable unsafe pointers. Their implementation can be found here. I will be using this as the basis for the answers I will be implementing from Cracking the Code Interview in future posts.

There is a lot more code in their implementation and I highly recommend looking it over if you need to use this in a code interview.

Conclusion

I don’t really know what else to say about this. Someone else created a really good implementation of this and I don’t see the point in reinventing the wheel. I think the value in this will be in the future posts when I explore some of the common problems people ask you to do in order to show your understanding of this data structure.

Again, I am trying to make information available rather than trying to show how clever I am for coming up with things. If I can find a good solution someone else has implemented I am happy to use it.

Super Mario Brothers

I have written on here before that I did not get to play video games as a kid. The closest I got to a Nintendo was watching my daycare owner’s kids playing Super Mario Brothers on the NES from the couch because I never got to join them.

When I watched them play, they knew where all the hidden shortcuts were. They knew to jump in certain places to hit invisible boxes and to travel over the side of a wall to get to a pipe that allows them to skip a bunch of levels.

I wondered as a kid how they found all these short cuts. I realized at a certain point that someone else showed them. Someone created a guide that talked about where all the easter eggs were and people either found them through reading that guide or watching someone else play.

There are speed records where someone can get all the way through the game from beginning to end in just over five minutes. It became a thing to try to get through the game as fast as possible.

As a kid I didn’t really understand that. I thought the point of the game was to play the game. I was told by people rolling their eyes that the point of the game was to beat the game.

I wrote a post yesterday talking about my being upset about the algorithm questions that are asked at programming interviews.

I have gotten a lot of push back on this.

I have been accused of being incompetent and not being a real programmer. I am confronted by people who are angry with me for not just accepting that if I read an algorithms and data structures book that I will be a better programmer.

I feel I am being misunderstood.

I feel like a a lot of people telling me this are like the people who I watched playing Super Mario Brothers as a kid. I think that they have been told there is some bible of short cuts that get you through the game faster. They don’t look around on their own or explore the game. They’ve been given a set of instructions that gets them through the game faster and they can’t comprehend why someone would not take a short cut that they know is there.

The impression I am getting from people is that they are blindly accepting that these are strict rules that we are supposed to follow and if we don’t follow them then we’re ignorant and wrong.

I think about all of the levels that the game designers created that no one ever looks at because everyone is in such a hurry to get to the end and beat the game.

I don’t care about beating the game.

I care about playing the game.

I don’t want to accept that there is only one way to be a programmer. I like to find things out for myself. I want to explore more than one way to do things. I don’t want someone telling me my code is wrong because it’s not the way they would do it because they only know one “right” way. I think there are a lot of right ways.

I did not mean to imply there was no point in learning algorithms. I am sure they have their place. I’m sure the right algorithm in the right place would completely change the way I think about my code. It’s just that over the last two years I have seen so many people implement lots of terrible code that they think is “best” because they read in a book somewhere that things have to be a certain way.

I had someone try to create a protocol around a class that would never be subclassed because it’s what he thought Apple wanted him to do because he didn’t think critically about how to use polymorphism properly. I have had people suggest I simplify my code by doubling the code base and add three or four data structures to get around using an if statement.

Singletons are evil. React is evil. JavaScript is evil. Use MVVMMVVMMVMVC. Emacs over Vim!

There was a lot of push back against Swift when it first came out because it was different. People lashed out at it because it was not what they were expecting or familiar with.

I feel like sometimes we over-engineer things instead of looking for simple solutions. We think we have to place a thing in another thing and guard against the possibility that someone in the future will do. We have to force a tool to act like another tool in order to conform to some protocol rather than using it how it’s supposed to be used. We want everything to be one size fits all because it makes life easier to think that way.

Right now I am trying to see if a simple solution will work for me before I implement a more complex one. I don’t want to just blindly apply something because a stranger on the Internet tells me to.

Just reading an algorithms book doesn’t make you a good programmer. Understanding a problem and when to implement the right algorithm makes you a programmer.

I want to figure that out for myself rather than having a bunch of people talk down to me about how I can beat the game in five minutes. I am actively refactoring my code to implement better solutions, but I don’t want that to be my first step. I want to screw up and do stupid shit so I can learn from it and figure out how to do it better. Sometimes when you think you know all the answers you don’t look for new ones and if you’re not learning anything new then what’s the point?

I’m sorry for people misunderstanding my desire to figure things out for myself as being willfully ignorant or contemptuous for good software development. You learn more from your own mistakes than you do from other people’s. The last time I checked, thinking for yourself was still allowed. I don’t care if you hate me, or think I am wrong or ignorant or stupid. I am entitled to my own reality and you are too.

The Algorithms of Discrimination

This is a cross post between this blog and my podcast. I realized that this blog has more reach than the podcast does because it’s new, so I am posting the script from that podcast here.

Transcript

This is a special episode of Janie Rants.

I have been asked a lot of questions about a series of tweets I posted on Twitter last night. In these tweets, I said that this was the first time I felt like I was unwelcome in the iOS programming community.

Like many things on the internet, this is a long and complicated story and it was not really conducive to the short format and tempers of Twitter, so I will try to do my best to explain myself here.

At the moment I am between jobs and I am trying to figure out how to proceed. I am trying to see if I can make it as a contractor but I have also been looking into obtaining regular work as well.

I posted a blog post a few weeks ago about an experience I had interviewing at a rather large and well known company that had a white board interview where I was being asked to implement a linked list in Java.

I expressed that I felt this was a useless task.

I got a lot of pushback from people on Twitter about this. A lot of older programmers chastised me that you can’t be a great programmer if you don’t understand data structures and algorithms. I tried to make the point that if you are an iOS developer that most of your job is to have knowledge of the iOS frameworks and that the language is secondary. Someone who had never owned a Mac or opened Xcode could theoretically get a job as an iOS developer.

I continued to get pushback about the absolute importance of algorithms and how someone implemented a linked list once in their career. I asked whether it was more important to be able to answer a question about something you might do once in ten years or about something you would use every single day. I don’t think I got a response to that.

I did a phone screen where I was once again told that the tech aspect of the screen involved doing an algorithm test. I expressed frustration on Facebook about once again being asked to do an algorithm test for an iOS position.

One person on there told me if I spent all the time I used complaining about algorithms to actually learning them I would know them by now. He also criticized me for not being willing to implement well known algorithms and structures that are simply not part of the Swift Standard Library. This hurt my feelings because this was a person I considered a friend.

Another person made the comment that really prompted my series of tweets last night. He said that he asked algorithm questions because he wanted to make sure he worked with the “right” people who has the “right” skills and could talk “his” language.

I know that to most of you listening out there, you probably hear that and don’t give it a second thought. Let me decode this for you.

Algorithm questions are not a way to make sure you’re hiring someone who is capable of coding. Algorithm questions are a way to discriminate against certain kinds of people.

I know, you think I am paranoid. You think this is some kind of conspiracy theory or that I am somehow claiming sexism because I am a bad programmer or I am too lazy to learn these things. Please hear me out.

My first experience learning programming was from Code Cademy online. I accepted a terrible job that my ex-husband would not let me quit where our team lead did not know what we were supposed to be doing, so he told everyone to pretend to work and to look busy.

To keep the suicidal thoughts at bay, I went on Code Cademy to learn programming. I had taken some programming classes, but had only coded things once and subsequently never practiced it enough to understand it.

I discovered that if I wrote code forty hours a week that I could learn programming. I could type code as easily as I type an email and the logic finally made sense. This was a revelation to me. I had given up on programming because I thought it was too hard and I could never learn it. I found that if I put in enough time and effort I could learn how to code.

I got myself fired from that job and went on unemployment. In the state of Wisconsin, if you’re on unemployment you can stay on it as long as you’re going to school to learn a trade. I re-enrolled at the local tech college and started taking iOS classes to learn iPhone programming.

A lot of people learn programming from sites like Ray Wenderlich or from the Big Nerd Ranch books. Lots of people spend thousands of dollars going to code bootcamps.

President Obama has talked about how he wants all kids to know how to code. Apple has added Swift Playgrounds to the iPad to teach kids to code. We’re inundated with messages everywhere that learning programming will lead to a better life. We’ll get better jobs and earn more money and be able to start companies.

None of these paths to programming include algorithms or data structures.

I spent two years trying to scrape up enough iOS experience to be able to get an entry level job. It was brutal learning Objective-C. It was brutal learning about the Model View Controller design pattern. Asynchronous closures. Memory management.

iOS is not a simple framework to learn. There are a lot of moving parts and there is a tremendous barrier to entry to get to a point where you have accumulated enough experience of working with the frameworks and the devices and the compilers to be able to be somewhat proficient with iOS.

So why the fuck do we quiz people of fucking algorithms?

We do that to keep people like me out.

If you have a six week coding boot camp, you’re going to teach people the bare minimum that they need to make something useful. You’re not going to spend weeks talking about data structures and algorithms.

The only people who know about data structures and algorithms are people who got computer science degrees or have been around for so long that they learned it on their own.

This discriminatory practice is written off as a meritocracy. Anyone can learn this stuff if they’re ambitious and smart, so it’s the standard against which all people are held.

Let me tell you about another standard we don’t think about: The SATs.

We think of the SATs as being fair. Everyone receives the same test. Everyone has the same time limit. Everyone has the same equipment. It’s fair, right.

Nope.

If you come from an upper middle class family, you probably had some help with the SATs. I went to a private Catholic high school that specialized in college prep. My parents bought me books that helped me figure out how to get better scores on the SATs. I had practice tests I could take with instructions about what the right answer was and why. It explained to me how to see a trick question and gave me strategies for getting around them.

Both of my parents had college degrees and were in education. It was expected that I would go to college. I didn’t have to have a job because my parents paid for my college, so all I had to do when I was in high school was study. When I didn’t like the score I got on the first test, I took it again. I could take the test as many times as I wanted and each time I took it my score got better because I got practice.

I can stand by my scores and talk about how I earned them through hard work and how the system is a meritocracy because I did marginally better than a few other people with the same privilege I had. But that’s not a complete story.

Take a student living in a poor community in Mississippi. This student might go to a school where they teach creationism instead of evolution. This student has no expectation of ever going to college. This student doesn’t know that there are resources out there to help them do better on the test. They don’t know about the trick questions. Their school doesn’t offer algebra because no one would take it anyway.

Does the test honestly reflect this person’s potential?

This theoretical person could be a genius. But they don’t have the cultural context to know what they are supposed to do in order to move from the sphere they are now to the better one brought by money and education.

I know so many of my classmates from my school who have trouble finding jobs. There are so many road blocks that are set up to keep the wrong people out. You have to have a GitHub repository and a Stack Overflow account with a certain amount of points. You have to contribute to open source. You have to present at meet ups.

We create so many barriers to entry for people who are culturally unfamiliar with what the community expects and we set these up to keep people out. We like to feel like we’ve earned our place in the community and we don’t want to deal with helping more people enter that we have to compete with.

Knowing algorithms and data structures means that you were privileged enough to get a computer science degree. It means you had enough free time that you learned this stuff on your own if you’re self taught. This assumes you have the money to take time off to learn something that will help you get better jobs.

If you’re struggling to make ends meet because you’re a single parent who can’t get past the velvet ropes to the land of coding opportunity, you do not have time to learn these things. You are told you’re not welcome and you give up.

None of this would bother me so much were it not for how completely useless this exercise is. Yes, knowing data structures and algorithms makes you a better programmer at some point, but if you’re interviewing someone for a job doing iOS development, there are so many other things that are iOS specific that no one ever asks about because for the most part these places don’t know them. You’re getting interviewed by people who don’t know anything about what we do who for some reason are in charge of determining whether you understand things or not. It’s bullshit.

The people who have the privilege to get through this red tape just kind of shrug and accept it’s a necessary evil. Some of them even embrace it and will fight with you tooth and nail about why it’s important for someone to know something they haven’t used in five years.

Yes, I could go and learn algorithms and data structures. I am holding my nose and accepting that this is probably something I must do in order to get better jobs, but that doesn’t mean that I should endorse them because I have the privilege of being able to take a few months off of work to learn something that’s nearly completely useless.

By filtering out anyone who comes from a non-traditional background, we’re ensuring a monoculture in programming. We want diversity, but only if the people we bring in think the same way we do. That’s not true diversity.

We need people who never went to college. We need people who learned by hacking and being tenacious and getting something working. We need people who come from diverse backgrounds who can bring new perspectives to what we do so that we can use technology to make people’s lives better and not just find more invasive ways to gather user data for targeted marketing.

Over the last year I have not felt that this community values those voices anymore. I went into iOS over web and Java because I felt that this community was welcoming to anyone with a curious mind and drive to do better and based on the responses I am getting from people I don’t feel that way anymore. I want there to be opportunity out there for people who are like I was four years ago. In order for that to happen, we need to change how we do our hiring practices or we’re all going to be poorer for it.

Thank you.