This is the final post in a series of 3 covering 15 exercises that provide a sense of a programming language's idioms and "feel." For newcomers, if you can't "jump in" and tackle these exercises in a particular programming language, don't embarrass yourself by claiming to know that language. For more experienced developers, these programs should be tough enough to require problem solving: try to embrace the language's idioms.
The first series of exercises dealt with calculations, the second with data structures. This final series is the fun one: exploiting libraries and unique environmental capabilities.
Libraries
- Write a program that outputs the current date and time to a Web page as a reversed ISO 8601-formatted value (i.e.: "2006-06-16T13:15:30Z" becomes "Z03:51:31T61-60-6002"). Create an XML interface (either POX or WS-*) to the same.
Educational goals of exercise 11:
"Hello, Web!"
- Write a client-side program that can both scrape the above Web page and the XML return and redisplays the date in a different format.
Educational goals of exercise 12:
HTTP get, string parsing.
- Write a daemon program that monitors an email account. When a strongly-encoded email arrives that decrypts to a valid ISO 8601 time, the program sets the system time to that value.
Educational goals of exercise 13:
Encryption, Email, OS libraries, daemons
- Write a program that connects to your mail client, performs a statistical analysis of its contents (see A Plan for Spam ) and stores the results in a database.
Educational goals of exercise 14:
Interop, database, open-ended difficulty with text parsing
- Using Exercise 15, write a spam filter, including moving messages within your mail client
Educational goals of Exercise 15:
More interop, open-ended problem.
Discussion
This is the hardest series to generalize, because most new programming systems have value-propositions linked to disparate libraries, frameworks, and types of development. I don't think there's a single series that would capture the different flavors of, say, Ruby on Rails, the Smalltalk standard library, and WinFX. But I do think expect that moving data on and off the Web is both common enough and has enough different flavors to be of interest. The other elements of these exercises touch on some common problems (parsing text, database connections) and some that might be less common. I am firm in my belief that interop is an important part of a language's feel and the time-set and email exercises are intended to force one out of the standard library.
I specifically included the word "mashups" when drafting this, because I wanted to capture this emerging type of "scrap-heap" programming. Unfortunately, I failed to actually do so. Suggestions for improvement welcome.
There are a lot of characteristics that this group of exercises hardly touches on: code-data equivalence, meta-programming, search, numerics, etc. Every language is going to have something really cool that this group of exercises doesn't hit and maybe, for you, that's the coolest, most important thing going. That's fine: I feel that way about Prolog. But these exercises aren't intended to be the basis for a survey course in programming languages, they're intended to be exercises to keep you from wasting everyone's time applying for a job: if you can do these exercises, I think that's prima facie evidence that you legitimately know the language.
Conclusion
Is this how I really go about learning a programming language? Yeah, pretty much. I always do either the Haar wavelet, a neural net, or a genetic algorithm; I always do at least one tree-based data-structure; and I always do some email manipulation. I'll admit I don't rush to understand interop, which is always a pain, but if I were to apply for a job using a language, I would absolutely prepare myself for interacting with system services and external libraries.
The latest language I (re-)learned was LISP. In the past decade, I've done pretty-much-these-exercises with Java, C#, and Ruby. Currently, I'm becoming more familiar with C++/CLI. Going forward, I will be strongly biased towards languages with built-in concurrency features. In the last decade, I've played with probably three times as many languages, but there's an enormous difference between playing with a language and claiming that you know it at a level sufficient to get an entry-level job.
For me, doing a similar set of exercises with LISP took me four months. Whether that's long or short, I don't know. I don't have a lot of spare time, so I pick it up on night and weekends and, you know, I'm happily married and live in Hawaii, so I've got other stuff to do, too. I wander around, read books, but try to continually press myself towards non-trivial applications such as Exercises 5, 10, and 15. On the other hand, I was relearning LISP, love programming languages, and know at least another few (C, VB, Prolog, Smalltalk), so that's probably an advantage.
However, really internalizing the idioms of a language takes longer (or at least, it requires immersion for months). I don't claim to be do things the "Ruby way" or the "Lisp way." A word of warning: when the internalization of the idioms takes place and you really know a language, it unlocks your mind in a way that can fool you into thinking "This is X times faster than other programming languages!" (X can range from 2 to 10, depending on your emotional state.) That's not really the way it works, at least not for the real challenges of software development.
The real challenges in software development are not technical; they are the challenges of dealing with human beings, with their different wants, needs, values, communication skills, and emotional states. Programming languages are easy and fun. People are harder, but even more fun.
Aloha.
Part 1, Part 2.