Back in April, I wondered aloud on Twitter:
Wondering aloud: lots of computer conferences have a one-day tutorial beforehand, usually for beginners. Would anyone want an advanced one?
This is something I’ve been thinking about from the arrangement of the Mac/iOS conferences that typically have a beginner tutorial on day one, then eyes-forward sessions and other contents starting the next day. It seems to have the unintended effect of bifurcating the audience: the intermediate and advanced developers roll in on the second day and it changes the composition of the crowd and the feeling of the group. The sense of “we’re all in this together” gets a little lost. What could we do to get those intermediate and advanced developers in on the first day, mingling with the newbies at breakfast and lunch? Well, we could try to have a tutorial on topics sufficiently advanced that it would be worth the time and expense for intermediate and advanced developers to arrive early for tutorial day.
It seemed like an interesting experiment, and Dave Klein of CocoaConf was game to give it a try. But what goes into an “advanced” tutorial? We could do a day’s worth of stuff that you only get into after a year or two of professional development — managing large code-bases, fancy UIKit tricks, expert XCode wizardry, etc. — though it’s likely five different instructors would come up with five different sets of topics to cover.
Another idea: pick a single advanced topic and really dig into it. Maybe something that people are aware of but haven’t had time to tackle. Something that’s so renowned for its challenge that the best way to learn it would be to just sit down with an expert for a day and work through some code.
Something like, Core Audio, you suppose?
Yep, that’s exactly what we’re doing. On Thursday, August 9 — the first day of CocoaConf Columbus — I’m going to do an all-day Core Audio intro tutorial. I haven’t hashed out the schedule, but it will basically be geared to projects that we can bang out in a tutorial setting and that do something interesting. I might draw from the book, but I might throw in some all-new material… just this week, I was working on code for an ADC support incident and realized that a basic web radio client could be explained and written in about two hours, so that’s at least possible (and ironic, considering we chose to leave Audio File Stream Services out of the book). Surely, the afternoon will have to be all about Audio Units.
Pre-requisites: as with the book, you’ll need a reasonable comfort level with C — not expert level, but not afraid of
* either. Not sure if I want to require a device or make everything simulator-friendly. Guess you can watch the CocoaConf page for that.
Anyways, Dave and family are going to be focused on CocoaConf DC for the time being, and probably won’t switch the page to Columbus until July. If you’re interested in a full day of serious Core Audio hackery and slashery, save the date (Thursday, August 9), and start thinking about how you’ll get yourself to central Ohio.
Hope to see you there. I’m looking forward to being able to do a full day of Core Audio.
OK, here’s my usual post-conference blog entry with slides and sample code links. In a break with tradition, I’m actually getting it up the day after I got home from CocoaConf, rather than weeks later.
“Core Audio Cranks It Up” is a talk I first gave at an earlier conference, so the links to slides and sample code are in What You Missed At Voices That Matter iOS, Fall 2011.
New for CocoaConf, I did a talk called Core What?, which started from Twitter discussions with potential attendees about topics including a grab-bag of Core Foundation and other C-level oddities and novelties, and all the gruesome PDF lessons I learned late last year.
For what it’s worth, this is another conference presentation I created entirely on my iPad. This presentation also includes an off-the-cuff reference to Bodacious Space Pirates (although one stage of the build was lost in export to PDF). You’re welcome.
We also did a “Reverse Q&A” panel, in the style introduced by Harmonix’s PAX East 2011 Reverse Q&A. This made it a lot easier to get the discussion rolling quickly, and featured much more insight from the audience than you’d get from a typical panel format. Feedback on Twitter has been positive, including from CocoaConf’s itself, which vows to use the format again in the future. But maybe next time I’ll stick to the handheld mic that I shared with audience members, because I think my super-sensitive lavalier was the source of the feedback whenever I was under a speaker.
CocoaConf Chicago early bird pricing ends this weekend. I’ll be there, doing the Core Audio on iOS 5 talk (with MIDI and Audio Unit effects), and a new “Core What?” talk about neat stuff I’ve found over the years in the various C frameworks. A big piece of it will actually center on the CGPDF… stuff in Core Graphics, after all the PDF work I did last fall. Drawing into a PDF and drawing a PDF page into your view are common enough tasks, and the parsing of a PDF is another one of those tasks where the API makes absolutely no damn sense until you understand the problem domain behind it. Beyond that… CFUUID, CF-only collections, other curiosities and oddities.
Oh, and there’s a Fry’s Electronics in Downer’s Grove, about 20 minutes from the conference hotel. I have at least $500 worth of stuff on my shopping list (NAS, FCPX-compatible video card, Rock Band drums or Pro Guitar, out-of-print anime…). So that will add to the fun.
Speaking of CocoaConf, Saul Mora (who recorded our panel at CocoaConf Raleigh) had me on as a guest for NSBrief episode #33, in which we discuss audio theory, Core Audio, and AV Foundation for an hour. Plus, I lay out the plan for the “Reverse Q&A” we’re doing at CocoaConf Chicago, inspired by the Harmonix Reverse Q&A Panel at PAX East 2011. I wondered aloud about the idea of doing this in an earlier blog, and I’m glad we’ll have a chance to give it a shot. Hopefully, this will prove to be a good way to shake up the regular old panel format, and be fun and insightful for audience and speakers alike.
Learning Core Audio continues to work its way through Pearson’s production process. This week we signed off on author bios and cover blurbs. Copy-edit was a few weeks ago… admittedly a bit of a disappointment as I discovered all the third-person sentences had been somewhat mechanically rewritten to second-person (i.e., “we” becomes “you”). Sometimes it works, sometimes it really doesn’t, and I was too tired to fix all the cases of the latter. Still, it would have been nice to have been told about this house style two years ago when we started the damn thing.
It should hardly be necessary to state the importance of Ritchie’s work. C is the #2 language in use today according to the TIOBE rankings (which, while criticized in some quarters, are at least the best system we currently have for gauging such things). In fact, TIOBE’s preface to the October 2011 rankings predicted that a slow but consistent decline in Java will likely make C the #1 language when this month’s rankings come out.
Keep in mind that C was developed between 1969 and 1973, making it nearly 40 years old. I make this point often, but I can’t help saying it again, when Paul Graham considered the possible traits of The Hundred-Year Language, the one we might be using 100 years from now, he overlooked the fact that C had already made an exceptionally good start on a century-long reign.
And yet, despite being so widely used and so important, C is widely disparaged. It is easy, and popular, and eminently tolerated, to bitch and complain about C’s primitiveness.
I’ve already had my say about this, in the PragPub article Punk Rock Languages, in which I praised C’s lack of artifice and abstraction, its directness, and its ruthlessness. I shouldn’t repeat the major points of that article — buried as they are under a somewhat affected style — so instead, let me get personal.
As an 80′s kid, my first languages were various flavors of BASIC for whatever computers the school had: first Commodore PETs, later Apple IIs. Then came Pascal for the AP CS class, as well as a variety of languages that were part of the ACSL contests (including LISP, which reminds me I should offer due respect to the recent passing of its renowned creator, John McCarthy). I had a TI-99 computer at home (hey, it’s what was on sale at K-Mart) and its BASIC was godawful slow, so I ended up learning assembly for that platform, just so I could write programs that I could stand to run.
C was the language of second-year Computer Science at Stanford, and I would come back to it throughout college for various classes (along with LISP and a ruinous misadventure in Prolog), and some Summer jobs. The funny thing is that at the time, C was considered a high-level language. At that time, abstracting away the CPU was sufficient to count as “high-level”; granted, at the time we also drew a distinction between “assembly language” and “machine language”, presumably because there was still someone somewhere without an assembler and was thus forced to provide the actual opcodes. Today, C is considered a low-level language. In my CodeMash 2010 talk on C, I postulated that a high-level language is now expected to abstract away not only the CPU, but memory as well. In Beyond Java, Bruce Tate predicted we’d never see another mainstream language that doesn’t run in a VM and offer the usual benefits of that environment, like memory protection and garbage collection, and I suspect he’s right.
malloc() make C “primitive”? I sure didn’t think so in 1986. In fact, it did a lot more than the languages at the time. Dynamic memory allocation was not actually common at that time — all the flavors of BASIC of that time have stack variables only, no heap. To have, say, a variable number of enemies in your BASIC game, you probably needed to do something like creating arrays to some maximum size, and use some or all of those arrays. And of course relative to assembly language, where you’re directly exposed to the CPU and RAM, C’s abstractions are profound. If you haven’t had that experience, you don’t appreciate that
a = b + c involves loading
c into CPU registers, invoking an “add” opcode, and then copying the result from a register out to memory. One line of C, many lines of assembly.
There is a great blog from a few years ago assessing the Speed, Size, and Dependability of Programming Languages. It represents the relationship between code size and performance as a 2-D plot, where an ideal language has high performance with little code, and an obsolete language demands lots of work and is still slow. These two factors are a classic trade-off, and the other two quadrants are named after the traditional categorization: slow but expressive languages are “script”, fast but wordy are “system”. Go look up
gcc – it’s clearly the fastest, but its wordiness is really not that bad.
Perhaps the reason C has stuck around so long is that its bang for the buck really is historically remarkable, and unlikely to be duplicated. For all the advantages over assembly, it maintains furious performance, and the abstractions then built atop C (with the arguable exception of Java, whose primary sin is being a memory pig) sacrifice performance for expressiveness. We’ve always known this of course, but it takes a certain level of intellecutual honesty to really acknowledge how many extra CPU cycles we burn by writing code in something like Ruby or Scala. If I’m going to run that slow, I think I’d at least want to get out of curly-brace / function-call hell and adopt a different style of thinking, like LISP.
I was away from C for many years… after college, I went on a different path and wrote for a living, not coming back to programming until the late 90′s. At that point, I learned Java, building on my knowledge of C and other programming languages. But it wasn’t until the mid-2000′s that I revisted C, when I tired of the dead-end that was Java media and tried writing some JNI calls to QuickTime and QTKit (the lloyd and keaton projects). I never got very far with these, as my C was dreadfully rusty, and furthermore I didn’t understand the conventions of Apple’s C-based frameworks, such as QuickTime and Core Foundation.
It’s only in immersing myself in iOS and Mac since 2008 that I’ve really gotten good with calling C in anger again, because on these platforms, C is a first-class language. At the lower levels — including any framework with “Core” in its name — C is the only language.
And at the Core level, I’m sometimes glad to only have C. For doing something like signal processing in a Core Audio callback, handing me a
void* is just fine. In the higher level media frameworks, we have to pass around samples and frame buffers and such as full-blown objects, and sometimes it feels heavier than it needs to. If you’re a Java/Swing programmer, have you ever had to deal with a big heavy
BufferedImage and had to go look through the
Raster object or whatever and do some conversions or lookups, when what you really want is to just get at the damn pixels already? Seems to happen a lot with media APIs written in high-level languages. I’m still not convinced that Apple’s AV Foundation is going to work out, and I gag at having to look through the docs for three different classes with 50-character names when I know I could do everything I want with QuickTime’s old
GetMediaNextInterestingTime() if only it were still available to me.
C is underappreciated as an application programming language. Granted, there’s definitely a knack to writing C effectively, but it’s not just the language. Actually, it’s more the idioms of the various C libraries out there. OpenGL code is quite unlike Core Graphics / Quartz, just like OpenAL is unlike Core Audio. And that’s to say nothing of the classic BSD and other open-source libraries, some of which I still can’t crack. Much as I loathe
NSXMLParser, my attempt to switch to
libxml for the sake of a no-fuss DOM tree ended after about an hour. So maybe it’s always going to be a learning process.
But honestly, I don’t mind learning. In fact, it’s why I like this field. And the fact that a 40-year old language can still be so clever, so austere and elegant, and so damn fast, is something to be celebrated and appreciated.
So, thanks Dennis Ritchie. All these years later, I’m still enjoying the hell out of C.
CodeMash starts Wednesday in Sandusky, with half-day iOS tutorials from Daniel Steinberg and myself, followed by two days of sessions. My Thursday session is The Dark Depths of iOS, and is a rapid-fire tour of the non-obvious parts of the iOS APIs.
Researching for this has proven an interesting exercise. I had the idea for the talk from the occasional dive into Core Foundation for functionality that is not exposed at higher levels of the iOS and Mac stacks. A simple example of this is the CFUUID, the Universally unique identifier defined by RFC 4122. More than once, I’ve needed an arbitrary unique ID (other than, say, the device ID), and am happy to use the industry standard. But it’s not defined in Foundation or Cocoa, so you need to use Core Foundation and its C API.
Another example I knew about before starting this talk was the CFNetwork sub-framework, which provides a much more complete networking stack than is available in Cocoa’s URL Loading System. CFNetwork allows you make arbitrary socket connections, work with hosts (e.g., to do DNS lookups), accept connections, etc. Basically, if what you need from the network can’t be expressed as a URL, you need to drop down at least to this level. It has an advantage over traditional BSD sockets in that it integrates with the Core Foundation view of the world, most importantly in that its reading and writing APIs use the asynchronous callback design patterns common to Apple’s frameworks, rather than blocking as the traditional C APIs would.
Stuff like those, along with Accelerate and Keychain, are things I knew I wanted to talk about, and did the first few slides on Core Media and Core Services by pointing out reasonably findable information from Apple’s architecture docs.
The eye-openers for me were down in the “System” level of Core OS… the various C APIs that iOS inherits from its open-source roots in FreeBSD and NetBSD (i.e., Darwin). These aren’t substantially documented in Xcode (though they do enjoy syntax highlighting and sometimes code-completion). The documentation for these is in the
man pages, which of course makes sense for long-time Unix programmers, but maybe less so today… if I’m writing in Xcode for a separate iOS device, the Mac command-line is a rather counterintuitive location to look for API documentation, isn’t it?
So the trick with calling the standard C libraries is finding out just what’s available to you. Apple has links to iOS Manual Pages that collect a lot of these APIs in one place, but they are largely unordered (beyond the historical Unix man page sections), and being programmatically generated, Apple can only offer a warning that while some APIs known to be unavailable on iOS have been filtered out, the list isn’t guaranteed to be completely accurate. There’s also a consideration that some of these APIs, while they may exist, are not particularly useful given the limitations under which third-party iOS applications operate. For example, all the APIs involving processes (e.g., getting your PID and EUID) and inter-process communication are presumably only of academic interest — the iPhone is not the campus timeshare mainframe from 1988. Similarly, ncurses is probably not going to do much for you on a touch display. OK, maybe if you’re writing an ssh client. Or if you really need to prove that Angry Birds could have worked on a VT100.
Another way of figuring out what’s there — if less so how to actually call it — is to go spelunking down in
<iOS_SDK>/usr/include to get an idea of the organization and packaging of the standard libraries. Had I not done this, I might not have realized that there is a C API for regular expression matching (
regex.h), XML parsing with libxml2 (both DOM and SAX), zip and tar, MD5 and SHA (in
CommonCrypto/) and other interesting stuff.
On the other hand, there are cases where code libraries are available but don’t have public headers. For example,
libtidy.dylib are in
usr/lib but don’t seem to have corresponding entries in
usr/include. That begs the question of whether you could call into these BZip and Tidy libraries and remain “App Store safe”, given the apparent lack of a “public” API, even though you could easily get the headers for these open-source libraries from their host projects. Heck, kebernet pointed out to me that
bzlib.h are available in the
iPhoneSimulator.platform path, just not
It would be nice if there were better visibility into these libraries, though their nature as unrepentant C probably scares off a lot of developers, who will be just as well off scouring Google Code for a nice Objective-C alternative (provided the license they find is compatible with their own). My takeaway is that there’s even more functionality at these low levels than I expected to find. I’ll probably at least consider using stuff like libxml2 and
regex.h in the future.