Conceptual Models of a Program?
retsofaj queries: "Almost all of the introductory programming books I've looked at focus on syntax, with possible digressions into a bit of semantics. What I haven't found are any great discussions that go beyond syntax and semantics and make it all the way to conceptual models. My goal is to develop a set of resources that can be used in an introductory course that teaches students programming starting with conceptual models, as opposed to starting with syntax."
"What I mean by conceptual models are how you think about what a program is (if a program can be anything!). Examples would be (all prefaced by "a program is made up of..."):
- flowcharts (structured programming)
- arrangements of opaque things sending messages to each other (OO)
- transformations of data structures (Wirth's view)
- state machines
- a knowledgebase (Prolog, etc.)
- algebraic operations on sets (Functional languages)
- Who/Where/How are the different models of a program being taught?
- What conceptual models do you use when programming (and where would I go to find out about them)?
Perhaps you're looking in the wrong places? Introductory books on analysis and design would seem to me a better place to find an introduction to analysis and design than books on programming.
Programming (coding) is how you implement a design. By the time you get around to coding, I would hope that you already have the design worked out.
Or am I missing something here?
Sortof like a modern, complex Karel in other words ;)
Karma: Could be worse (could be raining)
I started programming because I had a problem to solve. I focused on what I wanted to accomplish, not syntax or method or anything else. That isn't to say I didn't think about things like modularity, clarity, documentation, testing, etc - I did. I read a lot of the common texts - Brooks' _Mythical Man Month_, McConnell's _Code Complete_, Raskin's _The Humane Interface_, Spolsky's website, and a host of articles. I didn't start out with a language in mind. I started out with a result in mind. All of those things helped me to understand that my program existed to solve a problem. It wasn't there to keep me busy. I wasn't writing it because I wanted to use every neat trick I'd ever heard of. I was trying to make my life, and the lives of those around me, easier. I don't know how well I accomplished that, but I did build a program that did what it was supposed to do.
Writers imply. Readers infer.
sorry but experience alone will not teach one the breadth of the subject. How, for instance, will one deduce that the re-written program would be better suited to a different programming paradigm if one has not studied the known paradigms?
Without reading about say, Functional Programming, how will one make the intuitive leap mearly by exercising the iterative.
Like *all* disciplines it is the combination of study and practice that will lead the way.
There are places where the networks are not touching,and there are places where they are-Boeing's Lori Gunter
... before you can tackle algebra.
;)
Students need to learn syntax before they learn (much) in the way of structure. It doesn't matter what language they first learn in, though I think something in the C family (i.e., C, C++, Java, etc.) is a good place to start, since a) most real-worl programming is done in one of these languages and b) if you can really, truly learn C, you can learn anything.
But hell, teach 'em in Perl or LISP or Pascal if it makes you happy. The point is that programming courses have traditionally started out with "Hello World" or some such thing for a reason: beginning computer scientists need to learn that they can type in, compile, and run a program before they start worrying about higher-level structures. Any attempt to teach theory before practice will fail as surely as the "New Math" -- which basically did try to teach algebra before arithmetic -- did a couple of decades ago.
The correlation between ignorance of statistics and using "correlation is not causation" as an argument is close to 1.
This is way beyond what an introductory course should takle. Design Patterns must first be recognized through sweat & tears before they can be truly understood and appreciated. Design Patterns offer the experienced software designer a common language to communicate their ideas to their peers.
come on fhqwhgads
Although there are a lot of useful models like the ones you outlined, I'm not sure that there is any way to teach problem solving, and it's most important step, problem conceptualization.
I think you could take people through graded series of exercises soluble in different approaches, but there's no "one size fits all" way to develop intuition.
One approach used widely in architecture, a sibling profession if we ever had one, is "masterworks" - taking students through the works of other great architects, examining each decision made in some detail with reference to notebooks and discussions.
I think that this approach may make a lot more sense than teaching theory because it gives some access to an experienced mind, rather than just a methodology created by such a mind.
I know that I learned more from working with great programmers and absorbing their tricks than from any book I ever read or course I took.
Hexayurt - open source refugee shelter,
Getting too caught up in programming models early in as students training will almost certainly inspire them to build complex systems with huge over-generalized models. Programming models should come later, after basic syntactical and functional issues are addressed. The only model fledgling students should learn is to keep it simple. Teach them to solve problems with the least lines of codes possible, and the simplest data structures.
Agreed. This one's _essential_. In fact, I would go so far as to say I've seen no other choice; if you want to learn both how to program and how to think about programming, this is the only book which combines both.
The only problem, as I point out in another message, is that they almost totally ignore other conceptual models of programming; lambda calculus is thoroughly explored, but combinatorial logic and similar models, as demonstrated impurely by APL/J/K and purely by Forth/Postscript/Joy, are almost ignored. A good teacher would, IMO, base a class on SICP, but augment with two of the above languages and a discussion of their paradigms.
-Billy
UML is a great tool for programming, and then for maintaining the code after it is written too. If you want to make a really reliable system take a look at Z, it is a tool for program specification, except it uses a type of propositional logic to "prove" the correctness of a program. Any mission critical application (OS kernel, NASA spacecraft software etc etc) is done in Z type languages.
If your writing a site I think you should also include places where software has failed because the software engineering side was badly done. I can't remember the names off hand, but certainly a spaceship blew up on lauch because of an integer conversion, and there is another example where a program gave a patient the wrong X-Ray dose to treat his cancer. ALso, the 70's software crisis is quite interesting (read "The Mythical Man Month") which is basically when people started to realise that the more people you throw at a software project the slower it goes!! Its the time when UNIX became popular because it was one of the few small operating systems and so was reliable.
It seems obvious when you say it aloud, but the purpose of any program is to "do something". That is where I start. With what exactly it "can mean to do something".
The fact that this is vauge is, frankly, exactly the point. I also take the student through the real-world words excersize. Particularly "what is a file? Now try again but completely forget that htere has ever been a thing called a computer; what is a file?" wearing them down to "An arbitrary collection of arbitrary things."
Once you have done this decomposition of practical thought (typically about ten minutes of easy banter and cheap jokes) you can "really start" with the idea that there is a thing called "a state", that that thing is "only as defined as it needs to be for the task" and that any task is a transformation on that state.
The whole lecture really involves working a crowd (of students) like you were the warm-up act for a TV sit-com live-taping audience. But done correctly you are seeding your students with the tiniest grains of everything you will be requireing them to think from there on out. Most importantly you are doing it in a non-threatening way AND showing them that what they already know is vitally important. (That's the heart of the all important act of validating your students.)
Then you start bouncing back and forth between the practical and the theoretical.
Basically, what you should *REALLY* do is spend a few weeks with an "english as a second language" teacher or just a plain english teacher and learn how to *TEACH* before you even think about teaching a particular subject like "programming".
The fundimental problem with computer science is that the students are learning from the people who learned from the people who made it up in the first place, and not one of those people ever learned to "teach" any subject to anybody. -- me
Innocent people shouldn't be forced to pay for inferior software development.
--"Code Complete" Microsoft Press
I agree, but also read code. There are lots of large projects with source available out there; grab it and find out how their authors did it, and note whether the approach is understandable, consistent, scaled well, etc. You can only write so much code for the sake of learning; also some designs lend themselves to larger projects, beyond the scope of a learning exercise.
Case studies are widely used in other disciplines like engineering, and they can be useful in programming too.
Not to reply to my own post but...
The most important "conceptual model" is "you already know how to solve problems, you do it every day."
This is generally followed by:
"This is not hard, just new/strange to you"
and/or
"Everything anybody can do in here, at the atomic level, is exactly analogous to something you have already done in the real world."
The first and hardest thing to do is demystify the experience. Computer mystics program by rote formula, always recreating the same program with nearly identical structures in a cookbook-like format. Computer scientists take knowledge and use it to manufacture a good solution for each unique problem.
Most of the freshly-minted graduates in Computer Science are Computer Mystics. If you can break down this formula approach to the subject you will get much further much faster and produce a better graduate.
Innocent people shouldn't be forced to pay for inferior software development.
--"Code Complete" Microsoft Press
- Break down what is being developed into very small components, and make them as independant of everything else as possible.
- Develop so that relationships between components can be easily understand to lessen the impacts of any change. (One hint to a student, can he envision a cube in his head and rotate it or unfold it?? If not, maybe programming isn't for him.)
- Write reasonably good, self documenting, maintainable code that is consistent. Teach that it might be easier to use 'i' as a variable in a short loop, but loop-idx or object_idx make more sense.
- Which leads into the next one, LEARN TO TYPE DAMMIT. Programmers spend their career at a keyboard, they should learn to use it efficiently. That means both hands and all the fingers. Throw in the feet if you can.
- Write self checking code that handles errors in a concise, yet informative node. I hate 'segment fault' type messages. Trap the damn things and let someone have a general idea where it occured and what dataset was being worked on if possible.
There are probably a thousand some concepts that should be taught, but these are a few off the top of my bald head that shine through.I rarely read replies, it's my opinion and if you thought about your opinion a little more, I'm OK with that.
I disagree.
I think that someone starting off with these mental tools straight out of college can avoid all the 'sweat & tears' that we had to go through.
I haven't personally derived each and every pattern described in Design Patterns (just 1 in fact)... but that doens't mean I don't find them useful. Quite the opposite.
Now I 'grok' the pattern I worked out for myself more than the others, but that doesn't mean I don't use them.
I still think this would be a bit much to through at someone early on, but perhaps after they've got a language under their belt, along with some basic concepts....
Fooz Meister
These are all hacking manuals! Why is everyone mentioning hacking manuals!
The Art Of Computer Programming = hacking with elegant algorithms.
The Pragmatic Programmer = hacking with inelegant algorithms.
Design Patterns = hacking with no algorithms whatsoever but instead just some sort of vague metaphors.
A New Kind Of Science = hacking with algorithms that create pretty pictures and thus concluding that you've unified quantum mechanics and general relativity.
Knuth's book side, these have as much to do with developing a genuine understanding of computer programming as ISBN 0385194269!
Some people prefer to read code. I definitely prefer reading code, because I think backwards and use non traditional techniques to learn programming principles. I prefer to deconstruct a piece of good code and work back to the theory that way. Some people prefer to understand the theory first and think about different approaches to apply it.
A good teacher is one who is able to adapt the study plan to the strengths and weaknesses of the students. People should stop thinking of teaching as a mechanical process. Teaching is a creative, organic process that changes both the teacher and student. There are many smart and talented people working as teachers, who can't teach worth a dime. There are great teachers who are terrible programmers. Finding some one who is great at both is difficult.
Perhaps you should be asking, "How do become a good teacher?" As Lao Tzsu taught, if a person wants to be a good teacher, first be a good student. The teacher has to be a student of the student to understand how and why a particular student fails, so that he can adapt the explanation/technique for that individual.
I find it frustrating to see people like the original submitter trying to do something like this. It is a fine example of someone with lofty ideals and noble intentions who is determined to not let reality get in the way of how things *should* be. Because if we can just teach them the wisdom *first* we can save them the time and effort of having to achieve it themselves! As the parent of this post points out, it doesn't really work like that. It would be really nice if you could teach most people the abstract theory and concept behind good design and development practices, but the truth is that you really appreciate why something is right by having done, or seen it done, wrong yourself.
If you have never developed before, the conceptual underpinnings will be largely meaningless. Sure, students can and will learn what you're teaching by wrote, but the information is not *real* to them yet because they can't make the connection to anything within their experience. Further, they won't retain it long enough for it to be of value later when their development skills catch up enough to appreciate it. So it is all well and good to say 'teach the abstract stuff first' but you're just going to frustrate them and yourself. It's like trying to give the benefit of your life experience to a teen by lecturing them. It's just words to them until they come into that wisdom on their own someday and finally 'get' what you were trying to tell them.
Show them a couple of very simple constructs (like an if statement and a while loop), then show them the corresponding code in as many languages as you can. Build up in their mind that a computer language is just a tool to solve the problem .
The language you use to solve problems isn't irrelevent (some languages are better at certain tasks than others), but at this point in their programming career, it largely is.
echo 5050
but on the other hand most tasks aren't as simple or well defined as 'Hello World'. remember the last time your boss/client said "hey can we change it to do [this]" and you groaned because [this] wasn't anywhere near the original spec and you knew how much work it would need to hack it in? at that point you're wishing you'd abstracted just a little bit more at the outset.
My corollary: the boss is always going to ask for something that you didn't expect. twice.
Experience helps a great deal. One should not have to "rewrite" the program each time it doesnt work. Remember, preparation is everything. If you truly understand the problem and are familiar with programming concepts, you will be able to build a program that will do some, if not all of what you need. Granted, experience does play a part, but being a good programmer is, in my view, being able to understand concepts and use previous experience to write a good, solid, robust program.
I agree with the basic sentiment-- like any other language, you learn to write code by writing. The missing piece in your loop, particularly for beginners, is the editor who marks up their attempts, who tells them "this part is good" and "that part sucks". I was a self-taught programmer over 30 years ago and in that first six unsupervised months, I picked up bad habits that took me years to break. If you're just starting, get someone (hopefully someone who knows what they're doing) to edit some of your code.
Once you reach a certain level of proficiency, you can also progress by reading other people's code. Almost every language has some standard "idioms" for expressing common ideas well, and you can learn a lot of that from other people's code.