Is C good enough - or can the world survive w/o OOP

B

BGB / cr88192

Stefan Ram said:
The term »object-oriented programming« was coined by Alan Kay.

In 2003, I became aware that no one knew how he defined it.
I have asked him about this, and his reply is given in:

http://www.purl.org/stefan_ram/pub/doc_kay_oop_en

I don't think this summarization is in conflict with Kay's description,
though granted his description is a little more in-depth.


so, taken this way:
everything is messages, well, to me this seems to imply everything is an
opaque API operating on some or another "object";
local retention and hiding of state, I agree, it is best not to have one
thing mucking around in the internals of another;
late binding, yes, this is why we have "objects", where an object holds its
own collection of methods/handlers/... (this just means not to base all of
ones' code structure around fixed-logic functions, as I see it).


one way of which to "approximate" this is bi-level:

split the codebase into a number of mostly-disjoint "components" which do
not share state (IOW: no shared globals), and communicate in a way defined
in terms of a more-or-less opaque API (I go as far as to generally dislike
sharing structs as well, although in a few cases it can be used to a
"greater good");

use "objects" which are accessed via a defined API, which may in turn simply
redirect to using internal vtables (I prefer to wrap objects in an API
mostly due to the fact that this better isolates the user of the API from
internal details of the object, such as how the vtable is laid out, and from
matters of having to manually deal with the possibility of NULL method
pointers).

technically, this amounts to something a little closer to CLOS-style OO than
Java or C++ style OO, but I personally find this acceptable.

it also need not result in the horrible nastiness which people accuse C of
having when people try to use it for OO, rather, this is more a result of
trying to naively pretend C is Java.
FWIW, a CLOS-style fits much better.

granted, it is a little less nice for an "object" to implement multiple
"interfaces", given one can't just cast the thing, meaning that, as a
general rule, there are not multiple-interface objects. also notable is that
this style does not implement explicit inheritence, usually leading to a
"greatest common factor" approach to API design (not that this doesn't
happened in "blessed" OO languages, where a class somewhat higher in the
inheritence tree often will end up with methods only used by a select few of
its descendents, ...).


but, it does not mandate the piles of particular practices usually accepted
as "OOP" by the people who often promote this term (actually, I can coin a
new term for these practices: "Java'isms"...).

one could even go as far as to try using these practices in C, allthough
probably many "OOP" supporters would recoil at the idea "but C is not an OOP
language", or such...


"one class per file" does not come up here, nor the requirement that
everything be organized into a taxonomical inheritence tree.

hell, programming is not natural biology, we don't need some grand "tree of
life" from which everything is inherited (actually, as I see it, this
actually runs counter to flexibility).

actually, these above two are the ones I take most issue with...

well, that and violating the core ideals of OO (such as keeping one thing
from digging in the internals of another), while still claiming it is
"proper" OOP.


to me, OOP does not mean:
this.someOtherObject.yetAnotherObject.someFieldWhichShouldBePrivate=42;
//magic constant indicating some particular state

stuff like this "should" be done via methods, as I see it...

either that, or people "could" stop taking the high ground and demeaning my
use of C...


but, alas, probably neither will happen...

then again, these sorts of experiences are possibly part of why I looked
some at the LLVM codebase and decided to keep well away. I don't know what
their actual practices are like in general, but code which looks like this
fills me with uncertainty.


not like I make the claim my code is exactly all that high either (actually,
some areas are fairly nasty...), but hell, at least I don't really have so
much pretense to claim code superiority...
 
S

Stefan Ram

BGB / cr88192 said:
split the codebase into a number of mostly-disjoint "components" which do
not share state (IOW: no shared globals), and communicate in a way defined
in terms of a more-or-less opaque API (I go as far as to generally dislike
sharing structs as well, although in a few cases it can be used to a
"greater good");

However, I believe this might also be considered to be a
description of ADT-entities (entities with an abstract data
type, that is, an interface/API). So what is the essential
property of OOP that distinguishes OOP from programming
with ADTs? To me, it is polymorphism.

http://c2.com/cgi-bin/wiki?ReplaceConditionalWithPolymorphism
to me, OOP does not mean:
this.someOtherObject.yetAnotherObject.someFieldWhichShouldBePrivate=42;

Yes, such code violates the »Law Of Demeter«.

Naïvly, one can start to do OOP in C with

struct object_of_a_specific_class
{ struct vtable * verbs;
/* possibly data of this object */ };

But some thought is needed to incorporate inheritance of
interfaces or implementations and so. We do not need to
discuss the details here, because books already have been
written about this topic (that is, OOP using C).
 
B

BGB / cr88192

Stefan Ram said:
However, I believe this might also be considered to be a
description of ADT-entities (entities with an abstract data
type, that is, an interface/API). So what is the essential
property of OOP that distinguishes OOP from programming
with ADTs? To me, it is polymorphism.

http://c2.com/cgi-bin/wiki?ReplaceConditionalWithPolymorphism

example, yes agreed.
oddly, I had never really thought of this one as an "OO feature", but simply
as a matter of "good style", something one is generally expected to use,
otherwise their code looks nasty...

apparently there are terms for damn near everything...


but, yeah, I am reminded of the Quake1 and Quake2 codebases, which have
almost no perception of this propery at times (yes... this code is nasty...
but I have seen worse...).

Yes, such code violates the »Law Of Demeter«.

Naïvly, one can start to do OOP in C with

struct object_of_a_specific_class
{ struct vtable * verbs;
/* possibly data of this object */ };

But some thought is needed to incorporate inheritance of
interfaces or implementations and so. We do not need to
discuss the details here, because books already have been
written about this topic (that is, OOP using C).

yep...

in a few places, there is code actually organized vaguely along these
lines...
 
B

BGB / cr88192

Nick Keighley said:
"Design patterns : elements of reusable object-oriented software"

Gamma et al


I have neither these books nor the means to get them...

nearly all info I get is online.
 
B

BGB / cr88192

Nick Keighley said:
big mathematical calculations?
reusable containers?
symbolic computation?
databases?

hmm, I will add:
some aspects of compiler internals (primarily the "upper end", as "lower
end" tasks would seem to be a better fit);
CSG operations;
"geometric manipulation" (not actually sure the term, where one applies
operations over big collections of geometry, but different from CSG as one
may be working with mesh data);
maybe physics (?);
....

physics is uncertain, as IME one does, at the same times, things which are
OO like, and things which are very unlike OO. it is OO from the perspective
that one manipulates objects, but not very OO in that one performs uniform
operations over the entire scene graph.


in many of these cases, the relational model is a good fit, as relational
logic is a good way to represent how the parts of a geometric object may be
interconnected, and especially how one applies operations possibly over the
entire model while not respecting the actual "parts" within the model.

physics simulation can be about like if one were trying to do OO and
relational logic at the same time.


I though up a few more cases, but realized they were simply special cases of
databases (such as managing compiler metadata, ...).


so, yeah, none of this means that OO is useful, only that it is not the
ideal solution for everything, and part of the skill of using a tool is
knowing when it is not the best tool.

for example, a hammer is not the best tool for tightening screws, even if
from a distance some screws may resemble nails...

nor is a hammer a very good idea for cleaning ones' bathroom...

or, as they may say in a shop class: a screwdriver is not a chisel...
 
N

Nick Keighley

Nick Keighley said:
On 28 Dec, 21:17, "BGB / cr88192" <[email protected]> wrote:
[...] too many people learned "OOP" from Java books...
this whole early Java experience had made me despise OOP for years, until
much later that I realized I had already been using OO, just in a very
different way...
for example, some of my early code had, actually, made use of a lot of
structs full of function pointers to allow allow plugging the same
front-end interface into different backends.
I had ideas like, say, carving up code into anonymous pieces with the
policy of not having one piece of code dig around in the other code's
internals,
"Design patterns : elements of reusable object-oriented software"
Gamma et al

I have neither these books nor the means to get them...

that's one book
nearly all info I get is online.

you could look the book up the internet and try "Design Patterns" in
google. To be honest I've never found a good resource about patterns
online but I haven't searched that hard.

The patterns book tends not to use inheritance heavily but use
dependency to link objects; which seems to be what you are trying to
do. You might also try the google archive for the news group
comp.object (the group it self seems to be fairly dead).
 
E

Edward A. Falk

Not really.

Agree. Here's how I first learned of the existence of the C language:

"It's like a portable assembler. You can even write OS code in it."

I didn't believe it until I learned the language for myself. Now I write
almost all of my own OS code in C.

There's something to be said for writing code and having a pretty good
idea of the machine language that it's going to generate.

As far as the OP's question about OOPs (always wanted to use that in
a sentence) are concerned, object-oriented programming has its place,
and there are a lot of problems I wouldn't want to solve without it,
but I think it tends to get over-used. Just because you have a hammer,
it doesn't mean you have to treat every problem like a nail.

IMHO, every keyboard should be designed to give the user a small electric
shock every time they use object-oriented programming techniques.
Not enough to really hurt, but just enough to make you only do it if
you really need it.

On a more meta level, if you want your knowledge of languages rounded out
for your professional career, I'd definitely look into Python. C, C++,
bash, and Python are (IMHO) the key languages of the industry now. I'd
learn Java, Javascript, Ruby, and PHP as secondary languages. Just my $.02
 
D

Duke Normandin

Agree. Here's how I first learned of the existence of the C language:

"It's like a portable assembler. You can even write OS code in it."

I didn't believe it until I learned the language for myself. Now I write
almost all of my own OS code in C.

There's something to be said for writing code and having a pretty good
idea of the machine language that it's going to generate.

Sounds like the Forth guys - they write Forth code , but always with an eye
on the asm code that it generates.
As far as the OP's question about OOPs (always wanted to use that in
a sentence) are concerned, object-oriented programming has its place,
and there are a lot of problems I wouldn't want to solve without it,
but I think it tends to get over-used. Just because you have a hammer,
it doesn't mean you have to treat every problem like a nail.

IMHO, every keyboard should be designed to give the user a small electric
shock every time they use object-oriented programming techniques.
Not enough to really hurt, but just enough to make you only do it if
you really need it.

Point taken...
On a more meta level, if you want your knowledge of languages rounded out
for your professional career, I'd definitely look into Python. C, C++,
bash, and Python are (IMHO) the key languages of the industry now. I'd
learn Java, Javascript, Ruby, and PHP as secondary languages. Just my $.02

I see that most of the languages you recommend are multi-paradigm. Stack the
deck in your favor and hedge that market, if you please... ;) If it all
boils down to assembler anyway (before machine code, of course), why not
have a look at HLA? I think I will...
 
N

Nobody

On a more meta level, if you want your knowledge of languages rounded out
for your professional career, I'd definitely look into Python. C, C++,
bash, and Python are (IMHO) the key languages of the industry now. I'd
learn Java, Javascript, Ruby, and PHP as secondary languages. Just my $.02

If you want your knowledge of languages rounded out simply for the
purpose of enlightenment, you should know at least one "real" functional
language, probably Haskell or ML (Lisp doesn't qualify; it's too easy to
use it as just another imperative language).
 
B

BGB / cr88192

Nick Keighley said:
that's one book


you could look the book up the internet and try "Design Patterns" in
google. To be honest I've never found a good resource about patterns
online but I haven't searched that hard.

The patterns book tends not to use inheritance heavily but use
dependency to link objects; which seems to be what you are trying to
do. You might also try the google archive for the news group
comp.object (the group it self seems to be fairly dead).

yeah, I may look into it.


I have read/posted on comp.object before, but it is not that often that a
whole lot interesting going on (a lot of the topics seem to be a bit more
theoretical, whereas I am most often concerned with practical and often
lower-level stuff...).
 
R

Richard Bos

Beej Jorgensen said:
"Use the right tool for the job" applies here. The Inform programming
language for text adventures is OOP--it would be nuts to have it any
other way. (One of my favorite projects quick projects to learn a new
language is to write a tiny text adventure engine in that language.)

Note, however, that this is Inform 6 and earlier you're presumably
thinking of. The current Inform 7 is a _very_ different (and IMO
inferior) beast.

Richard
 
S

Seebs

Note, however, that this is Inform 6 and earlier you're presumably
thinking of. The current Inform 7 is a _very_ different (and IMO
inferior) beast.

:( Yeah. It's... I mean, it's interesting, but it's an interesting research
project, I don't think it's a good tool for the tasks for which I usually
used Inform.

-s
 
B

Beej Jorgensen

:( Yeah. It's... I mean, it's interesting, but it's an interesting research
project, I don't think it's a good tool for the tasks for which I usually
used Inform.

Inform fans! Woo! :) I can appreciate 7's features from a
non-programmer standpoint, but 6 is way more comfortable for me to
actually use. Fortunately I think the two are planned to co-exist, as 7
actually compiles to 6 before going to Z-code. And I'm sure if Graham
Nelson decided to ditch 6, there would be some kind of rebellion.

-Beej
 
R

Richard Bos

Nick Keighley said:
big mathematical calculations?
Yes...

reusable containers?

....no, I think that could actually fit very well...
symbolic computation?
....yes...

databases?

....certainly not. That fits quite well with OOP. Not the hard work done
inside the back end, granted, but the interface between database and
user-application _is_, in essence, object-oriented.

Richard
 
N

Nick Keighley

...no, I think that could actually fit very well...

I know container libraries have been written using inheritance but I
never came across one that worked all that well. And C++ made it moot
but adding templates. How do you solve the its-really-the-same-code-
with-a-different-type problem?

list<int>
list<Widget>

do you use void* all over the place or use a dynamically typed (so-
called "weakly typed") language?
...certainly not. That fits quite well with OOP. Not the hard work done
inside the back end, granted, but the interface between database and
user-application _is_, in essence, object-oriented.

a lot of ink gets expended on the so-called "database"/OO "impedence"
problem. comp.object has long threads (mostly generated by an insane
person, true) on the subject. I gather (it's completely clear to me) a
lot of things databases try to do (persistence, integrity) don't
actually map that well to OO. And all that noramlised data stuff
doesn't seem to have leaked through to OO designs. I agree Entity
Relationship diagrams look like class diagrams to me; but apparently
they aren't. Bunging code in the object is, apparently, a sin.

Datatbases look to me like pretty good persistence stores for objects
(and the OO people seem to agree). But don't go and say that on
comp.databases (or whatever) if you don't want to end up black and
crispy.

OT? Yeah I know but comp.programming is no fun at the moment.



and to compound my sins...
--
"Does anybody ever actually root for the coyote?"
-Carl Burke (cburke#mitre.org)
"Of course! Wile Coyote is the technologist, the tool-user, the
direct spiritual descendant of the ape who got an Idea in the opening
of "2001: Space Odyssey!" He's got a brain and opposable thumbs and
an Acme Products catalog, and by golly he's going to _use_ them!
What's the bird got besides feet and luck? An air of annoying
smugness, that's what. Make him lunch, I say. When I win the lottery,
I'm going to fund a Wile E. Coyote Chair of Applied Engineering at
some university, I am...
-William December Starr (wdstarr#panix.com) in
rec.arts.sf.written
 
D

David Thompson

Where did you get that idea from? Yes in Forth you can define a 'word'
(sort of like a function) in assembler but normally words are managed by
an interpreter. Clue, Forth is a Threaded Interpreted Language.

Yes but no.

Original and traditional FORTHs were/are threaded code, but not
'managed' by a separate interpreter i.e. a fetch/dispatch loop.
Instead in 'direct' or 'indirect' threading each primitive just
dispatches to the next -- usually something like JMP VPC+ or JMP @VPC+
-- where a highlevel (nonCODE) word actually starts with a primitive
conventionally DOCOL which pushes VPC on the rstack and sets it to the
new word's body, which ends with a primitive which pops VPC (thus
returning). In 'subroutine' threading the word body actually consists
of a series of native CALL (or JSR or whatever) instructions that use
the native processor and native stack to accomplish effectively the
same thing; this usually takes somewhat more space, but on some
machines apparently the native call/stack is more efficient than a
simulated one by enough to be worth the cost.

But FORTH code can just as well be compiled to machine code by
effectively inlineing the words it invokes -- perhaps selectively, as
with C compilers e.g. only if smaller than X, only if not recursive,
only if leaf, etc. -- and optionally optimizing. At least the two main
current commercial implementors do so, and claim that on current
popular machines the resulting native code is not much larger and
often even smaller than the naive threaded code -- and of course
almost always much faster. It is my understanding they do only one
word at a time, so they probably can't be quite as aggressive as some
compilers for conventional whole-source (or whole-sourcefile)
languages like C, but apparently they don't need to.

To confuse matters FORTH(er)s call their interactive UI the
'interpreter', or often the 'outer interpreter' to distinguish it from
the 'inner' VM. This interpreter consists of repeatedly parsing a
token from the input, looking it up in the dictionary to find a word,
and then either executing it (if not in compile state, or if it is a
compile-time aka defining or IMMEDIATE word) or compiling it into the
currently open definition (if in compile state for a normal word).
To me that is indeed a form of interpreter, but one unrelated to the
normal mode of (compiled) code execution.
 
K

Kaz Kylheku

an interpreter. Clue, Forth is a Threaded Interpreted Language.

That is false. Forth is also a compiled language.

A Forth word can in fact have separately-defined compilation and
interpretation semantics.

A sequence of words can be compiled to machine code, not
necessarily to a sequence of threaded calls.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top