HNHacker News
TopNewBestAskShowJobs

andymatuschak

567 karma · joined April 19, 2011

Wonder, blunder, salve, solve.

Working on tools that expand what people can think and do.

Past: led R&D at Khan Academy, helped build iOS at Apple.

http://andymatuschak.org

[ my public key: https://keybase.io/andymatuschak; my proof: https://keybase.io/andymatuschak/sigs/cXR2O704tD-HTFzScbqwt5b81_3bhHaU-xHGAHmHkfc ]

submissionscomments
andymatuschak··on My internship on the Khan Academy iOS team
We're serious about intern mentorship: http://bjk5.com/post/23266999170/how-intern-mentorship-works...

If you're an iOS dev who wants to be mentored for a few months by a former UIKit author, hit me up. :) andy@khanacademy.org

andymatuschak··on My internship on the Khan Academy iOS team
Ah; sorry, I was referring to Khan Academy specifically.
andymatuschak··on My internship on the Khan Academy iOS team
Anyone can apply for an internship; you can think of it as a paid, fixed-duration, apprentice-like position.
andymatuschak··on Show HN: §, an interactive toy I built to accept my offer from Khan Academy
Good point. http://life.khanacademy.org/post/87602482963/a-mobile-dev-se...
andymatuschak··on Is TDD dead?
I really enjoyed Gary Bernhardt's response to this discussion: https://www.destroyallsoftware.com/blog/2014/test-isolation-...

You should read the whole article, but to motivate:

> This post was triggered by Kent's comment about triply-nested mocks. I doubt that he intended to claim that mocking three levels deep is inherent to, or even common in, isolated testing. However, many others have proposed exactly that straw man argument. That argument misrepresents isolated testing to discredit it; it presents deep mocks, which are to be avoided in isolated testing, as being fundamental to it; it's fallacious. It's at the root of the claim that mocking inherently makes tests fragile and refactoring difficult. That's very true of deep mocks, but not very true of mock-based isolation done well, and certainly isn't true of isolation done without mocks.

> In a very real sense, isolated testing done test-first exposes design mistakes before they're made. It translates coupling distributed throughout the module into mock setup centralized in the test, and it does that before the coupling is even written down. With practice, that preemptive design feedback becomes internalized in the programmer, granting some of the benefit even when not writing tests.

andymatuschak··on Show HN: Learning SICP with Understudy
> Moreover, the experience can be completely asynchronous. You don't have to both be available to make progress.

Studying SICP (or anything) can involve different "modes":

Reading and doing exercises will often be solitary. Q&A could definitely be asynchronous (IRC works great for that!). But we're talking about explaining what you've learned; only in synchronous conversation will you get the back-and-forth "wait what? How's that work?"

A hard part of learning is figuring out exactly what you don't know; conversation is remarkably effective at elucidating that. Where do you feel uncomfortable while speaking? Where does your partner look especially confused or skeptical? The human connection gives you expression, body language, tone of voice, etc. in a quick feedback loop.

(disclaimer: not involved in creating Understudy, but I'm a happy user!)

andymatuschak··on Google Correlate - Draw
Stone fruit (peaches, plums, apricots, nectarines) are in season in the summer and easily bruise and get brown spots when they overripen.
andymatuschak··on iOS 7 Parallax Background in JS
Warning: Just as with UIScrollView, there's a lot more to getting this one right than it initially may seem...

But here's probably the next thing I'd address: http://en.m.wikipedia.org/wiki/Gimbal_lock

andymatuschak··on _why's site is back up
Honestly... I just had a habit of checking up on him every once in a while. Came upon this today when someone brought him up and I thought to check in. It's been there for weeks and somehow no one else noticed.
andymatuschak··on Monads in Python (with nice syntax)
This approach to the "do" syntax requires that the function implementer know the monad type a priori.

That defeats some of the purpose of monad as general abstraction. One of the big ideas here, as far as I'm concerned, is that monads represent an abstraction over a common structure of programs. Lists, Maybes, threading models, etc, all share this same language of structuring computations. This is significant because it means that one can build functions which manipulate those structures, and then those structures can be deployed generically. Depending on how you're counting, that means third-order abstraction.

For instance, consider liftM from Control.Monad:

  -- | Promote a function to a monad.
  liftM   :: (Monad m) => (a1 -> r) -> m a1 -> m r
  liftM f m1              = do { x1 <- m1; return (f x1) }
This represents a common idea across e.g. both List and Maybe. I've got a function of values. I want to turn it into a function of Lists / Maybes. Well, liftM recognizes the similarity of List's and Maybe's structure and provides a single implementation suitable for both places.

The decorator described in this article cannot function at liftM's level of abstraction: at least as far as I can tell (as a non-Python programmer), it requires a monad type parameter. If that's true, I think it's missing a key idea behind the power of monads.

andymatuschak··on Engage by Mixpanel
Using push notifications for marketing purposes or to send unsolicited promotional information is a violation of the App Store guidelines.
andymatuschak··on Designing for iOS: Taming UIButton
Regarding the TripComputerButton, I'm a little surprised that this is performant in a table view! I'm guessing your buttons are fairly small (< 100x100)?
andymatuschak··on Designing for iOS: Taming UIButton
Many of these are places where people are caching rasterizations of deep layer hierarchies to avoid paying the compositing cost on a per-frame basis. But if you do that with drawRect:, you're using the CPU (not the GPU); if you use your own images, you're on the hook for your own caching, which you're likely to mess up. Such cases should probably use -[CALayer setShouldRasterize:] instead.

For more about this stuff, check out the two WWDC sessions I mentioned above.

andymatuschak··on Designing for iOS: Taming UIButton
Render the gradients into a resizable UIImage via CG. That differs from approach #2 in the article, which does the same thing, but generates a non-resizable UIImage.

To make a resizable image at runtime, draw into an image as described in approach #2, but make the image have width of left cap + 1 point + right cap, then use -[UIImage resizableImageWithCapInsets:] to generate a wrapper with the correct resizing behavior.

Then: make sure that if you have 100 buttons on-screen which all use the same gradients, you end up reusing the same generated UIImage. You don't want to redraw the same thing for each of them.

andymatuschak··on Designing for iOS: Taming UIButton
It's not really true that all techniques perform fine if you're rendering just one button.

If you're using a masked CALayer, and that layer's in a scroll view or is otherwise animating around the screen, there's a very real chance that you'll drop frames, just from that layer's off-screen rendering pass. Depends on how big the button is.

Certainly, though, if you need parameterizable imagery, you need parameterizable imagery, and so you can't load them from disk. But you can still make your runtime-generated images resizable!

andymatuschak··on Designing for iOS: Taming UIButton
It's really worth noting that there are substantial performance ramifications to your choice here, in terms of CPU time for generation, memory usage, I/O, and GPU time for rendering.

The resizable image background technique will be the fastest option (provided you don't need to programmatically tweak the appearance). Next would be the full-sized background (which needlessly wastes memory). Then the CG-based approach, which could actually perform better than the full-sized background if you had generated a resizable image—the technique presented here needlessly wastes memory and CPU time by generating a full-width image. But it will still perform worse in basically all cases than the resizable-image-from-disk technique, so you would only want to do that if the parameters need to be tweaked at runtime.

The CAGradientLayer-based approach (as written) is a very poor idea unless you need the animated transitions because it requires extremely expensive off-screen drawing passes due to the masking. If your situation permits you to use "overdrawn" masking (as I discussed in WWDC 2012's "Polishing Your Rotation Animations"), this would actually perform quite well—less memory consumption than all the other options; small rendering cost each frame. See also WWDC 2011's "Understanding UIKit Rendering" for more on graphics performance with UIKit.

I guess it's also worth noting that the cost of masking CALayers with a borderRadius is much lower in iOS 6 than iOS 5, but don't go nuts: it's still way higher than all these other options.

andymatuschak··on We need more native code
It's true: you could fix these specific bugs with JavaScript (though I don't know if you could ever get Services working!) But you'd get a huge amount of standard behavior if your code editor were based on Cocoa's text system. As it stands, you'll always be playing catch-up as AppKit changes the behavior of Mac OS X's text views from release to release (and as the rest of the apps on the system move with these changes "for free").
andymatuschak··on We need more native code
Now, I'm not trying to incite a native vs. web flame war here, but I believe that building separate native UI layers would have actually been much better. I hope I can provide some constructive criticism on the native app for the Mac:

The app, as it stands, does not behave like any of the others on my screen. This greatly increases the startup cost for me, since it doesn't follow the idioms I've already learned (and which I'm concurrently employing in these other apps).

For instance, the code editor doesn't behave like any other text editor on my screen (including the Xcode and TextMate source editors open alongside): Ctrl+Arrow doesn't navigate; double-click-and-drag doesn't select by word; my services are not available in the contextual menu; etc.

The keyboard shortcut for "change tab" that works in all the other tabbed windows on my screen does not work in this interface. The same goes for zooming shortcuts, "find" within the source editor, etc.

Then there are more fundamental disconnects: there's a "save" button in the interface, for example. That's an extremely rare thing to see in a Mac app. In fact, as of Lion, the user should never have to explicitly save.

Now, of course, building a native UI layer (in terms of design, not just ABI) would be a great deal of work. You could reasonably argue that it wouldn't be worth that work, but I'd just like to point out that it would indeed provide a much better experience.

andymatuschak··on Learning From Data - Online Course
His book is not yet available. That seller is likely not legitimate.
andymatuschak··on Learning From Data - Online Course
Yaser Abu-Mostafa was (by enormous margin) the most effective professor I had at Caltech. Despite being such an expert in the field, he understands clearly when a concept is particularly challenging--and what about it makes it so. This class (the official equivalent) was one of my absolute favorites. Definitely worth a look!
← PreviousPage 3 of 3