Added By: Feedage Forager Feedage Grade B rated
Language: English
app  apps  can’t  code  don’t  it’s  i’m  make  new  people  thing  things  time  vesper  web app  web  work   
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics

Brent Simmons’s weblog.


Dash and Apple’s Statement

Mon, 10 Oct 2016 15:01:43 -07002016-10-10T15:01:43-07:00

Apple states that nearly 1,000 fraudulent reviews were detected — and that they’d given the developer notice and had tried to resolve the issue with him.

If this is true, then it would be hard to say that Apple has done anything wrong. In fact, we want Apple to notice fraudulent reviews (since they harm consumers and other developers), get them removed, and work things out with the developer.

I don’t know what’s true here. It wouldn’t be right for Apple to make all the evidence public, and it wouldn’t be right for Apple to publish their correspondence with him. So it’s likely we won’t ever know more than we do right now.

Apple’s statement is consistent with Apple’s doing the right thing, though. There’s a very good chance that they are.

While Apple’s culture of opacity continues to bother me — enough so that I won’t put any of my own apps on an app store — I can’t say for sure that this is a case where they’ve mistreated a developer.

Apple’s Judicial System

Thu, 06 Oct 2016 12:09:44 -07002016-10-06T12:09:44-07:00

(Update Oct. 10: see Dash and Apple’s statement.)

Apple has a judicial system — that is, they have a system where they make judgments and enforce penalties. It’s not a criminal judicial system, and so the state and federal laws that govern that system don’t apply.

Apple is allowed to run this system however they want to. And we can’t see in, so we don’t know how it runs.

But we have learned — in the case of Dash — that one of the features of the system is that Apple may accuse a developer of fraud, not provide any evidence to the developer, and then remove that developer’s apps, with no appeal allowed.

While this is legal, and within Apple’s rights, it’s not what we’ve come to expect from a moral judicial system. No matter what the context, we expect that the accused see the evidence against them, we expect avenues for appeal to be made available, and we expect proportional penalties.

Otherwise, here’s what happens: if you’re well-known enough and have a good app, other people will raise a fuss on Twitter and on blogs and possibly in the press, and maybe something will happen. Maybe.

That sucks. That’s a middle-ages way of handling things.

Apple is allowed to run it that way, if they want to. Of course. They own it.

But any adult would expect the same basic morality that people accused of crimes get: that is, again, the right to see the evidence against them, an avenue of appeal, and proportional penalties.

In the meantime, it’s our job to presume innocence in the absence of evidence. This is also a moral issue, and it’s true even if you’ve never heard of the developer.

Open Floor Plans

Thu, 06 Oct 2016 10:09:01 -07002016-10-06T10:09:01-07:00

I don’t know if it’s true that Apple’s new campus will be mostly open floors with few offices. But it is true that I could never work without my own office.

Like almost everybody at Omni, I have my own office. We also have lounges with chairs and sofas, and some people work in the lounges some or all of the time. Everyone’s different.

Here’s why I work in an office: when I’m around other people — it doesn’t matter who they are — I feel a constant low-simmering level of anxiety. And I find it extremely difficult to be productive when I feel any level of anxiety at all.

I’m a nerd, and this is something a good number of nerds put up with. It doesn’t go away over time.

When people who decide on workspaces for programmers don’t understand this, I wonder if they understand programmers.

[Sound Off] Childcare at AffectConf 2016

Mon, 03 Oct 2016 14:11:07 -07002016-10-03T14:11:07-07:00

Sound Off is raising money for childcare at Affect, a new conference in Portland. The goal is to pay for two childcare providers by raising $2400.

Here’s the thing: everybody who wants to should be able to go to conferences. Everybody should be able to learn things, meet new people, and help other people.

Just because you have a child who needs care shouldn’t disqualify you. Simple as that.

Affect is a “2-day event about the work, culture, and design of social change.”

Memory Graph Debugger Tips

Thu, 22 Sep 2016 13:38:42 -07002016-09-22T13:38:42-07:00

I’ve been using Xcode’s new memory graph debugger for just about a day, so I don’t have a ton to share here, but I do have a few things.

  • To start, hit the rotated Sleestak-fingers button in the debugger. It’s between the Cyberman button (view debugger) and paper airplane (location simulator). In other words: it’s not in Instruments. It’s in Xcode.

  • Turn off zombies. If your scheme has zombies on, you’re going to get a bunch of extra noise. (Tip: keep zombies off in general until you need them.)

  • Turn on Malloc Stack Logging in Diagnostics in your scheme. (I think I have it right that this needs to be on in order for the memory graph debugger to show backtraces.)

  • Open the right-hand sidebar in Xcode. Clicking on an object shows its class, hierarchy, and backtrace.

  • Lines between objects have a label. A line represents a reference. Click on the label to see if the reference is strong or weak or unknown and what the source and destination are.

  • Don’t click on anything where the name looks something like MagicOb (something like that). It crashes Xcode for me every time.

  • Click on the circle-with-double-arrows to expand a tree. To unexpand, click again in that same spot. (The arrows point inward now instead of outward.) However, there’s a bug where sometimes this disappears. Select something else in the left-hand sidebar and then come back, and the collapse arrows should appear.

  • In the left-hand sidebar, look for the purple icon with the ! inside. These indicate possible problems.

  • However, most problems aren’t detected. It’s up to you go through and see what’s hanging around that should not be.

I’ve fixed two bugs using the memory graph debugger, and I saved a bunch of time in both occasions. It’s probably worth telling about them as a reminder of the kinds of problems you can run into.

Notification block

An NSNotification observer was set up using a block — which is something I myself don’t do, since it litters an init or viewDidLoad with extraneous code and since it’s dangerous.

It’s dangerous because, unless you remember to be careful, it can capture a strong reference to self, and then that object is never going to go away. I don’t like APIs that require the developer to remember extra things like this.

And, sure enough, this was one of those cases.

The tipoff was in the memory graph debugger: the reference was labelled as “capture,” which let me know there was a block doing a capture, and it was then pretty quick to find out where.

(See also, from 2015: How Not to Crash #3: NSNotification.)

View controller / view retain cycle

There’s a general rule of programming that says objects should know about their children but not about their parents.

However, sometimes a view needs to know about its view controller. This is less than ideal, but sometimes it’s the least-bad option. (Well… I’m skeptical — but it happens, and we ship great apps, so there ya go.)

The related rule of programming says that if a child knows about its parent, it still can’t hold a strong reference to its parent.

That’s what was happening here: a view was retaining its view controller. The simple fix was to make that a weak property.

And, again, the memory graph debugger took me right to this. I could see what was happening inside the app in a way I never could before.

It’s marvelous. You should use it.

Make It Seem Like Nothing

Tue, 20 Sep 2016 09:18:08 -07002016-09-20T09:18:08-07:00

Adam Rush interviewed me for

Adam asks me about public speaking, and I reply that I have the goal of “making it seem like nothing, as if I just got up and started talking to you” — which is more of a peek into my head than it sounds like.

I remind myself to make it seem like nothing many times per day. Not just with public speaking but especially with writing words and apps.

I think I mean a few different things by that. Don’t be show-offy. Don’t be self-conscious. Don’t do fancy or clever things just because I can. Make it look easy and effortless.

I don’t claim that I succeed at all this — just that that’s my aesthetic mantra.

Super Time on Supertop

Mon, 19 Sep 2016 14:26:19 -07002016-09-19T14:26:19-07:00

I was a guest on the Supertop podcast a couple weeks ago, and I spaced on linking to it.

Here’s the podcast. It’s made by the fine folks who make Unread and Castro. (I’m an Unread user. It’s in my iPhone’s dock, even.)

(I’d check out Castro except that I actually don’t listen to podcasts on my iPhone. I listen to them at work via my iTunes on my Mac. Which is dreadfully weird of me, I know.)

The Cool Kids Psychosis

Fri, 16 Sep 2016 10:21:32 -07002016-09-16T10:21:32-07:00

One way to explain Donald Trump is to think of him as a fourth-grader who desperately wants the approval of the cool kids. He wants to be in their club.

And then, when he feels like he doesn’t get that approval and respect and an invitation to join in — whether the club is Manhattan society, the billionaire’s club, the serious politicians club — he feels like that approval has been withheld unfairly. The cool kids have it rigged against him.

Well, in the face of that unfairness, retaliation against the cool kids by any means necessary — any bullshit and lies whatsoever — is completely justified. They’re evil, and he’s better than them, and whatever it takes to prove that is within bounds.

(One well-trodden route here is the populist option, as if to say, “Those cool kids all think they’re cool, but real people know better. They know I’m the cool one.”)

Children do this sometimes, and it’s awful, and they learn and they grow up.

When adults do it, it’s because they’re psychos.

Secret Project Diary #4: MUM

Mon, 12 Sep 2016 13:53:39 -07002016-09-12T13:53:39-07:00

Some random notes on my secret project Mac app… * * * It’s very close to what I call the Minimally Usable Milestone (MUM). That doesn’t mean all the features are all there — or even that they’re all designed — but that you could use the app for its main purpose, if you don’t mind all the unfinished parts. This is pretty exciting for me. What this means is that the app has good bones, and now it’s a matter of implementing commands, doing some side windows, that kind of thing. It’s still a ton of work, but it’s rewarding in a specific way: every bit of progress is something I can see and use. Up until now it’s mostly been programming-by-faith. The app has taken a long time to get to this point for a few reasons. One is that I was working on two apps at the same time. I realized that it wasn’t realistic to do two — so I picked the one I wanted to do the most. Another is that I work in bits and pieces — 15 minutes here and there, and when I’m lucky a few hours in a row on the weekend. As long as the work is steady I don’t lose context — and even 15 minutes a day adds up after a while (especially as you consider that some of the work is thinking work that happens in the shower, on the bus, and so on). A third is that I have the luxury of shipping whenever, which means my process goes like this: write the code to understand the problem, then write it again now that I understand it. It’s not fast, but I do it this way because it’s super-important to me that I don’t have to do major surgery later. The bones, the foundation of the app, should need only minimal attention after 1.0. * * * I don’t know when the beta will be. I don’t know if it will be public or not. But it won’t go into beta until 1) there are no known crashing bugs, 2) there are no known bugs, and 3) it’s fast. (Of those three, the hard one is really #2.) However, there will be testers who see it before it hits beta. I like early feedback. But even that is still a ways away. * * * All of the code at the app level is in Swift. There are about 10 frameworks (modules) that the app uses: some could conceivably be used in other apps, and others are app-specific. The oldest of these still has a bunch of Objective-C code, while newer modules are in Swift. It’s rare that I write a new line of Objective-C. I like not just writing modular code but actually enforcing that by using actual modules. Though some modules may depend on lower-level modules, they’re each otherwise self-contained, with their own tests and so on. I like to be able to focus: I select the module in that popup in the Xcode toolbar, and then just work on it and forget about everything else. * * * I’ve found a simple organization pattern that I like for my Swift code. Properties at the top. Init methods Public or internal methods. Then a private extension. The public/internal methods can see into the extension, but nothing else can. (This way I never have to mark an individual func as private.) I also make heavy use of // MARK: Whatever for organization. I do not make separate extensions for protocol conformance methods. I tried it and it felt too busy. Instead I just have public/internal and then the private extension. I also mark things as final all the damn time. Subclasses are the devil’s classes. I’m a big fan of protocol-oriented-programming. And: my methods tend to be small. This is probably a function of my available time — I break things into smaller chunks, because I only have time for a small chunk. It’s probably also a function of my having to enlarge my font size in Xcode. Something in my brain responds to the actual physical on-screen size and not the number of lines of code. * * * I keep the app to-do list in OmniOutliner (which I work on at my day job), since app to-do lists are hie[...]

Adding a Notification Observer in Swift Using a Name Defined in Objective-C

Thu, 08 Sep 2016 09:38:28 -07002016-09-08T09:38:28-07:00

I spent hours on this. This post exists for anybody Googling this particular problem.

Here’s the issue: I have a mixed Objective-C and Swift app.

I have a Swift class that needs to observe a Notification (aka NSNotification) posted in Objective-C code. The notification name is defined in a .h and .m file:


extern NSString *SomethingHappenedNotification;


NSString *SomethingHappenedNotification = @"SomethingHappenedNotification";

In Swift I tried a number of permutations, trying to get the notification name correct, including using Notification.Name​(rawValue: SomethingHappenedNotification) and similar. Each try resulted in a compile error.

The answer came from Tim Ekl (privately) and Jordan Rose (on Twitter) independently at the same time:

Ah, the word "Notification" is stripped from the name as redundant, so it becomes Notification .Name.Some (or just .Some).

In other words, the syntax for adding an observer looks like this:

NotificationCenter.default.addObserver(self, selector: #selector(someSelector(_:)), name: .SomethingHappened, object: nil)

Note that the Objective-C name SomethingHappenedNotification becomes just .SomethingHappened in Swift, and it’s automatically a Notification.Name.

It seems obvious now! But it wasn’t (at least for me). So: if I saved you some time today, then go be nice to somebody. :)

The Lonely Person

Wed, 31 Aug 2016 11:14:01 -07002016-08-31T11:14:01-07:00

When I was a kid, one adult said to me about another adult: “It must be so lonely to be the only person who’s right all the time.”

To me, then and now, this sounded like a devastating put-down.

This made me think about the importance of being right. Everyone likes to be right, I suppose — it’s human nature. But it made me question something I hadn’t thought to question: how important is it, really, to be right?

Is it more important than being kind? Is it more important than working hard? Or learning? Or listening? Or enjoying the company of other people?

I concluded that being right is not only less important than a whole bunch of other things, it actually gets in the way of other more important things.

Vesper Sync Shutdown Tonight, Open Source Plans

Tue, 30 Aug 2016 09:44:52 -07002016-08-30T09:44:52-07:00

Sync Shutdown Tonight

We will turn off Vesper’s syncing service tonight at 8pm Pacific. Though syncing will stop working, other things won’t.

  • Data is stored on your device. The app will continue to work even without syncing. You can continue to use the app.

  • You can still export your data. As many times as you want. The Export feature works with the data on your device — it has nothing to do with syncing.

  • We plan to remove the app from the App Store Sept. 15, but you can continue to use the app even after that. The Export feature will continue to work after that.

I think that covers everything, but I may update this post if we find people asking questions that haven’t been covered by the above.

Open Source Plans

We plan to do all of the below by the end of 2016, but we can’t make promises. (Life may intervene.)

Q Branch’s existing open source code — DB5 and QSKit — will be moved to my personal GitHub account. I will continue to maintain DB5 (I continue to use it). QSKit will not be maintained, but will be made available as historical artifact.

We will make Vesper for iOS, Vesper for Mac, and Vesper’s JavaScript sync service open source on my personal GitHub account. This code will also be provided as historical artifacts: they’re not intended as active projects. They’re also not intended as examples of how to write apps these days.

The licenses will be public domain or something roughly as non-restrictive. However: the name Vesper and the app icon remain the property of me, Dave, and John. If you build anything based on this code, you must pick a different name and different app icon.

Other notes:

  • Before being posted, Vesper for iOS will be revised so that it uses the default system font, since we can’t ship Ideal Sans as part of this. I’ll probably also adopt Dynamic Type as part of this work. (Since it’s the right thing to do.)

  • Vesper for Mac is most definitely incomplete.

  • The syncing backend runs on Azure Mobile Services, which is Node plus a bunch of goodies. It’s not something you can just upload and run anywhere — but the code might still be useful to look at.

  • In Vesper there is good code and bad code and so-so code. Part of the fun of this will be me writing blog posts ripping apart the bad code. You have no idea how much I’m looking forward to that. :)

On Beta Testing

Sat, 27 Aug 2016 11:35:58 -07002016-08-27T11:35:58-07:00

Craig Hockenberry tweets: Something that hasn’t been written about Vesper: it had the best beta test I’ve ever been a part of. We used Glassboard, which worked very nicely for discussion. I knew it would work because we had used Glassboard to beta-test Glassboard. The greatest beta testing group I’ve ever been a part of was the NetNewsWire beta mailing list. It was a discussion mailing list originally hosted at (which breaks my heart to remember), and later at It had a couple dozen pretty active people and a few dozen more who didn’t post quite as often. What I would do is post super-early builds — not even betas, not even alphas, but development builds right off my machine — and we’d talk over everything. Not just bugs but every detail large and small, every idea, every feature request, every aspect of design and behavior. Even though NetNewsWire was my thing, it was very much a collaboration with a great bunch of people. That collaboration played a major role in the quality and success of the app. I’ve thanked those people and thank them again. From the outside it may not have looked like it, but development of NetNewsWire was always a very social experience. (Same with MarsEdit.) And the thing I miss most about NetNewsWire is that mailing list. * * * This style of beta testing isn’t something I just accidentally fell into. It came from the mid-’90s. UserLand had just released Frontier’s free “Aretha” version, and there was a mailing list for people using Aretha. I’d never been a part of anything like that. There were all these people talking about everything about the app. It was collegial and interesting and fun — and Dave Winer, the developer, was so open about everything, and he listened. It seemed like a miracle to me that such a thing could exist. I loved it. I’d been waiting all my life for such a thing, for a community like this. I threw myself into it, then ended up working with Dave informally on some small projects, and later took a job at UserLand (which was my dream job, for sure). (Another great mailing list at the time was Chuck Shotton’s list for MacHTTP, later named WebSTAR. I was an enthusiastic, though not at all accomplished, developer of WebSTAR plugins. I made $0 on my plugins! But I loved writing them.) When my time at UserLand ended in 2002, and I started working on NetNewsWire, one of the first things I did was start a new mailing list, and some of my friends from the Frontier community joined me on the NetNewsWire list, and they formed the seed and the backbone of the NetNewsWire mailing list. It might seem funny to think of beta lists as having children and grandchildren, but the NetNewsWire list was very much the child of the Frontier list, and the Glassboard and Vesper lists were the grandchildren. * * * Anyway: that’s how you do beta testing. Get good people and let them talk things over. And listen. * * * One of the rules I’ve used — which I probably got from Dave — is not to argue with “I bet lots of people are like me and want feature X,” but instead say why you specifically want feature X, or why you’d prefer some behavior or design change. In other words: instead of just asserting that a thing would be better or more popular if done a different way, tell a story with details. Maybe that’s not right for every beta test, but that’s what works for me. I like stories. A single person can convince me with a good story. Voting is not necessary or desired.[...]

Why Vesper Didn’t Start as a Web App

Thu, 25 Aug 2016 11:29:49 -07002016-08-25T11:29:49-07:00

Some people — people I respect — have asked why we didn’t make Vesper a web app from the start.

Or: why not make it a web app now? Surely it would be cheaper to run, and you wouldn’t have to worry about syncing or about keeping up with changes to iOS.

Well, we did want to do a web app. We worked with Alex King, who got pretty far along on the design. In those days there was no Apple-provided syncing system with web services (there is now), so we wrote our own sync system in part because we wanted to make a web app.

And: all three of us love the web. We have blogs and podcasts and videos on the web. My longest-running “product” is this very site — it’s 17 years old, and of everything I’ve ever done it’s the thing I’m most proud of.

But we didn’t get together to make web apps. We love making iOS and Mac apps, and we don’t love making web apps. We’d do it, but it’s not our passion. (Well, we would have had Alex King’s team do it, actually.)

There’s a difference between loving the web and loving making web apps.

Way back in 2002 I wrote Why I Develop for Mac OS X — it’s because of what Joel Spolsky called an “emotional appeal.” I wrote:

But to me it’s the difference between an empty night sky and a night sky with all the stars shining and a big, bright bella luna. “Emotional appeal?” Oh yes indeed. And I don’t apologize for that for one second.

It’s still true, 14 years later. And it’s why Vesper didn’t start as a web app, and why we’re not converting it now.

More Notes on Vesper

Sun, 21 Aug 2016 15:56:17 -07002016-08-21T15:56:17-07:00

This is the first time I’ve ever shut down an app. In the past I’ve sold my apps (MarsEdit, TapLynx, Glassboard, NetNewsWire) — and two of those are still going. (I’m writing this post — like all my posts — in MarsEdit.)

* * *

We never debated about providing an Export feature — not only was it the obvious right thing to do, it was a feature we’d planned to do regardless.

Initially I thought we’d do it as a web app. You’d kick off an export, then the web app would create a zip file and send you email later so you could download it.

We didn’t do it this way because it sounded like a real pain to write, and, more importantly, it didn’t do anything for people who didn’t use syncing.

The iOS document provider feature — which was introduced after Vesper shipped (it was originally an iOS 6 app) — was just what we needed. It meant we could write the notes and pictures as files in a folder, and then a document provider could upload those files to iCloud Drive, Dropbox, or wherever.

Perfect. It works whether you’re syncing or not — it has nothing to do with syncing.

And it will continue to work even after sync shuts down. It will continue to work as long as you have the app on your device.

* * *

We decided to make it so that new users can’t sign up for syncing, since it’s going away. And, since a new user can’t sync, we can’t really ask them to pay for the app, either — so we made it free.

Consider the alternative: we allow new sync users, and we continue to charge for the app. Some people would buy it the same day we shut down syncing. That’s not good.

Since it’s free, it will probably get more downloads in the next few weeks than it’s had in its entire life.

* * *

Some people have asked that we make it open source. The request is getting serious consideration, but I can’t make any promises.

The code is all Objective-C. It’s an iOS 6 app with just enough changes to keep it working on iOS 7 and beyond. It knows nothing about size classes, presentation controllers, and so on. Doesn’t even use auto layout. It’s not an example of how you’d write an app these days.

* * *

Belief inside Q Branch: if we had started with a Mac app rather than an iOS app, Vesper would have been much more successful. That wasn’t clear at the time we started, though (Dec. 2012).

* * *

This is the last app on the App Store where I wrote all (or almost all) of the code. Odds are excellent that there will never be another app written largely by me on any app store.

(Yes, my day-job-apps are on the app stores, but they’re written by a team.)

I’m working on new stuff from Ranchero Software. I had planned two apps, but I think it’s going to be just one, just because two takes too much time. So I picked the one I’m more passionate about.

It’s a Mac app, because I’m a Mac developer at heart, and it won’t be on the Mac App Store because I prefer the freedom of shipping instantly, without any large corporation’s bureaucracy slowing things down and holding veto power.

And then that will be my app. The thing I work on for the next 10 or so years, until I retire. That’s the plan. (To be clear, though, I don’t plan to leave my day job, which I love.)

When will it ship? I don’t have a date. I don’t know.

Last Vesper Update, Sync Shutting Down

Sun, 21 Aug 2016 13:39:06 -07002016-08-21T13:39:06-07:00

We at Q Branch just released the final version of Vesper. It does one crucial thing: it allows you to export your notes and pictures. See the new Export section in the sidebar.

Sync will be turned off Aug. 30 at 8pm Pacific. We’ll destroy all the data, and neither we nor anyone else will be able to recover it.

The app will be removed from the App Store on Sep. 15. Until then, starting now, it’s free — since you can’t create new sync accounts, and it wouldn’t be fair to charge new users if they can’t sync.

I loved working on Vesper. It was one of the great software-making experiences of my life. We’d get on a roll and it was wonderful.

And now it hurts to turn it off, but it’s time.

To everyone who used the app: thank you so much.

Radical Infantile Terrorism

Tue, 02 Aug 2016 15:27:31 -07002016-08-02T15:27:31-07:00

We can’t just keep letting babies into the country. We can’t, or we won’t have a country. Won’t have a country. We have to get smart, people.

No country in history has ever been ripped off like this. We’re going to build a giant condom and make them pay! A giant, beautiful condom — oh, so beautiful — and so big.

That baby had no right to stand there and viciously attack me. Even CNN — who won’t interview me, which is fine, which is fine, believe me — well it’s disgraceful — even CNN, which I guarantee you will be out of business in three years because they won’t interview me — fine — says it was vicious. So, so vicious. Can’t I respond?

This is what’s wrong with our country — which, by the way, we won’t have anymore. People who’ve seen the plans for the condom — wonderful people, so wonderful, people who support Trump, who by the way is going to win big in November — say it’s beautiful. They say they’ve never seen anything like it in the history of the world. Believe me.

I’m a builder, so I think I know a few things about building things, okay? It will be big, and beautiful, and we’ll have a country again. We’ll make America great again.

Oh, I miss the old days. Remember the old days? We used to know what to do with babies. But now you can’t even say it, right? You can’t even talk that way anymore. We’re so politically correct.

I was always against the babies. Hillary Clinton had a baby! Do you know where babies come from? Don’t ask. It’s disgusting. Disgusting.

Where is that baby now? She won’t tell you. Crooked Hillary is hiding that baby. I’m not saying, I’m just saying, is she hiding something? You tell me.

In the old days we used to know what to do with babies that won’t even speak English, which by the law is the law of our country.

[Trump points to man in crowd.] Sir? That’s right sir — we’d carry them out. Carry them out! [Crowd chants “carry them out!”]

It’s sad, it’s so sad. We have to get smart, and tough, and babies aren’t tough. I know tough guys, and babies aren’t tough.

After we build that giant, beautiful condom, and make them pay for it — which, by the way, will be so easy, so easy — we’ll build a big, beautiful boob and make them pay for that too. So beautiful.

[Crowd chants “giant boob!”]

In Ryan’s Shoes

Mon, 01 Aug 2016 13:31:38 -07002016-08-01T13:31:38-07:00

I try to imagine what I would do were I Paul Ryan. I think and hope that I would un-endorse Trump. It’s obvious by now that a Trump presidency would be a calamity.

The cost of un-endorsing Trump might be the end of Ryan’s political career. He’d make more money in the private sector, sure, and he could probably still work on policy, but as a private citizen. Plenty of people do.

He’d lose an awful lot of power, though. I don’t think he’s in it for power alone — I think he’s in it for the power to turn his policies into law. Which is totally fine. Which is how it should be. (It’s not true of every politician, I grant, but I believe it’s true for Ryan.)

That’s a big thing to lose. He believes his policies will help the American people, and that the policies of Democrats (and some other Republicans) will hurt. I may disagree, but I respect it.

But here’s the thing: Trump is already hurting our country. Continuing to endorse him — no matter how tepidly, no matter how leavened with criticism — makes Ryan complicit in this harm.

Americans need to believe that the leaders of both parties are patriots first and party loyalists second. I’m sure Ryan knows this.

His un-endorsement may not hurt Trump. It may even help him. But there are times to think tactically and times — like now — to just do the right thing, the selfless thing, and be a hero.

Sound Off Round 4: Live-Captioning Open Source & Feelings

Thu, 14 Jul 2016 14:06:23 -07002016-07-14T14:06:23-07:00

From Sound Off:

Open Source & Feelings has a thorough and unambiguous code of conduct, one of the best diversity statements we’ve seen from a conference, and an about page with everything from venue accessibility, to public transit, to tips about keeping safe while traveling to and from the conference. Everything about Open Source & Feelings communicates thoughtfulness, deliberateness, and listening to feedback.

Donate now to help out this good cause.

Sound Off board member Ashley Nelson-Hornstein explains how live-captioning is useful for all physically-present attendees, not just for people you’d expect to need the help.

It’s also worth remembering that accessibility issues aren’t just something for a small percentage of the population.

Everybody has — or will have, if they live long enough — something they need help with. I have increasing trouble hearing, and live-captioning would certainly help me, and maybe you too.

Straight up: help make sure everyone can participate.

PS The conference will be here in Seattle, at Seattle Central College. I was on the college newspaper there, in moons past.

My Rules for Mutable Foundation Collection Objects

Thu, 30 Jun 2016 15:04:27 -07002016-06-30T15:04:27-07:00

I have some simple rules that I always follow when dealing with mutable Foundation collection objects (plus mutable strings) in my Objective-C code.


I often use a mutable collection object when constructing a thing — array, dictionary, set, or string — and then pass it somewhere else.

Once it’s passed, ownership is relinquished. The construction code never continues to hold a reference to the thing it made.

Wherever that thing goes it’s treated as immutable (whether or not it really is).

No mutable collection objects in APIs

In my .h files, under no circumstances are properties or parameters allowed to be mutable collection objects.

(Or, well, it’s extremely rare. There could be a utility API that takes a mutable thing, but that API does some kind of work that doesn’t retain that collection, so it can’t mutate it later on.)

Mutable collection objects are internal to a .m file

An object may use mutable collection objects internally, but those aren’t allowed to escape the .m file they live in. There’s no chance, then, that one of these could be mutated without its owner knowing about it.

* * *

By following these rules — which, after all these years, I do without even having to think — I never run into an issue where I’ve passed a mutable array (or whatever) to another object, then held on that array and mutated it. It just can’t happen.

But, really, whatever — these days I write Swift code instead.