It seems the heart of most ApplicationProgrammingInterface
s are not written as object-oriented code, but as procedural code.
- OOP code can always wrap the procedural code later, but the opposite is rarely done.
- Procedural code usually more closely matches the hardware than OOP code, so it's a more natural fit for low-level APIs.
- Most languages can interface with C. Not as many can interface with C++.
- C compilers are available for almost all platforms.
- OOP, functional, and symbolic programming maps reasonably easy onto procedural code. Only OOP maps onto OOP.
- LeastFlexibleProtocolWins. OOP is a superset of procedural. Therefore procedural is less flexible. In other words, avoid AbstractionInversion.
- MostFlexibleProtocolWins?. OOP APIs are not flexible. C APIs are more flexible, because C has minimal assumptions about the runtime. The runtime of OO languages are wild beasts, obviously incompatible with one another. 2 distinct OO languages cannot talk with one another, and even today we're still waiting for C++ ABI so that C++ binaries produced by distinct compilers can work together. So all FFIs are C based. All successful ABI (Windows SDK and DDK) layers are C. Because C is minimal, it is also very stable. Actually, this page should be about C APIs rather than the general "procedural APIs", because there's no other language approaching near the success of C at providing APIs.
- Data is more cross-language than behavior, thus the interfaces de-emphasize behavior, and thus de-emphasize OO which is generally a behavioral interface paradigm.
- The inheritance rules and flavors differ for each OOP language. Example: prototyping (cloning) versus single inheritance versus multiple-inheritance versus "interfaces".
- BeOs presented a C++ API over a C++ OS.
- SymbianOs presents a C API over a C++ OS.
- X Windows, Gnome and Motif. They use OOP concepts in a procedural-only language (C). See http://le-hacker.org/papers/gobject/index.html.
- The whole slew of Java APIs, e.g., the base Java API, Swing, JDBC, JNDI, Servlets, JSP taglibs, etc.
- All Smalltalk environments
- The LispMachine
- Most of Perl's vast CPAN library.
- PHP's PEAR library
- BoostLibraries, C++
- DOM for HTML and XML
Some of the exceptions are questionable. Having an OOP interface does not mean the API is not procedural at the heart.
- Domino's is still fundamentally based on Cee, not CeePlusPlus code.
- Microsoft.NET is not inherently OOP, straight Cee can still compile to the CLR.
I see a pattern emerging though. An API for an OOP only language(i.e. Java), or written in a language that is only OOP - will of course be OOP underneath. In Cee/CeePlusPlus
, a procedural based API with an OOP interface is much more common.
Also many developers strongly dislike the object based Java API, and consider it cumbersome & messy, a potential strike against using OOP for an API in some instances.
Do you have a list of the names of these developers who strongly dislike the object based Java API?, Senator McCarthy?
Did you mean SenatorJosephMcCarthy?
? (I think he, 9/11, and Nazis all fall under GodwinsLaw
) I am one of those who strongly dislike it, I've heard others say the same. Perhaps you have a list of those who strongly like it?
This was true 10 years ago, but not today. Most APIs I see today are object oriented.
How many of them are wrappers around procedural APIs? PEAR is all OO classes, but almost all of them wrap built-in PHP functions, which are themselves wrappers for C APIs.
How many of the Java APIs are wrappers around procedural APIs? None, I hope.
Since all API will eventually reach machine code, saying Java APIs are wrappers around procedural is the same as saying all APIs are wrappers around machine code, or by extension, the "heart" of all programs are machine code.
Heh... I meant "How many of the non-Java OOP APIs are wrappers around an equivalent procedural API that's also offered?" The example I gave was PEAR; there're also C++ wrappers around Gtk++ and MySQL, and I'd expect that even some Java APIs HaveThisPattern (java.net over BSD sockets, or some versions of the JavaAwt and JavaSwt over native GUIs). I'm not arguing that everything is procedural machine code after being compiled.
But the distinction is just as meaningful (or meaningless). When I create a BSD Socket in java.net, that's an object. It receives messages and has a subclass (SSLSocket). When I ask it for its channel, it returns a Socket
Channel object. It doesn't matter if there's C code, Pascal or machine code under that. It's an OO API by any definition of that term I can think of.
They used to call them "handles". I suppose if you think handles are an inherently OO concept, then the above are indeed OO-ish. The problem is that NobodyAgreesOnWhatOoIs.
The difference is that you couldn't ask the handles to do anything, only pass them as arguments. Yes, inside the object is a handle, but that doesn't make the object any less of an object. -- EricHodges
descriptor_t myFile = open("foo.txt", "w"
int c = read(myFile);
the same as
File myFile = new File("foo.txt", w);
int c = myFile.read();
once you've gotten used to shifting the arguments around? I guess I'm confused as to why the first version isn't considered "asking the handles to do something". Is it just the syntactic difference? Is it because it doesn't have PolyMorphism
? Would handles in a vTable be considered OO then? -- JonathanTang
The first version isn't "asking the handles to do something" because messages aren't sent to the handles. Handles are passed to functions. I'm not sure why the question is being asked. The first example uses a procedural API. The second uses an OO API. Don't we all agree on that? -- EH
I'm not sure; I'd probably call the first procedural, but it seems like a direct syntactic mapping of the second, modulo polymorphism. So what makes the difference between an OO API and a procedural? Is it the grouping of functions (would Gtk+ be OO)? Is it the object.method syntax (would Dylan and CLOS libraries be OO)? Is it the presence of polymorphism (would the Java 1.02 collection framework not
be OO, because it doesn't provide any useful polymorphic abstractions)? -- JonathanTang
I'd say that objects make the difference between an OO API and a procedural API. Yes, there is a direct syntactic mapping between the two examples, but that's true of all procedural and object oriented code. I don't consider Gtk+ an OO API (no objects). I found useful polymorphic abstractions in the first Java collections framework, so I'm not sure what you're talking about there. -- EH
Let's not confuse using OO concepts with using OOP. It's not hard to write procedural code that is "object-like" - but that doesn't make it OOP. -- LayneThomas
I don't understand, Layne. I've done object oriented programming in procedural languages. I don't see the confusion you're talking about. -- EH
Any procedural language can implement OOP just pass an object as a parameter to your methods: method(object, parms) in procedural is the same as object.method(parms) in OOP.
No it isn't. It's a way to sortta kinda fake OOP in procedural, but don't confuse them to be the same, they aren't. method(object, params) uses methods from a global scope and lacks polymorphism because of this, unless one has generic functions ala Lisp. object.method(params) uses methods scoped to that particular object, meaning multiple possible implementations, aka polymorphism. It is more than just a syntax difference. object.method(params) also allows the object to keep it's data private, whereas method(object, params) requires all fields on the object to be public, thus lacking encapsulation, another key feature of OOP.
Neither polymorphism, nor encapsulation are distinctive features of OO. Both are just fine in procedural settings, using proc(args) notation. It looks like some people think that CeeLanguage
is all they need to know about procedural programming. Oh, well. Maybe it's time for an OoFaq?
I said they were key features, a true statement, not distinctive features, please don't put words in my mouth.
You suggested that a mere notation difference object.method(...) versus method(object,...) is what makes the difference between procedural and OO and "allows" for encapsulation and polymorphism. Simply false. And if it was true then what I "put in your mouth" follows trivially. You should have known that procedural programming allows both polymorphism and encapsulation, and if you knew that then the paragraph above was meaningless.
No, I was suggesting that the notational difference reflects the underlying semantic difference, objects working on themselves vs free floating methods working on passed in datastructures. I didn't say procedural programming couldn't have these features, but they'd be implemented differently, with something like modules.
Here's one of your pearls: "whereas method(object, params) requires all fields on the object to be public, thus lacking encapsulation, another key feature of OOP"
. It's simply false. End of discussion. You figure for yourself what you meant to say, I'm responding to what was written and it doesn't make any sense. It's up to you if you want to persist in errors.
OK, my mistake, you're taking my words too literally, when I said public, I wasn't referring to "public" as in public, private, protected visibility, I merely meant not totally private. Somehow those fields need to be visible to outside functions, even if you have control to which functions those are, with modules or whatever, there's still a difference in how procedural vs OOP is reasoned about, the syntax very clearly show's that difference.
What do you mean "not totally private"? Private to a module actually means private
. And the function bodies within a module implementation are actually on the inside, they cannot be considered outside functions. This is vastly superior to the half-baked modularity solutions built in most OO languages that confused the concept of classes with the concept of module. It's well known from good old Pascal that function within a module have access to all implementation details for that module (including possibly several private types, private functions, etc. The module's interface is a wall of separation between private and public.
When I say outside, I mean outside of the datastructure. Whether modules or classes is the superior concept is not at all a settled matter, so your claim of vastly superior is simply your opinion.
- You don't quite get it. The module implementation is the inside of the "data structure". Pick up and read any ML implementation of a hashtable or a binary search tree or any other common AbstractDataType. The AbstractDataType is the module, and the module is the abstract data type. Only some modules can export more than one ADT, if they are closely related. To claim that in such cases function bodies that have knowledge of the data are somehow "outside" is simply baseless.
Whereas OO language designers, by attaching the wall of separation to the type level (the private/protected/public modifiers attached to methods), break both modularity and encapsulation. Given a module system, a competent developer can easily simulate a class system with respect to encapsulation concerns, whereas the reverse is not true. In fact, quasi-totality of OO frameworks have encapsulation leaks because what ought to have been module-level concerns had to be exported public from the respective classes in the absence of proper modules.
Completely irrelevant to the point I was making, I'm not claiming one is better than the other, only that the underlying mental model is different, and that difference is obvious from the syntax each side prefers. You're so busy being defensive that you aren't listening to what I'm saying.
If you think you understand the procedural mindset so much better, try explaining it instead of just bitching about how you think I have it wrong, put your ego aside and try having a productive conversation. If I have it wrong, then you explain the difference in the mental model of procedural vs OO programming, and the conversation can move forward.
- You'd have to first understand the mental model of good procedural programming, before claiming to know the difference. This is just about matters of fact that you simply got wrong, I could not care less if your ego is too precious to correct your mistakes. So, again, what was the difference in the "underlying mental model" that is suggested by procedure(ars) vs object.method(...)? The correct answer has absolutely nothing to do with either encapsulation or polymorphism. And there, irrespective of the details that seem to have escaped you, you have got the big picture wrong.
Not to mention you could easily handle polymorphism in a procedural language with the variant data type and switching/dispatching on the type check.
Manually switching on a type is not polymorphism
For the record, I did not create this topic. -- top
Nor did I. -- bottom
Don't look at me. -- middle
You guys are making my sides hurt. -- side
See also: ProceduralMethodologies