Teaching collections: shifting paradigms and breaking rules

Just because some things look alike and may act alike at some level, doesn’t mean that they should be taught at the same time, under a unified umbrella of learning. Consider bagels and donuts. They are both toroids . You can layer several instances onto a stick for storage or serving. You can cut them both in half. If you have no taste or sanity, you can place custard — or, cream cheese, salmon, onions, and capers — interchangeably between the two sides of either item.

Despite these common API surfaces, their use-cases, edge conditions, and recipes share little overlap. Conformance to ToroidFoodstuff does not correlate with each preparation of dough, the cooking process, or the serving and accoutrements associated with either food.

So why do we always have to lump arrays, sets, and dictionaries into a single lesson on collections?

A new language learner has little interest in traversing dictionaries, although it’s possible, or taking a set’s prefix, which is also allowed. Nor are new learners always prepared to take on optionals, the core return value for dictionary lookups, early in the language learning process.

I’ve recently spent some time helping to outline an introductory sequence for Swift learning. I pitched eliminating collections as a single topic unto itself. I want to reject superficial similarity and build language skills by introducing simple, achievable tasks that provide measurable and important wins early in the learning process.

Take arrays. They can store numbers and strings and more. You can grow them, shrink them, slice them. They have a count. They have indexes.  Arrays are perfectly matched with iteration in general and for-in loops in particular. Arrays and for-in iteration work hand-in-hand. So why not learn them together?

The answer is generally that arrays belong with collections and for loops belongs within a larger set of iteration topics. Ask yourself whether new coders actually need while and repeat-while loops in their initial approach to the language? How often in normal Swift coding do you reach for those two for simple reasons in simple code?

I’m not saying while-loops shouldn’t be taught. I’m trying to figure out what sequence of incremental learning provides new Swift developers with the most coherent set of basic tools they need to express themselves and expand their understanding over time.

Every classroom minute spent mastering while is a minute that could expand and practice for. Introductory lessons should focus on the core terms and patterns most commonly used in the workplace. Expressive language vocabulary can always be expanded through practice and engagement. Classroom minutes represent the restricted path.

Dictionaries, I argue, should be taught late. Every lookup is tied directly to optionals, a dictionary’s native return type. And optionals are quite a conceptually heavy topic. Dictionaries are the perfect pairing.  The type is a natural source of optional output, and an opportunity to discuss nil-coalescing and default fallbacks.

From there, you can pull in failable initializers, and optional chaining.  Dictionaries also lend themselves to advanced concepts like (key, value)-based for-in loop tuples, the key-value basics of Codable, and how custom structs relate to key-value coding, not to mention the entire conversation about nil, errors, try?, and more.

As for sets, well, I love sets and use sets, but are sets even appropriate for new learners outside of some sense of “completionism” learning? Should they be taught only because they’re one of the “big three” collection types? I’d argue that people should learn sets when they are already proficient in core language basics, not in the most introductory setting.

For example, you can tie sets into a lesson on view touches. Just because they’re a collection doesn’t mean that the newest students have to learn every collection right away, just as they don’t need to learn NSDictionary, NSArray, and AnyObject, and so forth, in the first days or weeks of exposure to Swift.

Trying to structure a plan to create a solid foundation of incremental learning is a challenging task for any non-trivial topic. When it comes to Swift and Cocoa/Cocoa Touch with its vast range of potential interests, ask the questions: “What core concepts and patterns best reward the language learner with immediate benefit?”, “What grouping conventions should be tossed overboard to better focus on the skills with highest returns?”, and “What critical paths allow learners to proceed towards measurable skills and performance with the least overhead?”

Justify each topic with an answer that’s not “it’s covered that way in the Swift Programming Language book”, especially when working with new learners versus developers moving into the language with existing programming experience. And even when teaching more experienced students, let the daily realities they’re trying to move towards mold the curriculum of what you choose to teach.

The best learners teach themselves. The best curriculum sets them up to do so.

4 Comments

  • I like the idea of teaching things based on correct timing in a person’s learning arc, rather than lumping things together because that is how we have always done it. I know from my own experience that early programming classes seemed built to discourage a person from pursuing a career in computer science. How short sighted its that? Instead, help the student have early successes so they can feel the excitement of writing code and the reward that comes from it.

  • There’s no reason why you can’t touch on a subject twice if need be. For example, if you are teaching people about iteration, in order to make it interesting, they need to know something about iterable collections but it needs to be kept simple. So teach the basics of arrays first and then revisit them later when you get on to collections.

    Similarly, I disagree with you a little on dictionaries. If you are going to teach people about optionals, you need useful concrete examples of why you would ever bother with them and subscripting a dictionary fits all of that. You don’t need to teach people everything about dictionaries when you first introduce them and I would argue that the basic concept is pretty simple to understand.

    In fact, I guarantee that anybody who is capable of learning to program already understands the concept of dictionaries. I do not remember when I first learned how to use a dictionary but I had a pretty memorable lesson at school when I was eight years old. Our teacher told us he could look up any word in the school issued dictionary in under 10 seconds. After a few trials, we had to admit he was telling the truth. He then taught us how to do it ourselves. So there you are: a bunch of random eight year old kids not only understood the concept of a dictionary but also the binary search algorithm. Obviously with Swift dictionaries, you’d gloss over the algorithm to look up the values at first, but later, you come back to them and go through all of that in detail.

    And an aside: a year ago I would have agreed with you about the relative importance of `while` and `for`. However, I saw this Dave Abrahams video and now, every time I find myself writing a `for` loop, I find myself asking if there is A Better Way.

  • In general, I am with Erica on this. However, after reading JeremyP’s comment, I was reminded about different learning perspectives and histories of individuals. <>

    The first time I learned a programming language, it was FORTRAN (with cards readers) in my freshmen engineering curriculum. I found I liked coding (we did not know the distinction between coding and programming back then) and went to the Comp Sci department and talked to a professor who steared me to this new class they had teaching the Pascal programing on interactive standalone mini computers called IBM Teraks using the UCSD operating system. Pascal gets a bad rap most of the time but nobody knocks it as a teaching language. This was a much more interesting class than the Engineering FORTRAN class and we weretaught the basic concepts in an orderly manner much like Erica has proposed for Swift. Yes, Pascal was simpler in those days, so you can argue that the training path was simpler by default. However, therte were comncepts like linked lists and pointers and bit manipulations which were saved for a second semester, which never existed since it was an experimental class and the next official class was assembly language. You had to wait for a year to get into the data structure class and since I was not in the Comp Sci department, and didn’t have the optional Engineering credits to burn, that was teh last comp sci course I ever took (until well later in life where I talked my bosss into paying for an AI course with LISP and Prolog and ART. To digress and come back, I liked LISP almost as much as Pascal, the latter which I kept up with informally until Apple cut me off when Jobs made that terrible mistake instead of going with Macintosh Pascal which I consider (along with the followup compiled version, THINK Pascal) to be the best language learning environment ever including playgrounds.

    As much as I enjoyed the advent of Swift and not having to learn Objective C, and thinking Swift syntax was like Pascal so I would be back home again, Swift is a complicated language. It is not checkers or Chess but more like (the game) Go. Part of my learning curve was to try and learn from version 1.0 with all the baggage of Cocoa and UIKit. You MUST learn optionals and key, value stuff if you want to play with the Apple API’s and even worse, multiple API’s to do the same thing on different Apple hardware. Yes, Apple is supposedly working their way toward a unified user Interface API and making the API less Objective C centric and more Swift centric, but until then, it will be difficult to come up with a “perfect” way of teaching Swift to a beginner.

    Having said that, I think you could make a 3 semester comp sci course where students did not have to worry about Human Interface programming until the second half of the 3rd semester. I will throw a rough draft of a curriculum, and expect people will disagree (as I am thinking of rearranging my own lists after I wrote them).. Arrays are much more involved these days than in the old days, so would have to be given more time. Also, I liked learning concepts using the UCSA turtle graphics uniut but I’ll defer to others what would be a good graphic learning add-on nowadays. I made the first semester fewer credits since we are talking about beginners. You could make an accelerated path for advanced students and push all into 2 semesters of 5 credits each. This doesn’t have to be a “college” course but an online course or alternate venue as well.

    1st Sem (3 credits)

    Text and Graphic Unit functions and interface
    Numbers, Strings simple data types
    numerical and boolean operations
    simple string operations
    if-then-else and conditinal if
    while loops
    functions
    arrays
    structs

    2nd Sem (4 credits)

    enumerations (basics)
    switch statement (basics)
    for loops
    optionals (basics)
    saving and retrieving from permanent memory
    closures
    classes (basics)

    3rd Sem (5 credits)

    dictionaries, sets
    advanced enumerations
    advanced classes , protocols
    functional programming (map, filter, reduce)
    error handling
    advanced strings and text handling
    advanced data structures ?
    projects(Apple API, WEB API, …?)

  • Like Richard, I learned Fortran in the days of punched cards. Were we ever excited when they installed teletype-like terminals with greenbar to enter your program! This single semester, taught to complete novices (Forestry students, no less!), covered nothing more than for loops, if-else, functions, arrays and variable types (strings, floats and integers) and printing. That simple set of knowledge allowed me, in 2 years of graduate school, to teach myself on an IBM system, the commands needed to process the data from thousands of fish caught and released after measurement, including averages and standard deviations, tabulated by location, and to start learning basic graphics on a Tektronix plotter. Building on this allowed me to learn Perl on my own, encouraged me to take classes in Java and C++ and these days, teach myself Python.

    My point is, students need, as Erica says, a simple foundation to understand HOW to logically decompose a problem into simple steps that can be successfully built into more complex structures. Iterative addition to the simple basics can add a “wrinkle” to what they already know, but if they can’t get the fundamentals, they will never go beyond rote learning.