Topic: ARC++ and Message Passing


Author: jones@jameson.arclch.com ((Ben Jones))
Date: Wed, 9 Mar 94 16:23:30 EST
Raw View
fjh@munta.cs.mu.oz.au (Fergus Henderson) writes:

>I agree that object closures are a good idea...
>but for crying out loud, why invent yet another meaning for the
>keyword `static' ???

I guess I was trying to avoid adding another keyword to the language.
How about:

    (* bound name)
        or
    (::* name)

The first would add the keyword "bound" to the language, or at least
in this context.  The second might be suggestive of a bound pointer to
a member of any class and would not add any new keywords.

Got any other suggestions?

--
Ben Jones - jones@jameson.arclch.com




Author: mbk%anl433.uucp@Germany.EU.net (Matt Kennel)
Date: 10 Mar 1994 04:39:30 GMT
Raw View
(Ben Jones) (jones@jameson.arclch.com) wrote:
: fjh@munta.cs.mu.oz.au (Fergus Henderson) writes:

: >I agree that object closures are a good idea...
: >but for crying out loud, why invent yet another meaning for the
: >keyword `static' ???

: I guess I was trying to avoid adding another keyword to the language.
: How about:

:     (* bound name)
:         or
:     (::* name)

: The first would add the keyword "bound" to the language, or at least
: in this context.  The second might be suggestive of a bound pointer to
: a member of any class and would not add any new keywords.

: Got any other suggestions?

Yeah.  Add another keyword to the language.

You're not making up Mensa puzzles.

: --
: Ben Jones - jones@jameson.arclch.com

--
-Matt Kennel    mbk@inls1.ucsd.edu
-Institute for Nonlinear Science, University of California, San Diego
-*** AD: Archive for nonlinear dynamics papers & programs: FTP to
-***     lyapunov.ucsd.edu, username "anonymous".




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sat, 5 Mar 1994 15:33:40 GMT
Raw View
jones@jameson.arclch.com ((Ben Jones)) writes:

[Lots of junk, and then...]
>
>ARC++ and Bound Function Pointers
>=================================
>
>ARC++ provides a simple extension to the C++ language to make this
>possible.  When a function pointer is qualified by the keyword
>"static" it indicates a function with the specified parameter and
>return types which belongs to any class.
>
>    struct D
>    {
>        void (*static output)();
>    };
>
>    C c1;
>    c1.output = x1.input;
>    c1.output();
>
>Not only is the syntax a lot cleaner but D is no longer limited to
>pointing to objects derived from X.  Strong typing is still preserved
>because the compiler can evaluate the expression "x1.input" and
>determine that "input" is a member function of the class of which "x1"
>is an instance and that it has the appropriate parameter and return
>types.

I agree that object closures are a good idea...
but for crying out loud, why invent yet another meaning for the
keyword `static' ???

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: jones@jameson.arclch.com ((Ben Jones))
Date: Mon, 28 Feb 94 11:16:25 EST
Raw View
This is the second in a series of articles which will explore ideas
for extending the C++ language.  These extensions are implemented in
an experimental preprocessor called ARC++ which takes the extended C++
syntax and generates ANSI C++.  Those who wish to try out the ideas
being presented here may obtain a copy of ARC++ for the PC, Mac,
Sparcstation, or Iris from the anonymous ftp on: "arcfos1.arclch.com".
Please go to the directory "/pub" and download the file "arc.READ_ME"
for instructions.

                     MESSAGE PASSING
                     ===============

                        Ben Jones
              (c) 1994 ARSoftware Corporation
                 jones@jameson.arclch.com


INTRODUCTION
============

The term "message passing" in OOP terminology usually means executing
a method in an object.  This amounts to nothing more than a glorified
function call.  The closest it comes to being a message is that
conceptually it is passed through the inheritance hierarchy looking
for an object which knows what to do with it.

When I think of a message, going out over a network, I visualize wires
connecting one black box to another.  One box sends the signal, the
other receives it:

    +----+     +----+
    | a1 |---->| x1 |
    +----+     +----+

Suppose that box "a1" is an object of class "A" and box "x1" is an
object of class "X".  All "a1" wants to do is send a message to its
own output.  All "x1" wants to do is receive a message at its own
input.  Neither one wants to know any details about the other except
that the connection is compatible.

C++ makes it very difficult to represent this model.  A solution,
implemented with a language extension called "ARC++", is outlined.


C++ Member Function Calling
===========================

Message passing is achieved by one object calling a function
associated with some other object.  In the above example, suppose that
we have an instance of class X:

    struct X
    {
        void input();
    };

 X x1;

We want to make a connection to the "input" function from an instance of
class A:

    struct A
    {
        void output() { x1.input(); }
    };

    A a1;
    a1.output();

Here, the definition of A's output function calls the "input" function
of "x1".  Obviously this limits all instances of A to calling a single
instance of X.  So we use a pointer:

    struct B
    {
        X *oOutput;
        void output() { oOutput->input(); }
    };

    B b1;
    b1.oOutput = &x1;
    b1.output();

Here, the definition of B's output function calls the "input" function
of any object of class X.  This, however, limits all instances of B to
calling only instances of X.  This is sort of like designing a chip
which can be connected to only one particular other type of chip.

We could make it more flexible by making the "input" function virtual.
Then B is merely limited to connecting to instances of X or anything
derived from X.  This is like designing a chip which can be connected
only one particular input of one particular family of chips.

We could go another step further and include a pointer to member
function:

    struct C
    {
  X *oOutput;
     void (X::*fOutput)();

        void output() { (oOutput->*fOutput)(); }
    };

    C c1;
    c1.oOutput = &x1;
    c1.fOutput = &X::input;
    c1.output();

Even in this most general case, there is one big problem.  Aside from
the clumsiness of the syntax for manipulating pointers to member
functions, "C" must still know that it is an object of class X which
it is refering to or at least an object of a class derived from "X".


What We Really Want
===================

A chip designer only cares that the connection is compatible.  In
software terms, the only thing that "output" wants to know is that a
function with certain parameter and return types belonging to some
unspecified object is going to be executed.

In other words, we'd like to be able to assign the expression
"x1.input" to that "output" and be done with it.

The only trouble is that in C++ the expression "x1.input" is illegal
unless it is accompanied by a parameter list, which executes it
immediately.

Other OO languages which don't worry about strong typing don't have
this problem.  However, strong typing is not the problem.


ARC++ and Bound Function Pointers
=================================

ARC++ provides a simple extension to the C++ language to make this
possible.  When a function pointer is qualified by the keyword
"static" it indicates a function with the specified parameter and
return types which belongs to any class.

    struct D
    {
        void (*static output)();
    };

    C c1;
    c1.output = x1.input;
    c1.output();

Not only is the syntax a lot cleaner but D is no longer limited to
pointing to objects derived from X.  Strong typing is still preserved
because the compiler can evaluate the expression "x1.input" and
determine that "input" is a member function of the class of which "x1"
is an instance and that it has the appropriate parameter and return
types.