Related
What is the formal and complete definition of the words "meta-logic" and "object-logic" in Isabelle? I see people keep using these but could not find any definition for these.
You don't find them because they are specific to Isabelle (as far as I know). "Object-logic" and "meta-logic" are terms introduced by Larry Paulson (as far as I can tell). In general, though not specifically, they are related to the general terms "metalanguage" and "object language", for disciplines like logic and set theory. Do a search on those and you'll get the standard wiki pages, because they're a standard part of logic.
Here, I'm looking at page 16, 2.2.3 Meta and object language of Logic and Computation - Interactive Proof with Cambridge LCF, by Larry Paulson, published 1987. At that time he was still conforming to standard terms, but then he switched. I forgot where I read it, but he made the switch somewhere to "meta-logic" and "object-logic", to clarify things for his own purpose. The two terms are in his papers and in the Isabelle distribution docs.
Others can give you their expert knowledge, but the meta-logic specifically is what you get when you import the theory Pure, in particular, a minimal set of logical connectives, ==>, \<And>, &&&, and ==. Discussion of these are spread throughout the Isabelle distribution documentation.
I know nothing much about intuitionistic logic, other than it doesn't provide the law of excluded middle, but you will read that they provide a minimal, intuitionistic logic.
Don't thank me. I've just read some things here and there, and listened. Others can provide expert knowledge.
My findings with regard this question are below.
I found in the Clemens Ballarin slides, slide 20.:
Meta logic: The logic used to formalize another logic.
Example: Mathematics used to formalize derivations in formal logic.
and it is put in parallel with:
Meta language: The language used to talk about another language.
Examples: German in a Spanish class, English in an English class.
Wikipedia has an entry on Metalogic, one section is Metalanguage - Object language:
In metalogic, formal languages are sometimes called object languages.
The language used to make statements about an object language is
called a metalanguage. This distinction is a key difference between
logic and metalogic. While logic deals with proofs in a formal system,
expressed in some formal language, metalogic deals with proofs about a
formal system which are expressed in a metalanguage about some object
language.
And here is slide 21 from Ballarin:
I've tried searching for Data Structure / Algorithms books that provide examples in either Objective-C, or another language supporting keyword message syntax, to no avail.
The reason I'm interested in this is because I really think the keyword syntax would help me understand the intent of code, which I find I have to think longer about in languages with typical function call syntax.
A good example is this snippet from a SplayTree implementation in C:
/* Continue down the tree. */
n = splay_tree_splay_helper (sp, key, next, node, parent);
The function name is pretty unhelpful, and even with the comment I have to thoroughly read the code to have any idea what's really happening there.
I know that technically any piece of C code is valid Objective-C, but I'm looking for something that structures algorithm implementations utilizing a good object model like Objective-C's since I believe the resulting code is more maintainable. This may seem counter-intuitive in the performance restricted space of algorithm design, but I've seen plenty of Algorithms books that have examples in idiomatic Ruby, Python, Javascript etc.
Basically I'm looking for anything with a good object model that allows for very descriptive keyword messages, whether it's Objective-C or even (though probably unlikely) anything else in the Smalltalk family.
Why would you want a book? Just download a smalltalk environment and read the whole actual source. Open a system browser, select one of the Collections categories (collection of classes) and start browsing the code (the extra column is for message categories). Open a workspace, type Object cmd-B (or ctrl-B, for browse) and see for yourself why the single responsibility principle was invented. Navigate through the code with hierarchy, senders and implementors.
I think you are looking for the wrong thing.
A good algorithms and data structures books will try to not waste your time with hard to read source code. Most of the good books I know spend most of their time explaining things at a high level and only show actual code in small snippets that can be easily understood independently of the language used and how proficient you are with it.
It doesn't matter how convoluted some guy's implementation of splay trees is. As long as you know what the splay tree is you should be able to implement your own version without looking at hit too much.
And finally, a good object model and nice syntax is not the be-all-end-all of things. Many datastructures make use of union types that are not very nicely implemented in OO style and the naming patterns and syntax are things you should be able to get used to very quickly.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I was talking with some of the mentors in a local robotics competition for 7th and 8th level kids. The robot was using PBASIC and the parallax Basic Stamp. One of the major issues was this was short term project that required building the robot, teaching them to program in PBASIC and having them program the robot. All in only 2 hours or so a week over a couple months. PBASIC is kinda nice in that it has built in features to do everything, but information overload is possible to due this.
My thought are simplicity is key.
When you have kids struggling to grasp:
if X>10 then <DOSOMETHING>
There is not much point in throwing "proper" object oriented programming at them.
What are the essentials needed to foster an interest in programming?
Edit:
I like the notion of interpreted on the PC as learning tool. Due to the target platforms more than likely being somewhat resource constrained, I would like to target languages that are appropriate for embedded work. (Python and even Lua require more resources than the target likely to have. And I actually kinda like Lua.) I suppose that is one of the few virtues BASIC has, it has been ran on systems with less than 4K for over 30 years. C may not be a bad option if there are some "friendly" tools available such as Ch.
The most important is not a lot of boiler plate to make the simplest program run.
If you start of with a bunch of
import Supercalifragilistic from <expialidocious>
public void inherited security model=<apartment>
public : main .....
And tell them they "not to worry they aren't supposed to understand that" - you are going to put off both the brightest and the dumbest.
The nice thing about python is that printing "hello world" is print "hello world"
Fun, quick results. Capture the attention span of the kid.
Interpretive shells like most scripting languages offer (command line) that lets the student just type 1 or 2 liners is a big deal.
python:
>>> 1+1
2
Boom, instant feedback, kid thinks "the computer is talking back". Kids love that. Remember Eliza, anyone?
If they get bogged down in installing an IDE, creating a project, bleh bleh bleh, sometimes the tangents will take you away from the main topic.
BASIC is good too.
Look for some things online like "SIMPLE" : http://www.simplecodeworks.com/website.html
A team of researchers, beginning at Rice, then spreading out to Brown, Chicago, Northeastern, Northwestern, and Utah, have been studying this question for about 15 years. I can't summarize all their discoveries here, but here are some of their most important findings:
Irregular syntax can be a barrier to entry.
The language should be divided into concentric subsets, and you should choose a subset appropriate to the student's level of knowledge. For example, their smallest subset is called the "Beginning Student" language.
The compiler's error messages should be matched to the students' level of knowledge. If you are using subsets, different subsets might give different messages for the same error.
Beginners find it difficult to learn the phase distinction: separate phases for type checking and run time, with different kinds of errors. For this reason, beginners do better with a language where types are checked at run time, i.e., a dynamically typed language.
Beginners find it difficult to reason about mutable variables and mutable objects. If you teach pure functional programming, by contrast, you can leverage students' experience with high-school and middle-school algebra.
Beginning students are more engaged by an interactive programming environment than by the old edit-compile-link-go model.
Beginning students are engaged by splash and by interactivity. It's good if your language's standard library provides built-in support for creating and displaying images. It's better if those images are supported within the interactive programming environment, instead of requiring a separate player or viewer. And it's even better if your standard library can support moving images, or some other kind of animation.
Interestingly, they have got very good results with just 2D images. Even though we are all surrounded by examples of 3D computer graphics, students seem to get very engaged working with just two-dimensional images.
These results have been obtained primarily with college students, and they have been replicated at over 20 universities. However, the research team has also done some work with high-school and middle-school students. The first papers on that work are just coming out, so I'm less aware of the new findings and am not able to summarize them.
When you have kids struggling to grasp:
if X>10 then <DOSOMETHING>
Maybe it's a sign they shouldn't be doing programming?
What are the essentials needed to foster an interest in programming?
To see success with no or little effort. To create something running in a matter of minutes. A lot of programming languages can offer it, including the scary C++.
In order to avoid complication with #includes, multiple source files, modularization and compilation, why not have a look elsewhere? Try to write some Excel macros or use any other software with some basic built-in scripting language to automate certain tasks?
Another idea could be to play with web pages. It is not exactly programming, but at least easy to achieve something and show to others with pride.
This has been said on SO before, but... try Scratch. It's an incredible learning tool for kids. It teaches the basics of programming concepts in a hands-on and language-independent way. After a bit of playing around with it they can get down to learning a specific language's implementation of the concepts they already understand.
The common theme in languages that are easy for beginners - especially children to pick up is that there's very little barrier to entry, and immediate feedback. If "hello world" doesn't look a lot like print "Hello, world!", it's going to be harder for people to pick up. The following features along those lines come to mind:
Interpreted, or incrementally JIT compiled (which looks like an interpreter to the user)
No boilerplate
No attempt to enforce a specific programming style (e.g. Java requiring that everything be in a class definition, or Haskell enforcing purely functional design)
Dynamic typing
Implicit coercion (maybe)
A REPL
Breaking the problem (read program) down into a small set of sections (modules) that do one thing and do it very well.
You have to get them to stop thinking like a user and start thinking like a programmer. They need to take it one step at a time. Ask them what they have to think of in order to figure out the problem them selves and then write them down as steps. If you can then you break each step even more in the same mater. When done you will have the program in english making it simpler to program for real.
I did this with a friend that just could not get it and now he can. He used to look at something that I did and be bewildered and I would say that he has done more complex stuff than this.
One of the more persistently-present arguments I have had with other programmers is whether or not one's first language should require explicit type languages. Many are of the opinion that learning a language which requires you to explicitly declare type information is one which will teach you to program typefully. Conversely, it can be said that dynamic languages might present a less demanding learning curve. It goes either way, I suppose.
My advice: start with a simple model of how a computer works. I am particular to stack machines as good tools for teaching computation.
Remember that beginners are learning two disciplines at the same time: how computers work and the abstract logic involved (the basics of Computer Science), plus how to write programs that match their intended logic (learning a specific language's syntax and idioms). You have to address both concerns in an interwoven fashion in order for the students to quickly become effective. This is also the reason experienced programmers can often pick up new languages quickly.
It's worth noting Python grew out of a project for a language named ABC, which was targeted at beginners. For example, the required colon isn't strictly required, but was found to improve readability:
if some_condition:
do_this()
I got 3 words : Karel the Robot.
it's a really really simple 'language' that is designed to teach people the basis of programming :
Look for it on the web. You can look at this, though I never tried it :
http://karel.sourceforge.net/
While this isn't related to programming a robot, I think web programming is a great place to start with kids that age. It's how I started at that exact age. It easily translates to something kids understand if they use the web at all. Start with HTML, throw in Javascript, and soon they want to be doing features requiring server-side scripting or some sort, and things progress from there.
With the kind of kids who are already interested in robotics, though, I'd actually go for a different language like the ones already described. If you want to work in a field like robotics, you don't need to be convinced to try something hard. You need to be challenged.
A few years ago I saw a presentation at Ignite! Seattle from one of the people working on the project now known as Kodu who envisioned as a programming language for children. He spent time talking about what common language features could simply be thrown out in a programming environment meant to teach fundamentals.
A lot of cherished imperative constructs, like C-style for loops, were simply left out in favor of a simple object-messaging approach. Object-oriented programming isn't hard to understand when you think about "objects" and "messages"; the hard part is when you deal with things that programmers, but not children, care about, like inheritance and contracts and sweeping abstractions. I've got this thing (noun), now act on it (verb), in this way (adverb like quickly), when thing (sees/bumps into) something (with some attribute) (that's your if). Events are really conditions, and have all of the power of conditions, but it's up to the runtime to identify when those events happen.
This kind of event and messaging driven approach probably translates even better to robots than procedural programming would, anyway, so it might be a good way to look at the problem. Try not to think about what you'd "need" to know to program in C or Pascal or something; think about what you'd want to be able to make something do.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have been programming in object-oriented languages for years now but secretly I look at some of the things my colleagues do with envy. A lot of them seem to have some inner OO instinct that I don't have - no matter how hard I try. I've read all the good books on OO but still can't seem to crack it. I feel like the guy who gave 110% to be a professional footballer but just didn't have the natural talent to make it. I'm at a loss and thinking of switching careers - what should do I?
I would say focus less on the OO programming and focus more on the OO design. Grab a paper and a pencil (or maybe a UML modelling tool), and get away from the screen.
By practicing how to design a system, you'll start to get a natural feel for object relationships. Code is just a by-product of design. Draw diagrams and model your application in a purely non-code form. What are the relationships? How do your models interact? Don't even think about the code.
Once you've spent time designing... then translate it to code. You'll be surprised at just how quickly the code can be written from a good OO design.
After a lot of design practice, you'll start seeing common areas that can be modularized or abstracted out, and you'll see an improvement in both your designs and your code.
The easiest way is to learn concepts such as SOLID, DRY, FIT, DDD, TDD, MVC, etc. As you look up these acronyms it will lead you down many other rabbit holes and once you are done with your reading you should have a good understanding of what better object-oriented programming is!
SOLID podcasts: http://www.hanselminutes.com/default.aspx?showID=168, http://www.hanselminutes.com/default.aspx?showID=163
SOLID breakdown: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
DRY: http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
FIT: http://www.netwellness.org/question.cfm/38221.htm
DDD: http://dddcommunity.org/
DDD required reading: http://www.infoq.com/minibooks/domain-driven-design-quickly
TDD: http://en.wikipedia.org/wiki/Test-driven_development
MVC: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
And yes, rolling up your sleeves and coding is always a good idea. Make a small project to the best of your current abilities. Then read an article from above. Then refactor your code to meet the needs of what you just read. Repeat until you have refactored the hell out of your code. At the end you should not only know what OO is all about but you should be able to explain why it is important and how to get their the first time. Learning how to refactor is a key to good code too. What is right now is not right tomorrow.
Too many people think of coding first, objects, last.
You can read all the books you want but that's not going to teach you how to think in an object-oriented fashion--that takes practice and a certain methodology.
Here are a few methods that have
helped me: When you're away from
work and open-minded you can
practice by looking at everything as an object. Don't look at these
objects and wonder how you're going
to program them, look at them as
properties and functions only and
how they relate or inherit from each
other. For example, when you see a
person, they are an object and
therefore would represent a class.
They have properties like hair
color, skin tone, height, etc. They
do certain functions as well. They
walk, talk, sleep, etc. Some of the
functions these people do returns
results. For example, their working
function returns a dollar amount.
You can do this with everything you
see because everything is an object.
Bicycle, car, star, etc.
Before coding a project, design it by
using post-it notes and a dry-erase
board. This will make good practice
until you get the hang of this.
Think of your specific
object/function/property. Each of
those items will have its own
post-it note. Place them as a
hierarchy on the dry-erase board. In
this regard, function/properties
will be placed under the object. If
you have another object, do the same
for that one. Then ask yourself, do
any of these post it notes
(objects/functions/properties)
relate to each other. If two objects
use the same function, create a
parent object (post-it note) and put
it above the others with the
reusable function under the new
note. Draw a line using the
dry-erase marker from the two child
objects to the parent.
When all this is done, then worry
about the internals of how the class
works.
My suggestion would be to learn something different.
Learn functional programming, and apply what you learn from that to OOP. If you know C++, play around with generic programming.
Learn non-object-oriented languages.
Not just because you should use all these things as well (you should), or because they should completely replace OOP (they probably shouldn't), but because you can apply lessons from these to OOP as well.
The secret to OOP is that it doesn't always make sense to use it. Not everything is a class. Not every relationship or piece of behavior should be modeled as a class.
Blindly trying to apply OOP, or striving to write the best OOP code possible tends to lead to huge overengineered messes with far too many levels of abstraction and indirection and very little flexibility.
Don't try to write good OOP code. Try to write good code. And use OOP when it contributes to that goal.
In many fields there's a "eureka" moment where everything kind of comes together.
I remember feeling frustrated in high school geometry. I didn't know which theorem to apply on each step of the proof. But I kept at it. I learned each theorem in detail, and studied how they were applied in different example proofs. As I understood not only the definition of each theorem, but how to use it, I built up a "toolbox" of familiar techniques that I could pull out as needed.
I think it's the same in programming. That's why algorithms, data structures, and design patterns are studied and analyzed. It's not enough to read a book and get the abstract definition of a technique. You have to see it in action too.
So try reading more code, in addition to practicing writing it yourself. That's one beauty of open source, you can download lots of code to study. Not all of that code is good, but studying bad code can be just as educational as studying good code.
Learn a different language! Most developers using only Java (just as an example) have only a limited understanding of OO because they cannot separate language features and concepts. If you don't know it yet, have a look at python. If you know python, learn Ruby. Or choose one of the functional languages.
The aswer is in your question ;)
Practice, practice, practice.
Review your own code and learn from the mistakes.
TDD has helped me most in improving my overall skillset including OOP.
The more code you write, the more you will notice the pitfalls of certain programming practices. After enough time, and enough code, you will be able to identify the warning signs of these pitfalls and be able to avoid them. Sometimes when I write code, I will get this itch in the back of my mind telling me that there may be a better way to do this, even though it does what I need it to. One of my greatest programming weaknesses is "over-analyzing" things so much that it starts to dramatically slow down development time. I am trying to prevent these "itches" by spending a little more time on design, which usually results in a lot less time writing code.
...secretly I look at some of the things my colleagues do with envy. A lot of them seem to have some inner OO instinct that I don't have - no matter how hard I try...
I think you have answered your own question here. Reading good code is a good start, and understanding good code is even better, but understanding the steps to get to that good code is the best. When you see some code that you are envious of, perhaps you could ask the author how he/she arrived at that solution. This is entirely dependent on your work environment as well as the relationships with your colleagues. In any event, if anyone asks me the thought process behind any code I write, I don't hesitate to tell them because I know I would want them to do the same for me.
Language designers have interpreted "Object Oriented Programming" in different ways. For instance, see how Alan Kay, the man who first used the term OOP, defined it:
OOP to me means only messaging, local
retention and protection and hiding of
state-process, and extreme
late-binding of all things. It can be
done in Smalltalk and in LISP. There
are possibly other systems in which
this is possible, but I'm not aware of
them.
(Quoted from http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en).
It might seem strange that he don't consider Java and C++ OOP languages! But as the designer of one of the first and best OOP languages (Smalltalk) he has his own valid reasons for that. Why did Alan Kay consider Lisp an Object Oriented language but not Java? That question demands serious consideration by anyone who claims to understand OOP.
Erlang has an altogether different implemntation of OOP, Scheme has another.
It is worth considering all these alternative views. If possible learn all these languages! That will give you a broader outlook, put some new and powerful tools in your hand and make you a better programmer.
I have summarized my experiments with implementing an OOP language, based on ideas borrowed from Smalltalk, Scheme and Erlang in this article.
public void MasteryOfOOP()
{
while(true)
/* My suggestion is: */
DO: find a lot of well-written object oriented code and read it. Then
try to use the insights from it on your own coding. Then do it again. Then
have a colleague who is a good OOP look at it and comment. Maybe post a chunk
of your code on SO and ask for how it could be improved.
Then read some more of those books. Maybe they make a little more
sense now...?
Now go back to the top of this post, and do it again.
Repeat Forever.
}
}
If you're lost as to how to design object-oriented systems, start with the data. Figure out what stuff you need to keep track of and what information naturally goes together (for example, all of the specs of a model of car group together nicely).
Each of these kinds of thing you decide to track becomes a class.
Then when you need to be able to execute particular actions (for example, marking a model of car as decommissioned) or ask particular questions (for example, asking how many of a given model of car were sold in a given year), you load that functionality onto the class it interacts with most heavily.
In general, there should always be a pretty natural place for a given bit of code to live in your class structure. If there isn't, that signals that there's a place where the structure needs to be built out.
There's too much information about objects. The most important thing is to master the basics and everything falls into place more easily.
Here's a way to think about objects. Think about data structures in procedural languages. They are a group of fields without behaviour. Think about functions that receive pointers to those data structures and manipulate the latter. Now, instead of having them separate, define the functions inside the definition of the the structures and assume the functions usually receive a pointer to the data structure to manipulate. That pointer is called this. In sum, think about objects as the combination of status (data) and behaviour (methods - the fancy name for functions in OOP).
This is the absolute basic. There are three more concepts you must absolutely master:
Inheritance - This is all about code reuse.
Encapsulation - This is all about hiding the implementation from the interface. Simply put, everything ought to be private until proven otherwise.
Polymorphism - It doesn't matter the type of the reference variable, but the type of the actual instance to know which behaviour (method) is called. Java doesn't make it easy to have this concept very visible because by definition everything is polymorphic. .Net makes it easier to understand as you decide what is polymorphic and what is not, hence noticing the difference in behaviour. This is achieved by the combination of virtual and override.
If these concepts are very well understood, you'll be fine.
One last final tip: You mention the best books. Have you read "Thinking in Java" by Bruce Eckel? I recommend this book even to people who are beginning in .Net, as the OOP concepts are clearly laid out.
Become more agile, learn junit testing and study about Domain Driven Design. I suggest the book Domain-Driven Design: Tackling Complexity in the Heart of Software although it's a bit tough at some points.
OOP skills comes over time. Reading 1, 2 ...10 books doesn't cut it. Practice writing some code. If you are working in a programming enviornment...that can be helpful. If not try getting into one. Offer to develop some application(s) for free. You have to get your hands dirty. Remember...no application is perfect from the ground up.That's why there is re-factoring.
Also...don't get carried away with the OOP too much...it somes over time. Worry about developing fully functional applications.
Try some programming in Self, one of the most pure OO languages around. So pure, in fact, that it doesn't even have classes, only objects. It also doesn't have variables, fields, statics, attributes, only methods. Also interesting is the fact that every object in the system is also an object on the screen and vice-versa.
Some of the interesting papers on Self are Prototype-Based Application Construction Using SELF 4.0 (the Self tutorial), Self: The Power of Simplicity and Organizing Programs Without Classes. Also, Self: The Video (Randall B. Smith; Dave Ungar) is terrific, having two of the language's designers explain Self's ideas.
This works for pretty much any concept, actually, at least for me: find the language which most purely embodies the concept you want to learn about and just use it.
OO finally clicked for me after I tried to program a bank-like program that handled transactions, calculated interest, and kept track of it all. I did it while I was learning Java. I would suggest just trying it, completing it, and then when you're done go look at a GOOD solution and see what you could've done better.
I also think OOP skills strenghten mostly with practice. Consider changing your company, if you've been there for more than 3 years. Certainly, this is not valid for all jobs, but often a man gets used to the projects and practices at a company and stops advancing as time passes.
Roll up your sleeves and code!
You said the answer yourself: practice. Best solution for this is to develop a game. Use the concepts you learnt in the books there.
Have you read the chapter on OO from the first edition of Scott Meyers "Effective C++" book? It didn't make it to later editions, but it was a great explanation. The title was basically "say what you mean, mean what you say" about suitable conventions.
Actually, you might like to see my answer to a similar question over here.
HTH
cheers,
OOP is not a thing you can master by reading thousands of books. Rather you have to feel the inner concepts. Read anything but try to feel what you read. Build a concept in the back of your mind and try to match those concepts when you face a new scenario. Verify and Update your concepts as you explore new things.
Good luck!
Plan things out. Ask yourself how you want your objects to relate to eachother and seek out how things can be changed and modularized.
Code things in such a way that if you wanted to change 1 piece of the code, you only have to change that 1 piece of code and not 50 instances of it.
beer helps. seriously. lie out on a couch with an A3 sized scribble pad, a pen and a beer. Lock the dog, cat and wife outside. And think about the problem while relaxed. Don't even dare draw an API on it!
Flowcharts, Responsibity cards (CRC) and beer (but not too much) go a long way.
Easiest way to refactor code is to not have to in the first place.
http://misko.hevery.com/code-reviewers-guide/
Those small simple rules will make you a better OO programmer. Follow the rules religiously as you code and you will find your code is better than it would otherwise be.
You'll also want to learn the Solid Principles: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
As much as these principles and ways of programming cause debate, they are the only way to truly write excellent code.
You may already write code this way and not know it-- if so, great. But if you need a goal to strive towards, these are the gold standard.
Give up! Why do you need that that OOP? Just write some usable app. Doesnt metter using OOP, procedual or functional approach.
Whataver approach you choose Python language should be sutable to practice it.
You're my target audience. Look at Building Skills in OO Design
Perhaps this can help.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have been asked to begin teaching C# and OO concepts to a group of procedural programmers. I've searched for ideas on where to begin, but am looking for general consensus on topics to lead with in addition to topics to initially avoid.
Edit
I intend to present information in 30 minute installments weekly until it no longer makes sense to meet. These presentations are targeted at coworkers at a variety of skill levels from novice to expert.
The best thing you can do is: Have a ton of Q&A.
Wikipedia's procedural programming (PP) article really hits where you should start:
Whereas procedural programming uses
procedures to operate on data
structures, object-oriented
programming bundles the two together
so an "object" operates on its "own"
data structure.
Once this is understood, I think a lot will fall into place.
In general
OOP is one of those things that can take time to "get," and each person takes their own path to get there. When writing in C#, it's not like the code screams, "I am using OO principles!" in every line. It's more of a subtle thing, like a foreach loop, or string concatenation.
Design center
Always use something (repeatedly) before making it.
First, use an object, and demonstrate the basic differences from PP. Like:
static void Main(string[] args)
{
List<int> myList = new List<int>();
myList.Add(1);
myList.Add(7);
myList.Add(5);
myList.Sort();
for (int i = 0; i < myList.Count; i++)
{
Console.WriteLine(myList[i]);
}
}
Using objects (and other OO things) first -- before being forced to create their own -- leads people down the path of, "Ok, I'm making something like what I just used," rather than "WTF am I typing?"
Inheritance (it's a trap!)
I would NOT spend a lot of time on inheritance. I think it is a common pitfall for lessons to make a big deal about this (usually making a cliché animal hierarchy, as others pointed out). I think it's critical to know about inheritance, to understand how to use the .NET Framework, but its nuances aren't that big of a deal.
When I'm using .NET, I'm more likely to "run into inheritance" when I'm using the .NET Framework (i.e. "Does this control have a Content property?" or "I'll just call its ToString() method.") rather than when I'm creating my own class. Very (very (very)) rarely do I feel the need to make something mimicking the taxonomy structure of the animal kingdom.
Interfaces
Coding to an interface is a key mid-level concept. It's used everywhere, and OOP makes it easier. Examples of this are limitless. Building off the example I have above, one could demonstrate the IComparer<int> interface:
public int Compare(int x, int y)
{
return y.CompareTo(x);
}
Then, use it to change the sort order of the list, via myList.Sort(this). (After talking about this, of course.)
Best practices
Since there are some experienced developers in the group, one strategy in the mid-level classes would be to show how various best practices work in C#. Like, information hiding, the observer pattern, etc.
Have a ton of Q&A
Again, everyone learns slightly differently. I think the best thing you can do is have a ton of Q&A and encourage others in the group to have a discussion. People generally learn more when they're involved, and you have a good situation where that should be easier.
The leap from procedural to object oriented (even within a language - for four months I programmed procedural C++, and classes were uncomfortable for a while after) can be eased if you emphasize the more basic concepts that people don't emphasize.
For instance, when I first learned OOP, none of the books emphasized that each object has its own set of data members. I was trying to write classes for input validation and the like, not understanding that classes were to operate on data members, not input.
Get started with data structures right away. They make the OOP paradigm seem useful. People teach you how to make a "House" class, but since most beginning programmers want to do something useful right away, that seems like a useless detour.
Avoid polymorphism right away. Inheritance is alright, but teach when it is appropriate (instead of just adding to your base class).
Operator overloading is not essential when you are first learning, and the special ctors (default, dtor, copy ctor, and assignment operator all have their tricky aspects, and you might want to avoid that until they are grounded in basic class design).
Have them build a Stack or a Linked List. Don't do anything where traversal is tricky, like a binary tree.
Do it in stages.
High level concepts : Describe what an object is and relate it to real life.
Medium level concepts: Now that they got what object is, try compare and contrast. Show them why global variable is bad compared to an encapsulated value in a class. What advantage they might get from encapsulating. Start introducing the tennets of OOP (encapsulation, inheritance)
Low Level concepts: Go in further into polymorphism and abstraction. Show them how they can gain even better design through polymorphism and abstraction.
Advance concepts: SOLID, Interface programming, OO design patterns.
Perhaps you should consider a problem that is work related and start with a procedural implementation of it and then work through (session by session) how to make an OOP implementation of it. I find professionals often grasp concepts better if it is directly related to real examples from their own work place. The junk examples most textbooks use are often horrible for understanding because they leave the student wondering, why on earth would I ever want to do that. Give them a real life reason why they would want to do that and it makes more sense.
I would avoid the "a bicycle is a kind of veichle" approach and try to apply OO to an environment that is fairly specific and that they are already used to. Try to find a domain of problems that they all recognize.
Excercise the basics in that domain, but try to move towards some "wow!" or "aha!" experience relatively early; I had an experience like that while reading about "Replace Conditional with Polymorphism" in Fowlers Refactoring, that or similar books could be a good source of ideas. If I recall correctly, Michael Feathers Working effectively with legacy code contains a chapter about how to transform a procedural program into OO.
Teach Refactoring
Teach the basics, the bare minimum of OO principles, then teach Refactoring hands-on.
Traditional Way: Abstractions > Jargon Cloud > Trivial Implementation > Practical Use
(Can you spot the disconnect here? One of these transitions is harder than the others.)
In my experience most traditional education does not do a good job in getting programmers to actually grok OO principles. Instead they learn a bit of the syntax, some jargon they have a vague understanding of, and a couple canonical design examples that serve as templates for a lot of what they do. This is light years from the sort of thorough understanding of OO design and engineering one would desire competent students to obtain. The result tends to be that code gets broken down into large chunks in what might best be described as object-libraries, and the code is nominally attached to objects and classes but is very, very far from optimal. It's exceedingly common, for example, to see several hundred line methods, which is not very OO at all.
Provide Contrast To Sharpen The Focus on the Value of OO
Teach students by giving them the tools up front to improve the OO design of existing code, through refactoring. Take a big swath of procedural code, use extract method a bunch of times using meaningful method names, determine groups of methods that share a commonality and port them off to their own class. Replace switch/cases with polymorphism. Etc. The advantages of this are many. It gives students experience in reading and working with existing code, a key skill. It gives a more thorough understanding of the details and advantages of OO design. It's difficult to appreciate the merits of a particular OO design pattern in vacuo, but comparing it to a more procedural style or a clumsier OO design puts those merits in sharp contrast.
Build Knowledge Through Mental Models and Expressive Terminology
The language and terminology of refactoring help students in understanding OO design, how to judge the quality of OO designs and implementations through the idea of code smells. It also provides students a framework with which to discuss OO concepts with their peers. Without the models and terminology of, say, an automobile transmission, mechanics would have a difficult time communicating with each other and understanding automobiles. The same applies to OO design and software engineering. Refactoring provides abundant terminology and mental models (design patterns, code smells and corresponding favored specific refactorings, etc.) for the components and techniques of software engineering.
Build an Ethic of Craftsmanship
By teaching students that design is not set in stone you bolster students' confidence in their ability to experiment, learn, and discover. By getting their hands dirty they'll feel more empowered in tackling software engineering problems. This confidence and practical skill will allow them to truly own the design of their work (because they will always have the skills and experience to change that design, if they desire). This ownership will hopefully help foster a sense of responsibility, pride, and craftsmanship.
First, pick a language like C# or Java and have plenty of samples to demonstrate. Always show them the big picture or the big idea before getting into the finer details of OO concepts like abstraction or encapsulation. Be prepared to answer a lot of why questions with sufficient real world examples.
I'm kinda surprised there's any pure procedural programmers left ;-)
But, as someone who started coding back in the early 80s on procedural languages such as COBOL, C and FORTRAN, I remember the thing I had most difficulty with was instantiation. The concept of an object itself wasn't that hard as basically they are 'structures with attached methods' (looked at from a procedural perspective) but handling how and when I instantiated an object - and in those days without garbage collection - destroyed them caused me some trouble.
I think this arises because in some sense a procedural programmer can generally point to any variable in his code any say that's where that item of data is directly stored, whereas as soon as you instantiated an object and assign values to that then it's much less directly tangible (using pointers and memory allocation in C is of course similar, which may be a useful starting point also if your students have C experience). In essence I suppose it means that your procedural -> OOPS programmer has to learn to handle another level of abstraction in their code, and getting comfortable with this mental step is more difficult than it appears. By extension I'd therefore make sure that your students are completely comfortable with allocating and handling objects before looking at such potentially confusing concepts as static methods.
I'd recommend taking a look at Head First Design Patterns which has really nice and easy to understand examples of object oriented design which should really help. I wouldn't emphasize the 'patterns' aspect too much at this point though.
I'm a vb.net intermediate programmer, and I'm learning OOP. One of the things I find is the lecturing about the concepts over and over is unnerving. I think what would be perfect documentation would be a gradual transition from procedural programming to full blown OOP rather than trying to force them to understand the concepts then have them write exclusively OOP code using all the concepts. That way they can tinker with little projects like "hello world" without the intimidation of design.
For example (this is for VB.NET beginners not advanced procedural programmers).
I think the first chapters should always be about the general concepts, with just a few examples, but you should not force them to code strictly OOP right away, get them used to the language, so that it's natural for them. When I first started, I had to go back and read the manual over and over to remember HOW to write the code, but I had to wade through pages and pages of lecturing about concepts. Painful!
I just need to remember how to create a ReadOnly Property, or something. What would be real handy would be a section of the book that is a language reference so you can easily look in there to find out HOW to write the code.
Then you briefly explaining how forms, and all the objects are already objects, that have methods, and show how they behave, and example code.
Then show them how to create a class, and have them create a class that has properties, and methods, and the new construct. Then have them basically switch from them using procedural code in the form or modules, to writing methods for classes.
Then you just introduce more advance codes as you would any programming language.
Show them how inheritance works, etc. Just keep expanding, and let them use thier creativity to discover what can be done.
After they get used to writing and using classes, then show how thier classes could improve, introducing the concepts one by one in the code, modifying the existing projects and making them better. One good idea is to take an example project in procedural code, and transform it into a better application in OOP showing them all the limitations of OOP.
Now after that is the advanced part where you get into some really advanced OOP concepts, so that folks who are familar with OOP already get some value out of the book.
Define an object first, not using some silly animal, shape, vehicle example, but with something they already know. The C stdio library and the FILE structure. It's used as an opaque data structure with defined functions. Map that from a procedural use to an OO usage and go from there to encapsulation, polymorphism, etc.
If they are good procedural programmers and know what a structure and a pointer to a function are, the hardest part of the job is already done!
I think a low level lecture about how Object Oriented Programming can be implemented in procedural languages, or even assembler, could be cool. Then they will appreciate the amount of work that the compiler does for them; and maybe they will find coding patterns that they already knew and have used previously.
Then, you can talk about best practices in good Object Oriented design and introduce a bit of UML.
And a very important thing to keep in mind always is that they're not freshmen, don't spend much time with basic things because they'll get bored.
Show Design Patterns in Examples
There where some plenty good answers, alright. I also think, that you should use good languages, good, skillful examples, but I have an additional suggestion:
I have learned what OOP means, by studying Design Patterns. Of course, I have of course learned an OO-language before, but until I was working on Design Patterns, I did not understand the power of it all.
I also learned much from OO-Gurus like Robert C. Martin and his really great papers (to be found on his companies site).
Edit: I also advocate the use of UML (class diagrams) for teaching OO/Design-Pattern.
The thing that made it click for me was introducing Refactoring and Unit Testing. Most of my professional programming career has been in OO Languages, but I spent most of it writing procedural code. You call a function on an instance of class X, and it called a different method on an instance of class Y. I didn't see what the big deal about interfaces was, and thought that inheritance was simply a concept of convenience, and classes were by and large a way of helping us sort and categorize the massive code. If one was masochistic enough, they could have easily go through some of my old projects and inline everything until you get to one massive class. I'm still acutely embarrassed at how bad my code was, how naive my architecture was.
It half-clicked when we went through Martin Fowler's Refactoring book, and then fully clicked when started going through and writing Unit and Fitnesse tests for our code, forcing us to refactor. Start pushing refactoring, dependency injection, and separation of the code into distinct MVC models. Either it will sink in, or their heads will explode.
If someone truly doesn't get it, maybe they aren't cut out for working on OO, but I don't think anyone from our team got completely lost, so hopefully you'll have the same luck.
I'm an OO developer professionally, but have had had procedural developers on my development team (they were developing Matlab code, so it worked). One of the concepts that I like in OO programming is how objects can relate to your domain (http://en.wikipedia.org/wiki/Domain-driven_design - Eric Evans wrote a book on this, but it is not a beginner's book by any stretch).
With that said, I would start with showing OO concepts at a high level. Try to have them design a car for example. Most people would say a car has a body, engine, wheels, etc. Explain how those can relate to real world objects.
Once they seem to grasp that high level concept, then I would start in on the actual code part of it and concepts like inheritance vs aggregation, polymorphism, etc.
I learned about OOP during my post-secondary education. They did a fairly good job of explaining the concepts, but completely failed in explaining why and when. They way they taught OOP was that absolutely everything had to be an object and procedural programming was evil for some reason. The examples they were giving us seemed overkill to me, partly because objects didn't seem like the right solution to every problem, and partly because it seemed like a lot of unnecessary overhead. It made me despise OOP.
In the years since then, I've grown to like OOP in situations where it makes sense to me. The best example I can think of this is the most recent web app I wrote. Initially it ran off a single database of its own, but during development I decided to have it hook into another database to import information about new users so that I could have the application set them up automatically (enter employee ID, retrieves name and department). Each database had a collection of functions that retrieved data, and they depended on a database connection. Also, I wanted an obvious distinction which database a function belonged to. To me, it made sense to create an object for each database. The constructors did the preliminary work of setting up the connections.
Within each object, things are pretty much procedural. For example, each class has a function called getEmployeeName() which returns a string. At this point I don't see a need to create an Employee object and retrieve the name as a property. An object might make more sense if I needed to retrieve several pieces of data about an employee, but for the small amount of stuff I needed it didn't seem worth it.
Cost. Explain how when properly used the features of the language should allow software to be written and maintained for a lower cost. (e.g. Java's Foo.getBar() instead of the foo->bar so often seen in C/C++ code).Otherwise why are we doing it?
I found the book Concepts, Techniques, and Models of Computer Programming to be very helpful in understanding and giving me a vocabulary to discuss the differences in language paradigms. The book doesn't really cover Java or C# as 00-languages, but rather the concepts of different paradigms. If i was teaching OO i would start by showing the differences in the paradigms, then slowly the differences in the 00-languages, the practical stuff they can pickup by themselves doing coursework/projects.
When I moved from procedural to object oriented, the first thing I did was get familiarized with static scope.
Java is a good language to start doing OO in because it attempts to stay true to all the different OO paradigms.
A procedural programmer will look for things like program entry and exit points and once they can conceptualize that static scope on a throwaway class is the most familiar thing to them, the knowledge will blossom out from there.
I remember the lightbulb moment quite vividly. Help them understand the key terms abstract, instance, static, methods and you're probably going to give them the tools to learn better moving forward.