tags:

views:

1523

answers:

14

This caught my attention last night.

On the latest ALT.NET Podcast Scott Bellware discusses how as opposed to Ruby, languages like c#, java et al. are not truly object oriented rather opting for the phrase "class-oriented". They talk about this distinction in very vague terms without going into much detail or discussing the pros and cons much.

What is the real difference here and how much does it matter? What are other languages then are "object-oriented"? It sounded pretty interesting but I don't want to have to learn Ruby just to know what if anything I am missing.

Update: After reading some of the answers below it seems like people generally agree that the reference is to duck-typing. What I'm not sure I understand still though is the claim that this ultimately changes all that much. Especially if you are already doing proper tdd with loose coupling blah blah blah. Can someone show me an example of a wonderous thing I could do with ruby that I cannot do with c# and that exemplifies this different oop approach?

+2  A: 

Maybe they are alluding to the difference between duck typing and class hierarchies?

if it walks like a duck and quacks like a duck, just pretend it's a duck and kick it.

In C#, Java etc. the compiler fusses a lot about: Are you allowed to do this operation on that object?

Object Oriented vs. Class Oriented could therefore mean: Does the language worry about objects or classes?

For instance: In Python, to implement an iterable object, you only need to supply a method __iter__() that returns an object that has a method named next(). That's all there is to it: No interface implementation (there is no such thing). No subclassing. Just talking like a duck / iterator.

EDIT: This post was upvoted while I rewrote everything. Sorry, won't ever do that again. The original content included advice to learn as many languages as possible and to nary worry about what the language doctors think / say about a language.

Daren Thomas
A: 

I'll take a stab at this.

Python and Ruby are duck-typed. To generate any maintainable code in these languages, you pretty much have to use test driven development. As such, it is very important for a developer to easily inject dependencies into their code without having to create a giant supporting framework.

Successful dependency-injection depends upon on having a pretty good object model. The two are sort of two sides of the same coin. If you really understand how to use OOP, then you should by default create designs where dependencies can be easily injected.

Because dependency injection is easier in dynamically typed languages, the Ruby/Python developers feel like their language understands the lessons of OO much better than other statically typed counterparts.

Simon Johnson
+9  A: 

There are three pillars of OOP

  1. Encapsulation
  2. Inheritance
  3. Polymorphism

If a language can do those three things it is a OOP language.

I am pretty sure the argument of language X does OOP better than language A will go on forever.

pete blair
yup - we will never stop fighting about that!
Daren Thomas
+12  A: 

The duck typing comments here are more attributing to the fact that Ruby and Python are more dynamic than C#. It doesn't really have anything to do with it's OO Nature.

What (I think) Bellware meant by that is that in Ruby, everything is an object. Even a class. A class definition is an instance of an object. As such, you can add/change/remove behavior to it at runtime.

Another good example is that NULL is an object as well. In ruby, everything is LITERALLY an object. Having such deep OO in it's entire being allows for some fun meta-programming techniques such as method_missing.

Ben Scheirman
+9  A: 

IMO, it's really overly defining "object-oriented", but what they are referring to is that Ruby, unlike C#, C++, Java, et al, does not make use of defining a class -- you really only ever work directly with objects. Conversely, in C# for example, you define classes that you then must instantiate into object by way of the new keyword. The key point being you must declare a class in C# or describe it. Additionally, in Ruby, everything -- even numbers, for example -- is an object. In contrast, C# still retains the concept of an object type and a value type. This in fact, I think illustrates the point they make about C# and other similar languages -- object type and value type imply a type system, meaning you have an entire system of describing types as opposed to just working with objects.

Conceptually, I think OO design is what provides the abstraction for use to deal complexity in software systems these days. The language is a tool use to implement an OO design -- some make it more natural than others. I would still argue that from a more common and broader definition, C# and the others are still object-oriented languages.

Peter Meyer
A: 

This is really probably getting down to what these people see others doing in c# and java as opposed to c# and java supporting OOP. Most languages cane be used in different programming paradigms. For example, you can write procedural code in c# and scheme, and you can do functional-style programming in java. It is more about what you are trying to do and what the language supports.

crashmstr
+2  A: 

I've only listened to the first 6-7 minutes of the podcast that sparked your question. If their intent is to say that C# isn't a purely object-oriented language, that's actually correct. Everything in C# isn't an object (at least the primitives aren't, though boxing creates an object containing the same value). In Ruby, everything is an object. Daren and Ben seem to have covered all the bases in their discussion of "duck-typing", so I won't repeat it.

Whether or not this difference (everything an object versus everything not an object) is material/significant is a question I can't readily answer because I don't have sufficient depth in Ruby to compare it to C#. Those of you who on here who know Smalltalk (I don't, though I wish I did) have probably been looking at the Ruby movement with some amusement since it was the first pure OO language 30 years ago.

Scott A. Lawrence
A: 

That was an abstract-podcast indeed!
But I see what they're getting at - they just dazzled by Ruby Sparkle. Ruby allows you to do things that C-based and Java programmers wouldn't even think of + combinations of those things let you achieve undreamt of possibilities. Adding new methods to a built-in String class coz you feel like it, passing around unnamed blocks of code for others to execute, mixins... Conventional folks are not used to objects changing too far from the class template. Its a whole new world out there for sure..

As for the C# guys not being OO enough... dont take it to heart.. Just take it as the stuff you speak when you are flabbergasted for words. Ruby does that to most people.
If I had to recommend one language for people to learn in the current decade.. it would be Ruby. I'm glad I did.. Although some people may claim Python. But its like my opinion.. man! :D

Gishu
"Adding new methods to a built-in String class coz you feel like it". sigh, and MS listened to this and added extensions methods to C#.
gbjbaanb
You're gonna love it with C#4.0 :) Muddy waters between static and dynamic languages now. Google out Anders PDC talk on Future of C#
Gishu
+3  A: 

Update: Its the new wave.. which suggest everything that we've been doing till now is passe.. Seems to be propping up quite a bit in podcasts and books.. Maybe this is what you heard.

Till now we've been concerned with static classes and not unleashed the power of object oriented development. We've been doing 'class based dev.' Classes are fixed/static templates to create objects. All objects of a class are created equal.

e.g. Just to illustrate what I've been babbling about... let me borrow a Ruby code snippet from PragProg screencast I just had the privilege of watching. 'Prototype based development' blurs the line between objects and classes.. there is no difference.

animal = Object.new                  # create a new instance of base Object

def animal.number_of_feet=(feet)     # adding new methods to an Object instance. What?
  @number_of_feet = feet
end
def animal.number_of_feet
  @number_of_feet
end

cat = animal.clone          #inherits 'number_of_feet' behavior from animal
cat.number_of_feet = 4

felix = cat.clone           #inherits state of '4' and behavior from cat
puts felix.number_of_feet   # outputs 4

The idea being its a more powerful way to inherit state and behavior than traditional class based inheritance. It gives you more flexibility and control in certain "special" scenarios (that I've yet to fathom). This allows things like Mix-ins (re using behavior without class inheritance)..

By challenging the basic primitives of how we think about problems, 'true OOP' is like 'the Matrix' in a way... You keep going WTF in a loop. Like this one.. where the base class of Container can be either an Array or a Hash based on which side of 0.5 the random number generated is.

class Container < (rand < 0.5 ? Array : Hash)
end

Ruby, javascript and the new brigade seem to be the ones pioneering this. I'm still out on this one... reading up and trying to make sense of this new phenomenon. Seems to be powerful.. too powerful.. Useful? I need my eyes opened a bit more. Interesting times.. these.

Gishu
Gishu, rather than trying to "fathom" this power, why not get hands-on in an extended project that is enabled by metaprogramming? This is what helped me get past my own cognitive constraints, coming from the C# world (and Java before then). If I hadn't got real, tangible, practical and practicable experience, I might not have realized that I was trying to assess the qualities of a given paradigm without having left behind the biases of the one that I'm most influenced by.
Scott Bellware
+1  A: 

I don't think this is specifically about duck typing. For instance C# supports limited duck-typing already - an example would be that you can use foreach on any class that implements MoveNext and Current.

The concept of duck-typing is compatible with statically typed languages like Java and C#, it's basically an extension of reflection.

This is really the case of static vs dynamic typing. Both are proper-OO, in as much as there is such a thing. Outside of academia it's really not worth debating.

Rubbish code can be written in either. Great code can be written in either. There's absolutely nothing functional that one model can do that the other can't.

The real difference is in the nature of the coding done. Static types reduce freedom, but the advantage is that everyone knows what they're dealing with. The opportunity to change instances on the fly is very powerful, but the cost is that it becomes hard to know what you're deaing with.

For instance for Java or C# intellisense is easy - the IDE can quickly produce a drop list of possibilities. For Javascript or Ruby this becomes a lot harder.

For certain things, for instance producing an API that someone else will code with, there is a real advantage in static typing. For others, for instance rapidly producing prototypes, the advantage goes to dynamic.

It's worth having an understanding of both in your skills toolbox, but nowhere near as important as understanding the one you already use in real depth.

Keith
+4  A: 

OO is sometimes defined as message oriented. The idea is that a method call (or property access) is really a message sent to another object. How the recieveing object handles the message is completely encapsulated. Often the message corresponds to a method which is then executed, but that is just an implementation detail. You can for example create a catch-all handler which is executed regardless of the method name in the message.

Static OO like in C# does not have this kind of encapsulation. A massage has to correspond to an existing method or property, otherwise the compiler will complain. Dynamic languages like Smalltalk, Ruby or Python does however support "message-based" OO.

So in this sense C# and other statically typed OO languages are not true OO, sine thay lack "true" encapsulation.

JacquesB
That's an interesting viewpoint. But even in python or ruby you should be injecting your dependencies in the constructor. So if you have a dependency on CookieEatingService you're going to have to inject something! Even if somehow the interpreter takes care of it for you and injects nil then calling service.EatCookie() will cause an error. It will only work if when a specific implementation is not found a stub is provided. This is something that C# can do too (albeit with more difficulty)
George Mauer
George, there's nothing in all of OO that suggests that dependencies must - or even should - be "injected" via constructor arguments. This is a bias of static language programming in the age of DI frameworks. It's a particular cultural bias and isn't reflected in the values of the Dependency Inversion Principle.
Scott Bellware
+20  A: 

In an object-oriented language, objects are defined by defining objects rather than classes, although classes can provide some useful templates for specific, cookie-cutter definitions of a given abstraction. In a class-oriented language, like C# for example, objects must be defined by classes, and these templates are usually canned and packaged and made immutable before runtime. This arbitrary constraint that objects must be defined before runtime and that the definitions of objects are immutable is not an object-oriented concept; it's class oriented.

Scott Bellware
+1  A: 

Object Oriented is a concept. This concept is based upon certain ideas. The technical names of these ideas (actually rather principles that evolved over the time and have not been there from the first hour) have already been given above, I'm not going to repeat them. I'm rather explaining this as simple and non-technical as I can.

The idea of OO programming is that there are objects. Objects are small independent entities. These entities may have embedded information or they may not. If they have such information, only the entity itself can access it or change it. The entities communicate with each other by sending messages between each other. Compare this to human beings. Human beings are independent entities, having internal data stored in their brain and the interact with each other by communicating (e.g. talking to each other). If you need knowledge from someone's else brain, you cannot directly access it, you must ask him a question and he may answer that to you, telling you what you wanted to know.

And that's basically it. This is real idea behind OO programming. Writing these entities, define the communication between them and have them interact together to form an application. This concept is not bound to any language. It's just a concept and if you write your code in C#, Java, or Ruby, that is not important. With some extra work this concept can even be done in pure C, even though it is a functional language but it offers everything you need for the concept.

Different languages have now adopted this concept of OO programming and of course the concepts are not always equal. Some languages allow what other languages forbid, for example. Now one of the concepts that involved is the concept of classes. Some languages have classes, some don't. A class is a blueprint how an object looks like. It defines the internal data storage of an object, it defines the messages an object can understand and if there is inheritance (which is not mandatory for OO programming!), classes also defines from which other class (or classes if multiple inheritance is allowed) this class inherits (and which properties if selective inheritance exists). Once you created such a blueprint you can now generate an unlimited amount of objects build according to this blueprint.

There are OO languages that have no classes, though. How are objects then build? Well, usually dynamically. E.g. you can create a new blank object and then dynamically add internal structure like instance variables or methods (messages) to it. Or you can duplicate an already existing object, with all its properties and then modify it. Or possibly merge two objects into a new one. Unlike class based languages these languages are very dynamic, as you can generate objects dynamically during runtime in ways not even you the developer has thought about when starting writing the code.

Usually this dynamic has a price: The more dynamic a language is the more memory (RAM) objects will waste and the slower everything gets as program flow is extremely dynamically as well and it's hard for a compiler to generate effective code if it has no chance to predict code or data flow. JIT compilers can optimize some parts of that during runtime, once they know the program flow, however as these languages are so dynamically, program flow can change at any time, forcing the JIT to throw away all compilation results and re-compile the same code over and over again.

But this is a tiny implementation detail - it has nothing to do with the basic OO principle. It is nowhere said that objects need to be dynamic or must be alterable during runtime. The Wikipedia says it pretty well:

Programming techniques may include features such as information hiding, data abstraction, encapsulation, modularity, polymorphism, and inheritance.

http://en.wikipedia.org/wiki/Object-oriented_programming

They may or they may not. This is all not mandatory. Mandatory is only the presence of objects and that they must have ways to interact with each other (otherwise objects would be pretty useless if they cannot interact with each other).

Mecki
@Meckl: I would note that the concept of objects communicating by passing messages it quite irrelevant in the modern world, outside of academia. It was an important concept during the development of the technology, but no longer matters as a distinct concept.
John Saunders
+1  A: 

You asked: "Can someone show me an example of a wonderous thing I could do with ruby that I cannot do with c# and that exemplifies this different oop approach?"

One good example is active record, the ORM built into rails. The model classes are dynamically built at runtime, based on the database schema.

liammclennan
Don't get me wrong, I've since started learning ruby and I like it very much but how exactly is ActiveRecord an example of OOP principles that are not possible in C#? It seems like an example of the capabilities of dynamic languages rather than OO. By the way, there are several popular ActiveRecord implementations in C# - the most popular one being Monorail's
George Mauer
Firstly, I was specifically talking about active record the library not the pattern. The library uses ruby's metaprogramming to dynamically define types that match the database schema. You can't do that with a class-oriented language since the types must be defined at compile time. Castle active record requires that the class model matches the database model (or a mapping is provided).Im using the definition of OO given above by Scott Bellware and Ben Scheirman which is only possible in dynamic languages.
liammclennan
gotcha, thanks for the clarification
George Mauer