Landing : Athabascau University

How I am learning to code

During my sabbatical I am learning to program. Given that I have been programming, on and off, for about 30 years (actually, more than 40 if you count a few weeks learning machine code with a single punchcard machine in primary school before picking it up again in my early 20s) and have been known to teach the subject, this may seem like an odd thing to want to do.

The thing is, though I do know a reasonable amount about the theory and best practices of programming, when it comes to actually writing code I have always been a hacker rather than a programmer. I actually think that hacking is a more useful skill than programming, but it's a complementary skill, not a replacement, and it comes at a cost. Hacked code is seldom maintainable, is seldom easy to make with others, and is seldom super-efficient, unless the hacking process is focused on efficiency, in which case it usually comes at the cost of even less maintainability. I can mostly make a program do what I want it to do but I have seldom put in much time to really learning to do it right. On a more esoteric level, which is the deeper agenda of my sabbatical research, I am extremely interested in ways to research using programming as the research method, so it is useful to have a deeper understanding of the subject and greater experience of the ways it can be enacted. I think there are ways of programming that can be an exploration of the unknown as much as any form of research, and I would like to build a robust methodology for doing that. In fact, that is the real research agenda behind what I am doing.

The conventional approach

My initial plan was to take a few MOOCs to teach me more about some core technologies - xMOOCs, to be precise: large-scale but highly conventional courses that have a strong structure, restrictive processes, clear learning outcomes and tight scheduling, whose limited concessions to online pedagogy are mostly concerned with splitting up a lecture into smaller chunks. I also considered some of the paid varieties that offer a more self-paced but otherwise similar approach.

This was not a bright idea, for reasons that I have written and spoken about many times, so I really should have known better. In fact, my entire teaching strategy for well over a decade has been a strong implicit criticism of the methods used in xMOOCs and courses of their ilk, which is to say the majority of courses, so it was weird of me to think that I might overcome their weaknesses and find them useful.

Enrolling on MOOCs was an interesting if unfulfilling experience. In the field of programming I am a slight outlier for typical MOOCs because I know a great deal about some things at many levels, and very little about others. This means that the bulk of courses for beginners bore me senseless but, for courses aimed at intermediate and advanced programmers, I am way out of my depth in places while finding other parts dull and obvious. Too smart to start, too dumb to progress. Naturally, after a week or two on a smattering of courses, I gave up. This was a waste of my time and highly demotivating. But I am just a slightly more exaggerated variant on the typical taker of any course, MOOC or otherwise. Any content-oriented, objectives-driven, structured course of a conventional nature has to aim at a particular kind of learner with a particular set of knowledge and skills. The chances that any actual learner is exactly like that idealised model are vanishingly slim. A good teacher and a strong learning community can take the edge off that and allow a bit of flexibility and adaptation, but it's a structural flaw in conventional courses that always raises its ugly head unless we adopt pedagogies that are very challenging to scale well to MOOC sizes, or build highly intelligent adaptivity into the course - much more intelligent than any I have seen in a decade or two of close involvement with the adapative hypermedia community. 

I have tried books, and got some value out of them. I find most classic textbook style approaches mind-numbing for much the same reasons as I don't like xMOOCs, but the ability to skip and cherry pick means they can be moderately useful, though they are seldom worth the cost, both in money and time. Random access combined with no pressure to submit assignments is a fairly acceptable combination, but it is not particularly efficient and far from ideal.

Another way

So what is my solution? I will be posting a bit more on this over the coming months, but this is what I have been doing so far.

Needs

First of all the needs: my most pressing need is to learn to program Elgg, the framework on which the Landing is based and that underpins a couple of other learning-oriented sites I am building, so that is my central focus. I already have some pretty clear ideas about some of the things I want to do with that though, in accordance with my research focus, my assumption is that this will change as I progress and exend and/or discover the adjacent possible. The more I learn, the more the adjacent possible will expand. My intent is to soften my horizons and extend them with every new thing I discover.  That is why I am learning to program and that is why I think programming could be a great research methodology, not just in things like artificial life, large-scale simulations and analytics, but as a means of exploration in itself.

Elgg is written in PHP, that I know fairly well, along with HTML, CSS, JQuery, MySQL and a few other things with which I have a passing familiarity. However, my skills are pretty rusty in places and, more importantly, knowing these things is just a prerequisite before hitting the big learning hurdle: Elgg itself is a very complex set of APIs, methods, patterns and procedures, with thousands of functions, classes and other parts of its extensive library. Simply hacking the code doesn't work if you want to produce maintainable code that plays nicely with the countless other Elgg plugins and its core. You have to know the library inside out and to have a firm grasp of the core API. Elgg is at least as complex and subtle as any programming language, but it operates at a higher level. It's the difference between building with raw materials and a decent set of tools, and making something out of Lego Technik. You start at a higher level and can achieve more, faster, albeit with some notable constraints based on the pieces available. Of course,  you can make your own pieces once you hit that barrier.

Conventional solutions

Learning Elgg is a little challenging. There is only one fairly basic book on Elgg, plus a basic wiki-based (now Github-hosted) introductory website and a bunch of technical documentation, and there are no courses on the topic that I am aware of: the courses I enrolled on were about pieces like JQuery, PHP, etc. There are also a few bloggers that occasionally share hints and tips. However, there are quite a few thousand examples of plugins to learn from, so the classic approach to learning Elgg is to pull apart some plugins, modify them, and use the ideas and techniques to build your own. Unfortunately, many of the thousands of available plugins are badly written hacks, even some of those found in the core plugins, so it is quite hard to judge the quality of each solution, especially as most work as intended so it is not obvious that they are doing things badly. Learning this way is not a mechanical process of learning a skill so much as a creative and critical interpretation of a range of possible solutions. It takes skill to gain skill, which makes it fairly painful, and not too easy to make the transition from 'hello world' to something useful.

Google

As for most Internet users, Google is my first and best friend on my learning journey. Finding stuff on the Elgg community site (itself written in Elgg) is not great and sticking to the site itself means failing to find solutions elsewhere, so Google's intelligent crowd-fed algorithms and high speed are an ideal combination.  In fact, the native Elgg search that used to be provided for the Elgg community site has been replaced with Google, albeit limited to the site itself, because it works much better. Google is the world's most successful and powerful learning technology and I love it. 

Help, advice and inspiration

Typically, Google leads me to two main classes of site, beyond the Elgg community and Elgg documentation sites. The first class of site is crowd-based. It is most well represented by Stack Overflow, the world's greatest resource for programmers seeking solutions to problems or starting points for further exploration. It is great for very specific issues as well as broader tactical or strategic concerns. What I particularly like about Stack Overflow is that the best solutions bubble to the top naturally through its various rating mechanisms, but it is always possible to explore alternatives and to find (and even engage in) dialogue about why one solution is better than another. It is great for finding solutions to specific problems but at the same time allowing depth and multiple perspectives to help me learn more. It is a classic example of the wisdom of a crowd, utilizing a huge set of interested parties combined with efficient collective algorithms to draw attention to the best solutions.

Another crowd-based approach that offers similar value for slightly different reasons is the official PHP manual, which provides not only direct help but also copious conversations and examples provided by the community. Unless you know precisely what you are looking for it is nothing like as effective as Stack Overflow at finding good solutions to specific conundrums quickly because it lacks the collective algorithms that drive good solutions to the top. This is not to say it is less useful though - it is just different. It takes more effort to sift through the conversations but, because the manual keeps the topics very tightly delimited, it is mostly relevant and you get to learn a lot of other things along the way and to explore the command or function a conversation refers to in a fair amount of depth. Not all discussions and examples are immediately useful, but it helps to develop a mindset, to think as programmers think.  

The second class of site returned by Google is the short intentionally designed tutorial, most well represented by W3Schools. W3Schools is a venerable tutorial site for Web programming that I have been recommending to students for about a decade now. It is both a reference and a hands-on active experimentation site, that keeps to a very simple and effective pattern for teaching that just works. Knowing a little about what it is teaching is helpful because I can recognize its limitations: it does not always encourage best practices, is a poor guide on its own, and it has a fair number of legacy tutorials that pop up from time to time. But it is about as good as it gets if you know what you are looking for but you are not sure of the details.

I'm surprised that I only rarely bump into video tutorials like those most obviously represented by the Khan Academy, but this may be the result of Google learning my preferences, which tend not to be for video. Though video can sometimes be helpful when learning complex interfaces and controls, and can be good for getting inspired, unless it is incredibly short (a minute or two at most) video is a very slow way to learn most of what I need to learn: it provides nothing like enough random access to precisely what I need. At a small scale, video suffers the same kind of problems as courses do at a larger scale: too much irrelevant stuff, too little control. With some important exceptions, it typically provides the illusion of being engaged in learning without actually getting the job done, with a lot of unwanted padding. I rely heavily on video when I am learning a musical instrument, but it is not great for learning to program when you already know most of what it is telling you.

Getting it wrong

Trial and error, combined with a reflective process to ensure lessons are learned, are important parts of the process and among the most basic and crucial of human learning strategies. Finding out how and why some things work better than others, and many things do not work at all, takes up a great deal of my time. While I can often code 90% of a program in a couple of hours, I can and do spend days on a couple of lines or one tiny piece of functionality that can sometimes result in a complete rewrite of everything when the reason for the problem is revealed, or that may equally be down to a single missing bit of punctuation or misspelt variable. This is and has always been true for all the code I have ever written. This would be frustrating were I not learning as I go, and that learning is the main purpose of what I am doing. It's a conversation with the machine, in which the machine is an important teacher. I've found it useful to make a note of what I have discovered along the way, and/or to keep snippets of code in my IDE (integrated development environment) for future use. This is a difficult bit of discipline to maintain: it is awfully tempting to leap from one discovery to the next until a solution is reached, without working on retaining the learning that occurs along the way.

Our tools shape us

Finding the right IDE was an important step on this learning journey. After trying old open source chestnuts like Eclipse and Netbeans, as well as simpler faster tools like Taco and TextWrangler (both of which I like and use for many things) combined with other tools for versioning, documentation, searching and source control, I eventually discovered, through a blog post from an Elgg developer that I know and greatly respectCoda. If you are a Mac user who is trying to program, I cannot recommend this too highly. It is worth every penny of the few tens of dollars it costs and I will even forgive that it is not open source because it works so well. Coda provides a very elegant environment in which I can do most things I need, including searching documentation for most programming languages, handling version control, autocompletion of code, debugging, running an SSH terminal, managing files locally and remotely, and a whole lot more. As much as a tool it is a teacher, making good practice easy to accomplish, with complex things simplified to provide the least resistance. From simple things like knowing which functions and variables you have already used and offering them as suggestions or intelligently indenting code, to more complex things like making the overall structure visible and accessible, it nudges you to work smartly. It doesn't force you to work in a particular way, but it makes it easier to do things properly. While most good IDEs offer such features, I have never found one that does it so fluidly and transparently as Coda.

Coda does everything but it is not always the best or most efficient tool for the job. When Coda reaches its limits other desktop tools are very useful. Simple desktop search is a big one, given that I have a lot of different code scattered in several places, and the Mac is super fast at finding pretty much any text in a wide variety of documents.  I also use dedicated versioning apps (Versions and Github clients) and a dedicated FTP/SFTP tool, Cyberduck. These dedicated tools have some more sophisticated features that come in handy sometimes. The local command line is another vital element of the mix because, sometimes, things are many times quicker and easier that way. I have various widgets that do things like generate lorem ipsum for testing too, as well as a wide range of browser plugins that help with debugging. My favourite of these is the Firefox Web Developer Toolbar, that I have used for many years and that saves me hours of debugging effort a week. Various developer plugins for Elgg also help a lot. Again, these tools are not just about efficiency but also about learning: the things they do help to shape the way I see and understand problems. They embed expertise.

The physical environment helps too. Multiple monitors are great for programming because you often find yourself working with multiple files and tools at the same time. I normally have three or more browsers working at once for code testing, for instance. This is about not letting the mechanics of the technology get in the way of learning. Sustaining a train of thought is simpler if it is all laid out in front of you.  I have thought about but not yet found a way of implementing at a reasonable price an e-paper wall, essentially an entire wall that is completely configurable to display anything at fine resolution - that would be roughly the perfect size for working on learning projects in general, but especially for software development. A monitor or projector is too bright, though backlighting might be useful. Similarly, it is good to have a fast computer and a fast network. I don't know exactly how much time I spend waiting for the machines but it is a lot. Not all of it is wasted - those enforced pauses are a bit like smoking breaks used to be, a chance to compose yourself and reflect. 

Planned serendipity and opportunism

My learning is opportunistic and intenionally serendipitous, partly as a result of discovering things along the way in things like Stack Overflow conversations, but mainly because of subscribing to Elgg community groups for developers and beginners. These are full of ideas and techniques, conversations that draw my attention to things I had not noticed or didn't think were relevant, ways of using Elgg to do things I didn't think of or that did not seem important. 99% of it is a distraction and irrelevant, but that 1% is great.  At first, this was mostly just a bunch of messages from a set of largely undifferentiated people but now I am aware of a few smart people, am coming to recognize the idiots and the genii, and am being drawn gently into a network. There are many occasional visitors, strangers and outsiders here, but there is also a very perceptable and fairly consistent set of persistent contributors. It is both a large set of people who share nothing but an interest in common, and a smaller network of people who know something about one another, as well as a more cohesive group who collaborate to develop the core. Each social form supports the rest, all coexisting happily. It is not a single collection of people but a lot of overlapping ones, with varying degrees of social connection and/or commitment. This means that the perils of group-think and the problems of filter bubbles in networks of people you know are very much softened.

Another big part of opportunistic learning will form the basis of a later post, probably a paper or two, and is a lot of the reason I am spending my sabbatical doing this. Creating something (anything) opens up opportunities to create more that would not have been possible or simply wouldn't have occurred as something to do before creating it. It increases the adjacent possible. To give a very simple and banal illustration of this, I recently created a group tag menu plugin. The initial specification for this was to allow group owners to provide a list of tags that would be displayed as a menu in the side bar of a group, clickable to show all things in the group tagged with the selected tag. The reasoning was to allow group owners to do things like provide a set of topics for a course, that would be automagically filled up by people in the group tagging things. I was basing the idea for this on an old Elgg plugin that had been abandoned by its creator five or six years ago, that did much the same thing for blog posts.   I realised very quickly that it would be useful and fairly simple to program to provide a default menu of the most popular tags in the group for those that did not want to create a manual list, so I added that option, in the process learning a bit more about Elgg's approach to metadata and annotation. As a result of this I then realised that it would take little extra effort to link the title (group tags) to a page showing a tag cloud of all the tags used by the group, so I added that too. Along the way I discovered that the basic search functionality of Elgg that I had intended to use was awful, so I wound up reimplementing that, again discovering new things about Elgg as I went - it seemed daunting but was actually incredibly easy. There is no particularly good reason that I could not have specified all of this at the start but it didn't occur to me to do so until I had created the plugin and saw what it did and how it behaved, and also what the code did and how it did it. Had I written it differently, these options might not have been easy and I might not have added them. This would have been a pity, because they actually turn out to be at least as useful as the specified functionality, and probably more so. What was happening here was an exploration of the design space that is caused by the design itself. Gould talked of exaptions, features of a design that are simply a byproduct of the way something is built or evolves, that later turn out to have some value in themselves. Another word commonly used for these is 'pre-adaptations'. The improvements I made are not quite exaptions in the strict sense used by Gould, but they are close cousins. A design that started with one intent reveals opportunities to do more that we can take advantage of. The same thing happens when we write stories or papers - what we write creates scaffolding that leads us in different directions than we originally planned, often much more interesting and better ones. My friend and mentor Richard Mitchell once told me 'I don't know what I think until I have written it' - writing is a way of scaffolding and creating thinking as much if not more than a way of writing what we think. Programming is like that, but on steroids, because we create things that behave, and that interact with people in very tangible ways. They become part of the conversation that creates knowledge and that builds further learning. It is probably a similar process for designers and architects though, on the whole and in some ways, the feedback loops for them are longer and more sparse. Programming is quick by comparison, and the results are visible instantaneously. It's maybe more like playing with clay, except that the clay we create is alive and does stuff. This echoes religious myths: programmers are gods in their tiny, virtual, isolated worlds that they create and populate with code.

Applied ignorance

Interestingly, the fact that I did not know much about the options at the start when building my group tag menu might have been an advantage, as Clay Shirky memorably opined in his essay The Bayesian Advantage of Youth. If you do not know what is possible it is equally true that you do not know what is impossible. And, of course, few things are actually impossible. Sometimes, knowing too much can be an impediment to learning more. Experts know the solutions to known problems and do not necessarily spend time exploring the problem space further. To be an expert is to see patterns, so anything that does not fit the pattern is either shoehorned into it or ignored. This is one mighty good reason to be interested in many things and to be a perpetual beginner at some things. Apart from constantly branching into new areas, I don't have a great solution to this problem yet. I am struck by the number of times I read in Elgg forums that 'x is impossible'. Of course it isn't - we are talking about Turing machines here that can be made to do anything that any other Turing machine can do. It is impossible until you approach it with a different mindset. This is another great reason for the support of crowds in learning, because diverse minds and different eyes see similar problems differently. 

The flipside of ignorance is that it is hard to know what questions to ask - framing a problem is nine tenths of the solution in most cases. And ignorance is frustrating: knowing that there is a solution but not knowing where to begin is not the most motivating thing in the world. There has to be a balance.

Github

Github is pure magic, plain and simple. It allows me to branch code by other developers, see in detail not just the code but also how they have developed it, to see multiple branches and multiple solutions and even, if I find a solution no one has yet discovered, to feed it back with a pull request. It lets me talk with developers, open issues, view timelines and branches with ease and sophistication. This is social networking without knowing the people involved, people working together as a team without collaboration, a remarkable and elegant way to harness a crowd to help the crowd to learn while at the same time building incredibly sophisticated software. It is revolutionary, it is brilliant. It is the next stage of evolution for things like Wikipedia, which is another of my favourite resources and often my starting point when one of the other tools presents me with a new technology or idea. I wish I had thought of it. Clay Shirky agrees

Friends 

There are a few individuals with whom I work more closely - friends, students, colleagues - with whom I can discuss ideas in detail, from whom I can gain inspiration and motivation, who can provide multiple perspectives and shared experiences. Mostly these do not tell me how to do something - they instead let me explore my own thinking and enhance it with their own. Without such people I would probably not bother doing any of this and, even if I did, the result would be poorer and less interesting.

Connectivism, distributed cognition and conditions for learning

The process I am following is most easily described as Connectivist. It is also and more fundamentally about distributed cognition. This is not simply a method for me to learn but a way of thinking about learning and knowledge that is fundamentally at odds with the structured process of education that we are familiar with. In my teaching I have tried to take advantage of such tools and methods but it is quite hard to do this properly when learning outcomes are fixed and prescribed, and assessment is aligned with and drives the course. Some of the elements that seem crucial here are:

  • learning happens best when you need to learn.
  • creation is a self-perpetuating process: the more you create, the more you are able to create.
  • people make things worthwhile - not just supporting the process, not just providing information, but creating meaning in it all.
  • problem-solving is not just about solving a problem - each solution is a scaffolding that lets you solve more problems as well as a creative engine that opens up more solutions and opportunities to you.
  • tools don't just help you to get things done - they shape the ways you do them, passing on and embedding the knowledge of their creators, and open out new avenues that would not be there without them.
  • there is no such thing as wasted time when you are actively engaged in learning and you are mindful of what you are doing and how you are learning. Efficiency is another issue: but efficient for what? 
  • diversity matters and different forms of social engagement have different value in providing that diversity.
  • crowds can teach in diverse ways.

I will return to some of these themes in later posts.

 

 

Comments

  • Anonymous January 14, 2014 - 6:18pm

    What a fantastic post.

    Your point that the connectivist process is "fundamentally at odds with the structured process of learning" seems to be related to an observation that I have had that some aspects of contemporary computing (ubiquitous computing and crowd-based systems) seem to be fundamentally at odds with the structured process of enterprise IT. (Been struggling with this lately)


    - Simon Chandler

  • Anonymous January 16, 2014 - 1:01pm

    Hi, Jon!!!! It's Guadalupe from the journal Revista Mexicana de Bachillerato aDistancia in Mexico City (where you're a member of its's editorial committee). I need to contact you. I called, but there is a message machine and I wrote to your email, but there is an automated response. Will you please write to me? Thanks a lot!!!!


    - guadalupe vadillo