A Year of Teaching Swift

We are nearly at the end of the school year here in Scotland and I wanted to take some time to reflect on the experience of teaching the Computer Science curriculum this year using Swift Playgrounds and Apple's Learn to Code curriculum.

Background

One of the projects I have been engaged with over the past few years is to move our Computer Science teaching out of the senior years and into the earlier years of secondary school. I'm not done with this yet but we are getting there.

In 2016/17, I taught the following courses:

  • Primary 7 (6th grade) - Introduction to Computational Thinking using Pixar in a Box
  • Primary 7 (6th grade) - Introduction to Computer Programming with Hopscotch
  • Secondary 1 (7th grade) - Learn to Code 1 & 2
  • Secondary 2 (8th grade) - Learn to Code 1 & 2

I taught the same course to S1 and S2 this year because we were still making the transition and this class hadn't done it before. In general, we obviously wouldn't teach the same course two years in a row.

I want to review the experience of teaching Learn to Code 1 and 2 here. Pixar in a Box is another post for another time but the idea with that is to promote the ideas of Computational Thinking without necessarily going straight to code.

Learn to Code

In the Learn to Code curriculum, there are three books called Learn to Code 1, 2 and 3 which use the Swift Playgrounds app as their learning tool. There are also two earlier books called Get Started with Code 1 and 2 which use either Tynker or Codespark Academy, and two later books called Introduction to App Development with Swift and App Development with Swift. These later two books use Xcode and macOS and extend up into college years. I'm only going to focus on the Learn to Code books here.

Learn to Code 1 and 2 were introduced alongside Swift Playgrounds at WWDC 2016. I started teaching them in October 2016, just after iOS 10 shipped.

Course Structure

The structure of the two books are really of a piece. Together, they provide a curriculum that covers much of the basics of a Computer Programming curriculum: commands, functions, loops, conditionals, variables, constants, arrays and basic object oriented programming.

In general, I think that the books introduce most of the concepts in an accessible way and do a good job of providing a staged progression through each of the topics.

Both classes that I taught Swift to this year had one term's prior experience in programming with Hopscotch and had also been through the Introduction to Computational Thinking class.

The Learn to Code World

Each of the books provide a series of exercises in each chapter that introduce and progressively challenge the skills that students are supposed to be learning at that point.

The format is nearly always the same: there is a character in a 3D puzzle world and the student is required to write code to "solve" the puzzle - however that is defined in the specific challenge.

In the world, there are collectible gems, toggle-able switches, moveable platforms and portals that transport you to other parts of the map. All of these make for quite an engaging game-like world and provide enough variety that the challenges rarely seem repetitive.

One issue I have with the constant use of a 3D map based approach is that, in my experience, it does disadvantage students who are not as strong in spatial reasoning and to some extent advantages students who are strong in that area but may not be as good at abstract reasoning as others.

Swift as a Teaching Language

I have taught a range of programming languages over the years. Primarily Visual Basic, Ruby and Python. I liked Ruby the best so far and hated Python for its crazily inconsistent library programming.

Swift is the closest thing to Ruby I've used. It is very consistent and predictable in its syntax and mostly makes sense as you read it. My only actual bugbear in the syntax that you explore in Learn to Code 1 and 2 is that the use of let to declare a constant isn't as intuitively obvious to students as var is.

Swift is a pretty decent teaching language at this level. It doesn't require much in the way of obscure ceremony or boilerplate code. I've seen students really start to bend the syntax to their will in some of the later exercises and this is really pleasing to see.

The Student Experience

From observation and talking with students during the class, I observed a few significant differences from any previous programming curriculum that we had used.

In times past the experience was that, if you were an able student in Computing, you would get your programs working. If you were not an able student, your experience would be almost insurmountable challenges to get anything working. Working or not-working was the differentiator in the class.

In the Learn to Code curriculum, I found that everyone got something working. The difference between the stronger students and the weaker students then was more to do with evaluations of the complexity of their solution, the understandability and style of their solutions or other factors like memory and time efficiency.

I have never really had these kinds of conversations in classes at this level before. It has been an incredibly satisfying year to get the opportunity to debate which of three possible solutions is the 'best' for a given problem and, further, what definition of 'best' we should accept.

For example, we looked at some solutions where students had written extremely compact code. It became a bit of a competition in the class to see who could solve a problem with the least code. Of course, this is almost never a desirable metric in practice, so I spent quite a lot of time teaching about Brian Kernighan's maxim:

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

I can't point to many areas of the course that students found overwhelmingly difficult. The course is well-paced with enough practice on each technique that students can consolidate their learning. The later section in Learn to Code 2 in which Arrays are introduced could use a slightly shallower learning curve, but it wasn't too difficult overall.

The Teacher Experience

Apple provides a teacher guide for all of their courses. In the early days I kept to that guide quite closely but as the term wore on and I gained more confidence in the material, I felt freer to move away from that document. This was good and bad. Some of the things in the teacher guide I was kind of uncomfortable doing in class - there's one chapter that asks you to lead the class in dancing and that is simply not going to happen. At other times, though, I think I could have delivered a better class if I had used their lesson starters instead of my own.

Apple's teacher guides also encourage you to use Seesaw to gather evidence of the students' work. I quickly abandoned this practice as the sheer volume of material produced was quickly overwhelming. Between screenshots and code exercises, my class of 12 could easily produce 50-60 individual items that I was supposed to look at and approve in Seesaw in one class hour.

Instead, I took the approach of simply being far more active in the classroom. Instead of silent work for an hour and then offline grading, I asked the students to show me their solutions as they completed them and we would have conversations about the success or failure of their solutions live in class. This was, in some ways, much harder and more active work for me but it meant that I got to have those qualitative conversations about code that I had been looking for for so long.

Assessment

What Learn to Code 1 and 2 rather lack is any way to formally evaluate a student's learning. A rubric is supplied, which I used, but there are no tests as such and no homework exercises. I ended up designing my own end-of-year test for Learn to Code and used the results of that test alongside the Learn to Code rubric to report to parents.

During the year, I also designed a series of weekly homework exercises based on Learn to Code 1 and tested them with the students going through the class this year (their results were not formally recorded as grades).

I have always found it difficult to set homework in computer programming classes because there is so little support available at home in this area that students can have wildly varying results. Instead, what I have done, is focus on code comprehension rather than code writing in exercises that will go home. I don't ask students to write code outside of class but to read code that I have written and either debug it or describe its behaviour. I'm in the early stages of doing this but I think this is a more sensible approach to programming exercises without teacher support.

Timing

Teaching Learn to Code 1 and 2 took me about 60 class hours over the course of this school year. I think this would have been slightly longer if I had stuck more rigidly to the Apple teacher guides and gone through all the exercises before letting the students code.

On reflection, I think that covering both Learn to Code 1 and 2 was maybe just a little too much for one school year. The learning went very well overall but both I and the pupils were somewhat running out of steam by the end of LtC 2 and I think we were all glad to finish when we did.

Future Improvements

I am definitely going to continue teaching Swift at school. As we go forward, I think a few improvements could be made.

Firstly, I would like Apple to publish a road map for future Learn to Code books. When I started planning the year, Learn to Code 1 and 2 were the only books in existence and we didn't know that there would ever be a Learn to Code 3 until the day it shipped. We plan learning experiences over the long run and it would be very helpful to know what's coming - or even if nothing else is coming.

I don't think many changes are needed in the Learn to Code 1 and 2 course itself. I'm looking forward to teaching it again. However, the aforementioned lack of summative assessment is something that would be worth looking at.

I would like to see a Learn to Code 4/5 where some iOS APIs are introduced within Swift Playgrounds. SceneKit and MapKit might be good candidates for "fun" APIs but I'm also interested in using lower-level network programming to teach about the structure of the internet.pl

The Swift Playgrounds app has worked well for us in general but a few things could help:

  • I would like to see a "teacher screen" mode where the code is much larger for the students to see.
  • Power efficiency was an issue at some points during the year but recent updates to the app have improved that significantly.
  • Some ability to transfer individual solutions between devices without having to transfer the entire book would be welcome. Sometimes you need to give a student a complete or partial solution for various reasons.
  • The ability to extract an individual page of a Playgrounds book would be convenient. Sometimes you want to use individual exercises by themselves.
  • You currently can't reset the in-book world to its initial state without re-running the program.
  • More debugging options would be helpful, such as breakpoints and variable inspectors.
  • When the books get updated, a detailed explanation of what changed and why would help. It's weird when your 'textbook' changes out from under you.
  • Integration with Apple Classroom to be able to open students directly into a particular exercise.

Overall, teaching Swift has been a pleasure this year and I look forward to doing more!