1. 15
  1.  

  2. 13

    Tradespeople figured this out a long time ago. 20% classroom time, 80% working alongside a journeyman as an apprentice building real projects for paying customers. Do this for several years, and voila!

    Software Engineering is more trade than profession.

    1. 6

      The challenges of teaching software engineering are git, commandline fiddling, etc? What about the (essentially fundamental) problem that the discipline exists to solve problems at a scale that seem impossible to replicate in a classroom (certainly a 4 day course) — so you just end up parroting a bunch of stuff, hoping they remember enough so that once they mess it up in production they remember the advice you gave as an alternate approach.

      People seem to realize that programming can only be learned by doing (hence our programming courses involve programming). But I’ve asked a bunch of people who teach software engineering how they do that for, e.g., teaching students how to deal with large legacy codebases, and everyone says it’s too hard — they just end up teaching green field project design, at a tiny scale (i.e., the prototype that a professional team could put together in a few days).

      1. 2

        Well, the challenges of teaching software engineering are that you need to suffer a load of git and command-line fiddling before you can get to the point where you learn any software engineering. If it were at all realistic to dump people into a Smalltalk, LISP machine, or microcomputer BASIC interpreter, then they would not have those problems. They would, instead, have different ones…

        But I’ve asked a bunch of people who teach software engineering how they do that for, e.g., teaching students how to deal with large legacy codebases, and everyone says it’s too hard — they just end up teaching green field project design, at a tiny scale (i.e., the prototype that a professional team could put together in a few days).

        We don’t say it’s too hard. In the section on refactoring, for example, we give the student some existing code and encourage them to use the refactorings they know about to restructure the code, to help them understand it and communicate their understanding.

        1. 3

          Well, the challenges of teaching software engineering are that you need to suffer a load of git and command-line fiddling before you can get to the point where you learn any software engineering.

          This could be a massive endeavour, but… how about cleanly separating the teaching environment from the professional environments? You don’t really give a crap about Git when trying to teach version control. You don’t really give a crap about ls when trying to teach files and directories. You don’t really give a crap about C when trying to teach imperative programming…

          The tools we use professionally do embody the fundamentals you want to teach, and learning them will cause the students to acquire a host of transferable skills. But they will also learn some fairly specific or useless cruft along the way. Such as this idea of staging, which is only useful for fairly big patches, or the fact that git checkout -b my_new_branch is a shortcut for git branch my_new_branch; git checkout my_new_branch.

          We need a simple, limited command line that is made for teaching how command lines work. We need a simple, limited programming language that is made for teaching programming (or maybe one language per major paradigm). We need half done or buggy projects, made for teaching maintenance. And so on.

          Leave the “real” stuff for more advanced courses. And to squash any misgivings about not teaching useful stuff (I remember resenting being confined to the “Caml environment” (basically the OCaml REPL) instead of being taught “real” programming), take a few minutes to talk about all the uninteresting cruft “real” stuff comes with. That it will be taught, but that we need to start with the basics.

          1. 1

            What is the size of the codebase they are refactoring? There’s a real phase shift of how refactoring works, I think, once you are dealing with systems that are too large to actually fit inside your head. Either you need to make them instead be made up of smaller parts (which is a refactoring — oops!), or you need to figure out how to make changes that mechanically will be checked (obviously the language you’re using changes the tools available for doing this).

            That was something I never quite learned until being confronted with an almost completely untested, ~7 year old large and nearly unreadable ruby code base that nonetheless was making 7 figures for the client (enough that they wanted to keep adding to it, but not enough to do too much work). “Refactoring” that code involved adding tons of instrumentation and then carving out clean, tested code paths, that we knew, from testing and instrumentation, didn’t mess up the rest of the codebase. But these were (intentionally) minimal changes, done almost in parallel with the existing code, because untested ruby code is a pretty hard thing to wrangle.

        2. 5

          My condolences for being required to do this in only four days. I can fully appreciate now why teaching software engineering requires one semester, or maybe even two. I particularly like James Hague’s description of a pair of courses that he took.

          1. 1

            I took the MSc, which had ten one-week modules and a dissertation. This course is supposed to be enough of an introduction to that stuff to get people excited to go and learn themselves, but I had to misapply it by presenting it to summer school students who wanted practical advice on writing their summer projects. They got it, in a barrage of other things.

          2. 3

            only having an hour for OOP is a sin

            No it’s not. Really. Sure, some things OOP uses should be presented, but I think none of them are exclusive to OOP: stuff like modularity/encapsulation/abstraction: the idea that you write a piece of code, and others should be able to leverage that piece of code without having to study it in its entirety. That piece of code can be a function. Or a module. Or a class. Or a package. Or a microservice… OOP can be used as an example for the above, and I don’t think you need more than one hour.

            Now inheritance & subtyping? Animal/Dog Shape/Circle nomenclatures? Nah, you can leave them out.

            1. 1

              Maybe try to teach how to play the violin in four days instead? ;-)

              1. 1

                I’m happy I didn’t have any teacher approaching the subject this way, imagine being forced to learn SVN, using the DOS command line and the likes.

                How does the saying go: give a man git and he will git once?

                1. 0

                  I think it’s: give me git once, shame on me etc.

                  1. 0

                    s/shame/blame/

                    :D

                2. 1

                  I think there are real opportunities to shave the coursework down to the very essence. It’s probably not worth teaching git upfront, for instance. Making students work through not having source control for a while will put them in a much more receptive frame of mind when they do end up learning it. It’s much easier to learn something when you’re excited about how it’s going make your life easier rather than learning for the sake of learning.

                  1. 1

                    A Git Clippy might help a bit. “You have uncommitted changes, use git add to stage them for commit”. Also, nano is much easier to quite than vim. Why not give people VMs with development environment preconfigured?

                    Seriously though, I believe a software engineering course should take people through designing and implementing a piece of software other people can use. Expressly forbid helping them directly, outside of a bug reporting process. Perhaps make it a requirement to implement everything your classmates ask for, or justify why it shouldn’t be done. The tooling people can learn on their own. What we really should teach is how to be aware of the problems of evolving requirements and growing codebases.

                    1. 1

                      git, in particular, is decidedly unfriendly. What I want to do is commit my changes. What I have to do is stage my changes, then commit my staged changes.

                      I disliked the Git commit system for many years.

                      As you said, for a newcomer staging can be a confusing and seemingly redundant part of the commit process. So for a long time I just dealt with it. I would make my changes, then add/commit at once. Earlier this year I finally realized the point. Previously when I would make even a small change, I would add/commit/push. This gets silly when you are talking about changes less than 10 lines, unless it is an important change.

                      So I created a script that checks the index, and if enough lines have been changed then it prints that a commit can be made. It also checks when the last commit was done and allows smaller commits if enough time has passed.

                      This is also helpful as sometimes when I am making a new change, I might quickly tweak it or revert it soon after. Now this doesnt end up as 2 commit but just the single commit as the first change never made it past the index.

                      https://github.com/cup/suede/blob/master/git/git-board.py