Discussion:
OOP and C
(too old to reply)
David Kleinecke
2017-07-26 01:17:14 UTC
Permalink
Raw Message
This is all very abstract and tentative.

Suppose I start with my notion of object-oriented
programming and see how it fits with C(89 assumed).

I define an OOP situation as one involving software
objects communicating with one another by messages.
Each object will spend some processing time doing
things. There is no limit to how many messages may
be directed at it while it is doing some task. Hence
the object will have an input queue (or a more
complicated equivalent) and a message sent to it is
sent to its input queue. The object itself therefore
runs in a loop - read a message from its queue,
respond to the message, loop back for another message.

Now it seems likely that a time will come when the
object's queue is empty. So the object goes to sleep.
I need to specify the runtime environment in more
detail. I am assuming a multi-core processor and
mono-core objects. That is, while the object is
working it uses one particular core. Going to sleep
means passing that core back to the runtime
environment. When a message arrives for a sleeping
object the runtime returns a core - probably not the
same one it had before - to the object and lets it
execute.

Sending a message to another object is simple enough -
add the message to the other object's input queue.
But the runtime needs to know so it is better to post
the message to the runtime and let the runtime add it
to the queue. Of course if the object cannot proceed
without an expected reply to the message it starts
another input or goes to sleep.

I would hope that everybody on comp.lang.c is savvy
enough to see that everything I have envisioned can be
done in C - except that the runtime may need some help.
Is the situation really as simple as it seems to me?

PS: I assume external input can be implemented as a
semi-object - doesn't accept messages but generates
them according to what is happening outside the
computer. External output - like a screen - could be
the other kind of semi-object - never generates a m
essage but responds to them.
Malcolm McLean
2017-07-26 08:03:24 UTC
Permalink
Raw Message
Post by David Kleinecke
I define an OOP situation as one involving software
objects communicating with one another by messages.
Each object will spend some processing time doing
things. There is no limit to how many messages may
be directed at it while it is doing some task. Hence
the object will have an input queue (or a more
complicated equivalent) and a message sent to it is
sent to its input queue. The object itself therefore
runs in a loop - read a message from its queue,
respond to the message, loop back for another message.
So what happens when the queue gets stuffed full, as can happen
when something is generating messages faster than the object
is processing them?
Richard Heathfield
2017-07-26 08:22:25 UTC
Permalink
Raw Message
Post by Malcolm McLean
Post by David Kleinecke
I define an OOP situation as one involving software
objects communicating with one another by messages.
Each object will spend some processing time doing
things. There is no limit to how many messages may
be directed at it while it is doing some task. Hence
the object will have an input queue (or a more
complicated equivalent) and a message sent to it is
sent to its input queue. The object itself therefore
runs in a loop - read a message from its queue,
respond to the message, loop back for another message.
So what happens when the queue gets stuffed full, as can happen
when something is generating messages faster than the object
is processing them?
If that's a temporary and limited state of affairs caused by a localised
data flood:
a dynamic queue solves the problem.
Otherwise:
If it is acceptable to discard data:
discard the data.
Otherwise:
re-design the program.

It is certainly possible to envisage circumstances in which it might be
acceptable to discard data - for example, if the queue is stuffed full
of numbers from a genuinely random source for use in, say, a
Miller-Rabin test, then it doesn't actually matter what those numbers
are, so to lose[1] a few might not worry us too much. Throw them away.

It is also possible to envisage circumstances in which we might care
very much about the data and where vast numbers of messages pile into
the queue in short order for a little while (e.g. pitch wheel events -
we want to keep every nuance of the tremolo and maybe it takes so long
to process a pitch wheel event that two more arrive while we're doing
it, but the performer is going to have to let go of the wheel
/eventually/...). Keep every message, and grow the queue as required.

If we care about the data too much to throw it away, and it's coming in
too fast for our queue design to handle, I see no choice but to come up
with a better design.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
[1] oor "loose", foor thoose whoo preffer that spellling.
Thiago Adams
2017-07-26 12:13:00 UTC
Permalink
Raw Message
Post by David Kleinecke
This is all very abstract and tentative.
[...]
Post by David Kleinecke
I would hope that everybody on comp.lang.c is savvy
enough to see that everything I have envisioned can be
done in C - except that the runtime may need some help.
Is the situation really as simple as it seems to me?
Yes, I agree with you.
I have implemented it in C.
The "actor model" is very useful for concurrent computation.
Chris M. Thomasson
2017-07-26 23:25:09 UTC
Permalink
Raw Message
Post by Thiago Adams
Post by David Kleinecke
This is all very abstract and tentative.
[...]
Post by David Kleinecke
I would hope that everybody on comp.lang.c is savvy
enough to see that everything I have envisioned can be
done in C - except that the runtime may need some help.
Is the situation really as simple as it seems to me?
Yes, I agree with you.
I have implemented it in C.
The "actor model" is very useful for concurrent computation.
Yes, they do tend to work out pretty nicely.
David Kleinecke
2017-07-27 00:28:28 UTC
Permalink
Raw Message
Post by Chris M. Thomasson
Post by Thiago Adams
Post by David Kleinecke
This is all very abstract and tentative.
[...]
Post by David Kleinecke
I would hope that everybody on comp.lang.c is savvy
enough to see that everything I have envisioned can be
done in C - except that the runtime may need some help.
Is the situation really as simple as it seems to me?
Yes, I agree with you.
I have implemented it in C.
The "actor model" is very useful for concurrent computation.
Yes, they do tend to work out pretty nicely.
OK Guys. I need to use the name "actor model".

From my POV actor models are one kind of OOP - IMO the most
natural one. C++ et al would be another kind of OOP. For want
of a better name the C++ model.

I suspect a certain amount of NIH in the existence of two
versions of the same ideas.

Wikipedia punts on the matter of identity by saying actor
models are "very like" OOP.

Jens Thoms Toerring
2017-07-26 14:09:36 UTC
Permalink
Raw Message
Post by David Kleinecke
This is all very abstract and tentative.
Suppose I start with my notion of object-oriented
programming and see how it fits with C(89 assumed).
I define an OOP situation as one involving software
objects communicating with one another by messages.
Each object will spend some processing time doing
things. There is no limit to how many messages may
be directed at it while it is doing some task. Hence
the object will have an input queue (or a more
complicated equivalent) and a message sent to it is
sent to its input queue. The object itself therefore
runs in a loop - read a message from its queue,
respond to the message, loop back for another message.
You seem to assume that the term "message" is meant
literally and each object runs a loop (probably in a
kind of thread of its own, or how else would that be
possible?), waiting for such "messages" (basically
datagrams) and processing them on arrival. But in
OOP the term "message" has a more abstract meaning.
A "message" typically is a call of a member function
of the object. So there is no loop the object is run-
ning in, no input queue etc. And the runtime doesn't
have to do any of the things you seem to envision.

OOP is (in my understanding) more about dividing the
solution of a problem into small, independent units (i.e.
classes) with well-defined interfaces, that can be "plug-
ged" together to solve the problem at hand. The emphasis is
on "small" and "interfaces" - a bit like the idea under
Unix to have a set of small, but well-designed tools, that
can be used as building blocks to solve complex problems.
And, yes, all this can be done in pure C (see e.g. Jacob
Navia's container library that clearly was written with
OOP in mind). It's just that this isn't the traditional
approach most people think off when solving a problem in
C.

Having a language that has built-in support for OOP tends
to make things a lot simpler (and often easier to read).
You definitely can write OO code in C, but once you have
gotten used to way e.g. C++ allows you to do it, it feels
quite a bit clumsy doing it in C.

And then there are things in C++ beside support for OOP
like templates that can make a lot of things much simpler
and more concise, and for which no equivalent exists in C.
Also operator overloading can simplify things if used
reasonably. It all depends, of course, on how well-written
the program is, and how familiar you are with the language
- you can't expect to understand a complex program written
in C++ without having spent some amount of time to learn
it and got used to the typical patterns. But then a program
written in C is also not easy to understand for the unini-
tiated.

Clearly, you can create a complete mess in any programming
language. C++ may make it a bit easier to create such a mess
than C, but if used appropriately you can write programs that
IMHO are easier to understand than if they had been written in
C.
Regards, Jens
--
\ Jens Thoms Toerring ___ ***@toerring.de
\__________________________ http://toerring.de
Loading...