Archive for the ‘Learning’ tag
Learning and Situated cognition
Sumeet recently blogged about the new style ThoughtWorks University that he and the other trainers have introduced and although I only got to see it in action for a few days it seemed clear to me that it was an improvement on the original version.
The questions being asked, discussions being had and situations that were coming up were pretty much the same as I've seen on any software project that I've worked on.
One particularly interesting thing which came up a few times was that there was a 'them vs us' feeling between the analysts and developers.
This is certainly an example of a situation which didn't come up on the project when I participated in ThoughtWorks University 4 years ago where we only had a one week simulation.
It is however a situation that does come up and on the projects I've worked on it certainly can feel like you're fighting the analysts. They're trying to balance the wishes of the client as well as those of the developers and to developers it can often seem that the analyst is just being difficult for the sake of it.
The cool thing was that the grads then came up with different potential solutions to this problem and they were pretty much the same solutions that we've used on projects I've worked on.
While discussing a different topic with Dave Cameron he pointed me to the Wikipedia entry for 'situated cognition' which "posits that knowing is inseparable from doing by arguing that all knowledge is situated in activity bound to social, cultural and physical contexts".
The following quotes seem to explain why, in my experience at least, I learn way more effectively when working with colleagues on projects than I could ever do on an out of context training course:
Knowing emerges as individuals develop intentions through goal-directed activities within cultural contexts which may in turn have larger goals and claims of truth.
Knowing is expressed in the agent's ability to act as an increasingly competent participant in a community of practice.
Learning must involve more than the transmission of knowledge but must instead encourage the expression of effectivities and the development of attention and intention that reflect real life learning processes
I think this new style TWU gives grads an even better start to their ThoughtWorks lives and I hope to take part as a trainer for one of the terms later in the year.
The prepared mind vs having context when learning new ideas
I'm currently working as a trainer for ThoughtWorks University (TWU) and the participants have some Industrial Logic e-learning material to work through before they take part in the 6 week training program.
I've been working through the refactoring/code smells courses myself and while I've been finding it really useful, I think this was partly because I've been able to link the material to situations that I've seen in code bases that I've worked on over the past few years.
It would have been interesting to see if I'd have got as much value from going through the material 4 years ago before I started working at ThoughtWorks and didn't have a range of code bases to relate the patterns to.
My thinking is that I would have found it more difficult to see the value of the material and that the approaches described would just have seemed 'obvious' despite the fact that I've made pretty much all of the mistakes that the training looks to address!
About a year ago I wrote a blog post where I described the value of re-reading books and one point which I'd forgotten is that even though it may be hard to relate to some ideas the first time you come across them it's still valuable to read about them anyway.
It helps to prepare your mind for when you eventually come across some code where the idea can be applied and Krishnan pointed out that this was actually part of the feedback received from the current TWU participants.
I think this is probably a good example of a variation of confirmation bias at work in that since we've been prepared to see certain patterns/potential to use different refactorings in code when we do come across those situations in code we're much more likely to see those situations.
Krishnan pointed out that it would still be very useful for the TWU trainers to refer back to the Industrial Logic material when we come across those patterns in the project simulation that we run as part of TWU.
I think this is the most important part of the process as it will help to reinforce the learning.
I'm still curious whether there ever is a time when it makes sense to delay learning about something until we have more context.
I find that when I'm learning about something which goes way over my head I'll often stop doing that and pick something else to look at which I can relate to a bit better.
I try to go back to the original material again later on but what I find often happens is that I'll come across it in the future more by coincidence than design and this time it will make more sense.
Is 'be the worst' ever limiting?
One of my favourite patterns from Ade Oshineye and Dave Hoover's 'Apprenticeship Patterns' is 'Be the worst' which is described as follows:
Surround yourself with developers who are better than you. Find a stronger team where you are the weakest member and have room to grow.
Be the Worst was the seminal pattern of this pattern language. It was lifted from some advice that Pat Metheny offered to young musicians: “Be the worst guy in every band you’re in.” Pat’s advice struck a chord with Dave, and was one of the reasons he started writing this book.
Since I started working at ThoughtWorks it hasn't been that difficult to follow this pattern and I've been the least experienced developer on the majority of teams that I've worked on.
I always thought this was a pretty good thing as since I'm always surrounded by people who know much more than I do about various aspects of software development the opportunity to learn is very high.
Recently conversations with several different colleagues leave me questioning whether at some stage we need to move away from this pattern, perhaps temporarily to improve skills in other areas.
The authors do cover this a bit in the book:
Being in a strong team can make you feel as if you are performing better. The other members of that team will often prevent you from making mistakes, and help you recover from mistakes so smoothly that you won’t realize that you may not be learning as much as you think. It’s only when you work on your own that you will see how much your team increases your productivity and realize how much you have learned.
Making technical decisions
One area in which I've noticed that this is true is when it comes to making technical decisions on a project. Quite often I find that even though I have an idea of what the solution to a problem should be I end up deferring the decision to someone more senior in the team.
I don't think there's a problem with discussing solutions with others in the team but it certainly seems that it would be a better learning experience to be in a situation where I was forced to make the call and then see how things went as a result of that decision.
It's certainly possible to engineer a situation where you have to make that type of decision by working on open source projects but it's still useful to get experience on real projects as well.
I guess the easiest way is to be on a team where you aren't the worst so that by default you'll end up in a position where you have to make those calls.
An alternative is for more senior people to encourage others to make decisions with the knowledge that at least they will be there to help recover the situation if it goes wrong. I've seen some of my colleagues use this approach and it seems to work reasonably well.
It's still not a perfect approach though because often someone more experienced may know intuitively that an approach isn't going to work but will struggle to explain why they know that.
Solving problems
The other situation where 'be the worst' is perhaps limiting is when it comes to solving problems on a team.
At the first sign of being 'stuck' there is a real temptation to ask someone for help even though you might be able to solve the problem alone given enough time.
A colleague in my first job suggested that whenever I got stuck it was worth struggling with it for an hour before asking for help. I don't know if that's too prescriptive but there certainly seems to be some merit in the idea.
I'd be interested in hearing others' thoughts on this and whether there is in fact a point at which you can grow more by focusing less on learning all the time from others and more on stretching yourself to find situations in which to take the responsibility for making decisions based on that knowledge.
The 'should' word
I've been reading Coders at Work recently and one of my favourite answers from the first chapter interview with Jamie Zawinski is the following:
I think one thing that's really important is not to be afraid of your ignorance. If you don't understand how something works, ask someone who does. A lot of people are skittish about that. And that doesn't help anybody. Not knowing something doesn't mean you're dumb – it just means you don't know it yet.
A variation of this which I've noticed myself doing is internally telling myself that I 'should' know how to do certain things much better than I can.
This is most typically the case when I'm struggling with something on a new project that I'm working on and while it is indirectly useful for helping to identify areas that we can work I think the voice in itself is not that helpful to our learning.
When this happens I've started writing down whatever it is that I think I should know better and then taking some time to read more in that area.
Wherever possible I also try to speak to people who already have that skill and find out how they went about learning it.
For example, as I mentioned in my post about reading the Unity source code, reading code is something I want to get better at and when I've worked with Dave Cameron he's able to understand how things fit together much more quickly than I am.
When we discussed this he pointed out that he'd spent a lot of time debugging through a lot of different code bases just for fun and working out how they fitted together by following the control flow.
It's pretty much always the case that others have spent quite a bit of time working on these skills so it's certainly something to keep in mind next time I come across something I 'should' know!
Learn one thing a day
I came across an interesting post about a month or so written by Chad Fowler on Tim Ferriss' blog where he suggested that a useful way of ensuring that we are always improving is to ask the question 'Am I better than yesterday?' at the end of each day.
I really like this idea and I think it fits in quite nicely with the approach that I take which is to try and ensure that I learn one new thing each day.
I find that it encourages me to be more inquisitive than I might otherwise be and helps avoid the problem of just cruising through the day and just doing the same thing day in day out.
When we start working on a new project it's quite easy to achieve this because we don't know much about the domain, we might not be familiar with the stack, there's existing code to get familiar with and so on.
It's much more challenging after you've worked on the same thing for a while and it's certainly tempting to conclude that there's nothing else to learn and that you need to work on something new to learn new things.
To an extent that's true because I find that a lot of what I learn comes from working with different people who have completely conflicting opinions on the best way to do things but there's certainly ways to keep on learning even after we've got past the initial fire hose learning stage.
Continuously question what you're doing
This is much easier when you're pair programming but certainly possible even when working alone.
I think what you question probably depends on what interests you the most so for me that tends to be a lot around how we can test code more effectively and how to make code more expressive and explicit wherever possible.
In order to do that I'm often looking for patterns that help to describe approaches that worked well and if we get something wrong then I want to try and discover what we would need to do when encountered with a similar situation in the future to not make that mistake again.
Fairly closely linked with the idea of questioning what we're doing is to try out other approaches and see if they work out better than what we're currently doing.
For example my colleague Matt Dunn and I were recently discussing where the factory and builder patterns were more applicable for object creation in different contexts.
We already had the factory pattern implemented in one section of the code so we spent a little time playing around with the builder pattern to see if that would have worked out better.
I think this appraoch works quite well because you can quickly see the potential problems you might encounter with another approach which might not be entirely obvious if you only talk about it.
Trawl the code base
An approach which I find quite useful once you are becoming reasonably comfortable when working with a code base is to start trying to find bits of it that you haven't done much work on or that you are curious to learn more about.
For me this exploration tends to guide me to the edges of the applicatins I work on and the interaction with other libraries that we are making use of.
A couple of examples of ares that I've explored on projects I've worked on have been the way that we make use of a dependency injection container which can often seem a bit 'magical' and the 'glue code' that we use to integrate with libraries like Hibernate.
If my intrigue is great enough then I'll probably end up looking through the code for those libraries as well.
There's nearly always something new to learn there as the design of frameworks tends to be a bit different than the design of applications from what I've seen.
And if that doesn't teach you anything…
At some stage we probably reach a point where we're really familiar with the code base and there doesn't seem to be much else that we can learn from a project.
If this is the case then I've found that learning a new language, taking part in coding dojos or participating in a book club can not only be quite useful for helping to learn new ideas/techniques but also perhaps giving you a new perspective on your project code base.
It's also interesting to talk to other people to see what they're learning as it can give you ideas of some areas that you might want to improve in as well.
I think people working in software development generally have a desire to learn new things and most of the time it's quite easy to find those opportunities so these are just a few ideas for things I try to do when it feels like I'm cruising too much for my liking.
Learning from others/Learning yourself
Something which has become quite apparent to me recently is that I learn things far more quickly if I try it out myself and make mistakes than if I just rely on someone else's word for it but some more experienced colleagues seem able to use information explained to them fair more effectively and don't necessarily need to go through this process.
While reading through the Dreyfus Model one of the ideas that is suggested is that once people reach the level of 'Proficient' at any given skill then they are able to learn from the experiences of others without needing to experience something themselves.
Andy Hunt sums this up quite nicely in Pragmatic Learning and Thinking :
Proficient practitioners make a major breakthrough on the Dreyfus model: they can correct previous poor task performance. They can reflect on how they’ve done and revise their approach to perform better the next time. Up until this stage, that sort of self-improvement is simply not available.
Also, they can learn from the experience of others. As a proficient practitioner, you can read case studies, listen to water cooler gossip of failed projects, see what others have done, and learn effectively from the story, even though you didn’t participate in it firsthand.
If you're not at that level yet it therefore seems to be the case that it's necessary to experience this situations in order to learn effectively.
The trick thing then is to engineer an environment where it is possible to learn but not one where you jeopardise a code base by doing so.
In a way this is what we did with the setter/constructor injection problem that I described previously – Erik pointed out the disadvantages that we would get from using constructor injection on a class which many classes derived from but I didn't fully appreciate his concerns and I couldn't picture the problems we would face until we spent a bit of time putting the dependency into the constructor and I was able to see how this dependency would cascade down into the 30 or so sub classes.
Since we were trying out a setter based injection approach alongside the constructor injection based approach in a time boxed exercise we were able to just throw away the constuctor based injection code when we saw that it wasn't quite going to work and so no harm was done to the code base.
I sometimes feel that a similar type of learning is probably going on in other situations as well.
One fairly common area of contention on projects I've worked on is around whether or not we should put stub/mock calls in a setup method in a test fixture.
On a project I worked on a couple of years ago we ran ourselves into a world of pain by putting mock/stub calls there because when we wanted to test a specific interaction in a test there would often be an unexpected failure because of those calls in the setup method.
It was never entirely obvious what had happened and we would end up wasting a lot of time before we realised what had happend.
As a result of that I've been pretty much against that approach although I can see why we might want to do this. It becomes very tedious typing out the same setup code in each of our tests.
Abstracting away that common setup into a method or series of methods which we explicitly call in each test provides one way to solve the problem but it takes the test setup one more click away from us when we're analysing test failures so I'm not sure whether it solves all our problems.
My current thinking is that perhaps we can make use of the setup method as long as all the tests defined in that test fixture require exactly the same setup but that as soon as we are writing a test which requires a different setup we need to pull that test out into its own test fixture.
The problem with this is that we end up splitting our tests based on how they test interaction with a dependency which seems very strange to me.
I still don't have the answer for the best way to solve this problem but I think I know a bit better from having experimented with some ideas than I would have by just listening to someone tell me about their experiences.
From my understanding of the Dreyfus Model, someone who's really good at unit testing wouldn't necessarily need to do this but would instead be able to learn from someone else's experiences just by talking to them about it.
I'm assuming that they would be able to do this because they have a wealth of similar situations to relate your stories to and they can therefore fill in any gaps in the knowledge they have.
I think this aspect of the Dreyfus Model helps identify why just explaining something from your experience rarely seems to be successful – unless the other person is 'Proficient' at the skill in question they won't easily be able to relate your experience to the problem without some experimentation of their own.
Perhaps there's more to it and I'm way off the mark but this theory at least seems reasonably plausible to me
Learning: Thoughts on doing so more effectively
One of the quite common sayings that I've come across when discussing student/teacher type situations is that it's the teacher's responsibility to present the material to the student in a way that they can understand and that if the student still doesn't understand then the teacher hasn't done their job properly.
I believe that this approach is also followed in the UK education system nowadays and while it makes sense in a way I don't think it's a particularly useful belief to have as a student since it seems to encourage you to be quite passive in the learning process.
I find that when you are in a situation where you are the student it is probably quite likely that you are aware of the best way that you understand new material whereas the teacher doesn't necessarily know and, unless they have the ability to work out which way you will understand best, they will probably explain something in the way that they would like it explained to them.
If you don't know the way that you learn best then it's quite a useful thing to try and work out.
I've worked out that I learn best when I can find something I understand already that I can link it to and as a general rule I understand things way better when I can work out a way to visualise it, usually by drawing a diagram or finding an explanation which includes a diagram.
My colleagues seem to have picked up that this is the way that I understand things best so wherever I happen to be working there will likely be stacks of papers with different diagrams on them!
I also know that it often takes me a few times before I understand something but that once I understand something I don't tend to forget it.
It used to really annoy me that I didn't understand concepts as quickly as some of my peers at university but now that I've noticed that pattern I tend to write down the concept or bookmark it if it's on the web and then come back to it later when I might have learnt something else which helps me understand the other concept.
Maybe the responsibility really does lie with the teacher, and I particularly like the quote from the last slide of this presentation which says 'If you can't explain it simply, you don't understand it well enough' but it doesn't do much harm to help them to help us.
I've also found that varying the way that I learn new ideas can sometimes be quite effective – for example there are now loads of videos available of people presenting on different technical topics and watching someone who knows a subject really well explain it through this medium can often make it easier to understand than reading an article about it.
One of the best ideas I've come across lately was from Pragmatic Learning and Thinking, which suggests discussing what you're learning with others.
This is useful because you get the chance to see how well you understand the topic by trying to explain it as well as getting their views on the subject.
From our experiences running a technical book club it's often quite surprising how varied people's opinions are despite reading/watching the same material.
It seems to me that perhaps the most important skill in the world of software development is learning how to learn new things and these are a few of the ways that I find work for me. I'd be keen to learn ways that other people are doing this too!
Dreyfus Model: More thoughts
Since we discussed the Dreyfus Model in book club a few weeks ago I've noticed that I'm more aware of my own level of skill at different tasks and references to the model appear more frequent at least amongst my colleagues.
These are some of the things I've been thinking about:
How do we use the model?
Alan Skorks has an interesting post where he discusses the role of the Dreyfus Model in helping to build software development expertise concluding that it doesn't help very much in developing expertise within a team.
In Pragmatic Learning and Thinking Andy Hunt suggested that one way to make use of the Dreyfus Model is to analyse the skill level of people that we interact with and then adjust the way we present information to them accordingly which I think is a good idea but requires a reasonable amount of skill to do.
I've found that it's actually quite revealing to just analyse your own level of skill and I hadn't realised how many things I am a novice at and just rely on a series of steps/instructions to make any progress and get quite frustrated when one of those steps doesn't work because I have don't yet have the ability to problem solve effectively in that area.
I had an example of this a few weeks when trying to port our code from Subversion to Mercurial using hgsubversion and struggled to work out how to get it to work, in particular with the fact that the process always failed at the same revision with no real indication (that I could understand at least) of why that had happened.
I am a novice with regards to doing this. I was just following the instructions and since I don't have any knowledge of the hgsubversion code base or even of Python I wasn't able to progress much further.
In this case though there is an argument that even if we are not skilled at a particular task we still might be able to make use of a higher level of skill with problem solving in general to try and infer why something might not be working as expected.
Recognising which other skills might be useful to us when we are struggling with a new skill is perhaps a skill in itself and in this case Dave was able to do this more effectively than I was by suggesting different ideas to try based on his understanding of what probably happened during the porting process.
This allowed us to progress further even though we weren't successful in getting it to work for the moment.
It's ok to be a novice at some things
Having recognised that I am a novice at quite a number of different things I was questioning whether I should be trying to improve in all those areas that I had identified.
Discussing this with some colleagues though we came to the conclusion that there are so many different areas of skill in software development that there's bound to be areas where we are going to be novice and if we don't use those skills that frequently perhaps it's fine that we don't progress beyond that stage.
For more core technical skills it's more important to raise our level although I think it might be difficult to identify which skills are important and which less so if we are a novice!
There seems to be potentially some conflict here with Marcus Buckingham's idea of focusing on your strengths if our strengths aren't aligned with the most important skills for software development.
On the other hand there are so many different areas of the field that it's quite likely that something we're good at will be important.
Experts and intuition
The way that those at the expert level work a bit differently to those at other levels is that they rely mostly on intuition when working out what they need to do but I think that there might be a bit of a trap here in that we assume we are an expert at something if we are unable to explain to someone else how or why we do it.
Although teaching a skill to someone else is a different skill than knowing the skill yourself, I think there is some overlap between them.
I have often found that when you try to explain something to someone else you are forced to really work out what you actually know around this area.
I think we probably learn more from teaching a skill to someone else than via any other learning approach and I currently measure my understanding of something based on whether I can explain it to someone else. If I can't then I don't know it as well as I thought.
The inability to explain something might indicate that we are an expert working by intuition but it might also indicate that we aren't as skilled as we'd like to believe.
Justin Kruger and David Dunning's paper titled Unskilled and Unaware of it, which discusses how people are liable to overrate their own ability and are even more likely to do this the less skilled they actually are, seems to provide some evidence that this theory might be true.
From my understanding of the Dreyfus model one would need to have gone through the previous levels before reaching the expert level so perhaps the perception of expertise wouldn't actually happen for a real expert.
Book Club: The Dreyfus Model (Stuart and Hubert Dreyfus)
In our latest book club we discussed the Dreyfus Model, a paper written in 1980 by Stuart and Hubert Dreyfus.
I've become quite intrigued by the Dreyfus Model particularly since reading about its applicability to software development in Andy Hunt's Pragmatic Learning and Thinking and after looking through Pat Kua's presentation on 'Climbing the Dreyfus Ladder of Agile Practices' I thought it'd be interesting to study the original paper.
These are some of my thoughts and our discussion of the paper:
- We discussed what actually counts as experience at a skill with regards to the idea that it takes 10,000 hours of practice to become an expert at something, and Cam made an interesting observation that 'if you don't have a change of thinking from doing something then you haven't had an experience'. I really like this as a barometer to tell whether you're actually learning something or just reapplying what you already know. I find pair programming is an excellent practice for encouraging this.
From reading Talent is Overrated I learnt that the important thing is that the tasks you are doing are slightly more difficult than your current ability so that you are always stretching yourself.
- I've learnt that it's not actually possible to skip the levels on the Dreyfus model when learning a new skill – previously when I've looked at it I always thought that it should be possible to do that but from experience
I think you always need to spend some time at each stage while you are finding your feet and this time can be unbelievably frustrating. I think it's useful to recognise that this frustration is because you are a novice and don't have a good way to problem solve yet and that it will get easier as you keep practicing.
It's interesting how this can be applied to some of the agile practices because all of them come from a higher level principle that we are trying to achieve but you won't actually understand that principle until you have done the practice for a certain amount of time. At that stage you have a better understanding of why the practice is useful which allows you to choose when it is useful and when a different approach might be more effective.
- We discussed whether you need to be a master to be able to teach a skill to people. I don't think these are correlated and that actually to be able to teach someone the more important thing is your skill at teaching on the Dreyfus model. At school for example I often found that the better teachers were the ones who had the ability to explain things in a way that students could understand rather than being the absolute best at the skill themselves.
- Dave mentioned that he is frequently asked how he knows a certain skill and has therefore started becoming more aware of how this happens so that he's able to do this more effectively. I've often found that understanding the way that more experienced practitioners think about problems is far more useful than just asking them to solve a problem you're having trouble with.
- Before the session we arranged for a few of us to try and come up with the behaviours needed for different skills and where they fitted on the Dreyfus model. There was a unanimous feeling that this was actually really difficult which also suggested that you can have a level of skill at using and understanding the Dreyfus model! I think it would be quite useful to identify the behaviours that you want to acquire so that you have some sort of roadmap for developing your ability at a certain skill but we also discussed the fact that the Dreyfus model is actually very useful as a reflection tool when working out where your ability with a certain skill lies and how you can change that. I think tracking your improvement against the Dreyfus model would be far more effective than a typical performance review.
- We spoke about beginner's luck and how we ofen do things much better when we first start doing them as it is pretty much reflective without too much analysis which would potentially ruin our performance. At this stage we are unconsciously incompetent at the skill so we just do it. I think having some success at a skill due to this actually results in motivation to keep on improving and actually improving our skill level.
I think the Dreyfus model in general is a really cool thing to learn about although I found that the way it is presented in Pragmatic Learning and Thinking is more accessible than the original paper. It's interesting that it was written about nearly 30 years ago and we don't make use of it as much as we could.
Learning through teaching
I've been watching one of the podcasts recorded from the Alt.NET Houston conference titled 'Why blog and open source' and one of the interesting ideas that stood out amongst the opinions express is that people write about their experience in order to understand the topics better themselves.
I've found this to be a very valuable way of learning – in fact it's probably more beneficial to the teacher than the student, somewhat ironically.
I've noticed that there are a few opportunities that we can take advantage of in order to increase our knowledge on topics by teaching other people about them.
By 'teaching' I mean explaining your understanding of a topic to other people rather than the traditional classroom approach where the 'teacher' is the expert and the 'students' are mostly passive learners.
Writing/Presenting
Blogging was the topic being discussed on the podcast, and I've found that writing about a topic is a pretty good way of organising your thoughts on that topic and seeing whether you understand it well enough to construct some opinions that you would have the ability to defend.
I've often found that when I start to write about a topic I discover some things about it that I hadn't previously considered and of course the ability for people to give you feedback on what you write means that it can become a two way conversation. There have certainly been a couple of occasions when people with more knowledge of a topic than me have pointed out where my understand of something can be improved.
The same thing applies when presenting about a topic although the feedback will be more immediate.
Book Clubs
One approach we've been trying out in our Domain Driven Design book club recently is to split the sub chapters between each of the members of the group and then everyone presents their part in the next meeting.
The advantage of this approach is that everyone gets the opportunity to teach the rest of the group in a topic area in which they have more knowledge and/or have studied more recently.
If you know you need to explain something to other people then I think it encourages you to approach the subject differently than if you are just reading through it for yourself. You also need to understand the topic more clearly yourself and be able to put it into your own words to explain to other people.
Pair Programming
I think one of the situations that can be the most frustrating in pair programming is when you understand something really well and your pair doesn't understand it as well.
The temptation is to wait until they're not around to implement your ideas but this misses a great opportunity to explore how well you really understand the topic area.
The questions posed by someone with less knowledge on a topic than you will force you to come up with good reasons for your opinions that you can explain in a more simple way than you may be used to. We may be forced to come up with metaphors that make it easier to explain something and certainly coming up with these metaphors may improve our own understanding.
In summary
I think there are a lot of opportunities in the world of software development to teach what we know to others and although it may seem that we are doing a favour to other people, I think we will find that we learn just as much as them from doing so if not more.
Of course it's not the only approach to learning but I've found it to be a surprisingly effective one.