call() and return()

S

Steven T. Hatton

Erik said:
I came across this nice little name the other day: retroactive modeling.
Meaning that you can use new things with old, or more concrete you can
use non-intrusive concepts on already existing objects even if you don't
have access to their implementation.

That approach is sometimes called a hack, a kludge or a patch. The fact of
the matter is that you cannot always accomplish the same thing
by "non-intrusive" means as you can with an "intrusive" design.
boost::enable_shared_from_this is an interesting example of the futility of
such an effort.
 
B

bjarne

Steven said:
I believe you missed the several intended ironies in my comment.

Irony doesn't transmit well in web postings, even less well than humor
in general. Maybe you should consider using "smilys".
 
I

Ian Collins

Steven said:
When I read the first paragraph in §2.11.3 of D&E, it struck me as blatantly
obvious that these two functions would be useful. The wording in D&E
suggests that call() and return() might be worth reconsidering.

But what advantages do they offer over the alternative non-intrusive
approaches? I can't see any and the lack of access to the member's
parameters is a big disadvantage.
I looked at the date of 1980 for the example of using call() and return(),
and thought about the fact that C++ still has no native thread support. I
don't know that it should, but I have to wonder if call() and return() had
been part of C++ whether I would ever have heard of Java.

I can't see any relationship between call() and return() and Java. They
are two solutions in two completely unrelated problems spaces.
 
G

Gianni Mariani

bjarne said:
Irony doesn't transmit well in web postings, even less well than humor
in general. Maybe you should consider using "smilys".

Microsoft has patents on those.

(omitting requisite smily due to patent infringement concerns).
 
S

Steven T. Hatton

Ian said:
But what advantages do they offer over the alternative non-intrusive
approaches?

Among the advantages of the intrinsic call/return pattern are: simplicity,
clarity, uniformity, localization of functionality, access to intrinsic
state, inheritability, etc. I am, of course, making some assumptions about
how it might be implemented.
I can't see any and the lack of access to the member's parameters is a big
disadvantage.

I don't see these bracketing functions as call specific. They would work at
the level of the object as a whole. Since I've never actually had them to
work with, and have only been aware of the concept for a day, it's hard for
me to assess their full potential.
I can't see any relationship between call() and return() and Java. They
are two solutions in two completely unrelated problems spaces.
http://www.gotw.ca/publications/c_family_interview.htm
"Q: Did you ever add features that your users didn't appreciate as much as
you did, and then have to deprecate or remove them later? What did you
learn from the experience?
[...]
Stroustrup: When I designed C with Classes and C++, I was very keen on the
idea that a class defined the environment in which the code of its member
functions operate (I still am). This led to the notion of constructors that
establish that environment (invariant) and acquire the resources needed.
Destructors reverse that process (releasing resources). These ideas are at
the root of the design of exceptions and resource management. For example,
see the new Appendix E: "Standard-Library Exception Safety" of The C++
Programming Language.[3] That appendix can be downloaded from my home
pages.[4]

Based on that line of thinking, C with Classes also allowed you to define a
call() function that was called before entry into a member function and a
return() function that was called after exit from a member function. The
call()/return() mechanism was meant to allow a programmer to manage
resources needed for an individual member function invocation. This allowed
me to implement monitors for the first task library. A task's call()
grabbed a lock and its matching return() released the lock. The idea came
partly from Lisp's :before and :after methods. However, the notion wasn't
perfectly general -- for example, you couldn't access arguments for a
member function call from call() [So what?]. Worse, I completely failed to
convince people of the usefulness of this notion, so I removed call() and
return() when I defined C++."

http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html [*]
"§17.1 Locks
The Java programming language provides multiple mechanisms for communicating
between threads. The most basic of these methods is synchronization, which
is implemented using monitors. Each object in Java is associated with a
monitor, which a thread can lock or unlock. Only one thread at a time may
hold a lock on a monitor. Any other threads attempting to lock that monitor
are blocked until they can obtain a lock on that monitor. A thread t may
lock a particular monitor multiple times; each unlock reverses the effect
of one lock operation."

I am aware that one can synchronize on individual Java methods, which
appears contrary to the idea of simple before/after bracketing on a class
instance.

"§8.4.3.6 synchronized Methods
A synchronized method acquires a monitor (§17.1) before it executes. For a
class (static) method, the monitor associated with the Class object for the
method's class is used. For an instance method, the monitor associated with
this (the object for which the method was invoked) is used."

Bear in mind, however, that a method in Java is actually and instance of
java.lang.reflect.Method. At any rate, the same kind of selectivity could
be accomplished in C++ with call/return through multiple inheritance. Or
through a language extension such as support for a /synchronized/ keyword.

[*]Everybody who contributes text to the C++ Standard should read this book.
Not for the technical ideas, but as an example of an alternative style of
presentation.
 
W

wkaras

Steven said:
I believe you missed the several intended ironies in my comment.

Then I also missed the Socratic double irony, because I've heard
more than once the argument that C++ is a bad language because
it was devolped iteratively based on experience with practical
usage.
 
S

Steven T. Hatton

bjarne said:
Irony doesn't transmit well in web postings, even less well than humor
in general. Maybe you should consider using "smilys".

Zaphod Beeblebrox?

Back to the original topic. After having 25 years to reflect upon the
matter, do you believe omitting call() and return() from C++ was the right
_design_ choice? Are they worth reconsidering?
 
S

Steven T. Hatton

Then I also missed the Socratic double irony, because I've heard
more than once the argument that C++ is a bad language because
it was devolped iteratively based on experience with practical
usage.

I don't believe I've ever made such a claim. What is most evident to me
right now regarding the faults of C++ is not really inherent to the
language. When I first started trying to learn C++ I bought a copy of the
Standard. Many people told me that reading the Standard was the wrong way
to go about learning C++. My own experience tells me that it was somewhat
beneficial, but not completely effective.

Some of the observations I made back then were that the Standard lacked
clarity, that terms were not well defined and that some of the wording was
overly cleaver. I was told that the failing was on my part, and that the
Standard was written in highly specialized language only accessible to
experts.

http://groups.google.com/group/comp.lang.c++.moderated/msg/f5836121a85f07b6

Quod erat demonstrandum.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Steven said:
Back to the original topic. After having 25 years to reflect upon the
matter, do you believe omitting call() and return() from C++ was the right
_design_ choice?

Have you considered that if it were a big demand for that feature several
compilers were already implemented it as extension?

By the way, if you are really reading "The Design..." you must know that the
best way to make a feature considered or reconsidered is to implement it
and show his usefullness with real samples.
 
S

Steven T. Hatton

Julián Albo said:
Have you considered that if it were a big demand for that feature several
compilers were already implemented it as extension?

Perhaps, but how long did quaternions languish as an academic curiosity
before someone realize they had a use in 3D graphics? There are many good
ideas sitting on bookshelves, either waiting from someone to come along and
realize their value, or for someone who recognizes their value to gain the
skills and resources necessary to make use of them.
By the way, if you are really reading "The Design..."

I pick it up from time to time and read a bit more of it. Fortunately, it
is the kind of book well suited to such use.
you must know that
the best way to make a feature considered or reconsidered is to implement
it and show his usefullness with real samples.

I still have a lot to learn about using C++. In particular, I have a lot to
learn about how multi-threading is accomplished with C++. One very nice
thing about Java is that threading is built in, and fairly straightforward.
In my _very_ limited experience with multi-threading in C++ I have
encountered problems because my GUI library uses a different kind of
threading than the 3D library. Also, how threads in Java work is far more
obvious than it is to me in C++.

The question I intend to bear in mind in order to evaluate the usefulness of
the call/return pattern is whether there are actions taken at the object
level as part of execution flow in existing programs. My instincts tell me
that there may be a place for such a feature in device drivers, as well as
in concurrent programming. Even if there are wrapper designs which
intercept parameters, it may be beneficial to separate the call-specific
and class/object-specific components.

I've been wrong in the past about features which appear useful, so I may be
wrong about call() and return(). I have to say, however, that my intuition
is very strongly in favor of their usefulness.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Steven said:
Perhaps, but how long did quaternions languish as an academic curiosity
before someone realize they had a use in 3D graphics?

I suppose that "someone" put his ideas at work, instead of telling other
people "I have an intuition about quaternions, the graphics library writers
must consider using it".
There are many good ideas sitting on bookshelves,

Yes, there are plenty of ideas, and people elaborate new ones every day.
I have to say, however, that my intuition is very strongly in favor of
their usefulness.

But is hard that other people start to work in that field just by your
intuition. People usually spend his time with his own intuitions and ideas.
 
S

Steven T. Hatton

Julián Albo said:
I suppose that "someone" put his ideas at work, instead of telling other
people "I have an intuition about quaternions, the graphics library
writers must consider using it".

Someone did, well, in a sense. He wrote a book explaining the idea, and a
lot of other people used it.
Yes, there are plenty of ideas, and people elaborate new ones every day.


But is hard that other people start to work in that field just by your
intuition. People usually spend his time with his own intuitions and
ideas.

As far as I know, there is only one person in the world who has hands-on
experience working with this design. I asked for his opinion. Not yours.
 
R

red floyd

Steven said:
Perhaps, but how long did quaternions languish as an academic curiosity
before someone realize they had a use in 3D graphics? There are many good
ideas sitting on bookshelves, either waiting from someone to come along and
realize their value, or for someone who recognizes their value to gain the
skills and resources necessary to make use of them.

Quaternions have had a known use long before 3D graphics. They are used
in rocket and missile guidance algorithms.
 
K

king

Stroustrup: When I designed C with Classes and C++, I was very keen on the
idea that a class defined the environment in which the code of its member
functions operate (I still am). This led to the notion of constructors that
establish that environment (invariant) and acquire the resources needed.
Destructors reverse that process (releasing resources). These ideas are at
the root of the design of exceptions and resource management. For example,
see the new Appendix E: "Standard-Library Exception Safety" of The C++
Programming Language.[3] That appendix can be downloaded from my home
pages.[4]

Based on that line of thinking, C with Classes also allowed you to define a
call() function that was called before entry into a member function and a
return() function that was called after exit from a member function. The
call()/return() mechanism was meant to allow a programmer to manage
resources needed for an individual member function invocation. This allowed
me to implement monitors for the first task library. A task's call()
grabbed a lock and its matching return() released the lock. The idea came
partly from Lisp's :before and :after methods. However, the notion wasn't
perfectly general -- for example, you couldn't access arguments for a
member function call from call(). Worse, I completely failed to convince
people of the usefulness of this notion, so I removed call() and return()
when I defined C++.
</quote>

The last sentence is what has me baffled.

why do we need it as a standard mechanism? Cant we have the call to
call() at the begining of every member function and return() before
every return? May be something like
#define RETURN returnf(); return
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Steven said:
As far as I know, there is only one person in the world who has hands-on
experience working with this design. I asked for his opinion.

.... and ignored it.
 
S

Steven T. Hatton

king said:
Stroustrup: When I designed C with Classes and C++, I was very keen on
the idea that a class defined the environment in which the code of its
member functions operate (I still am). This led to the notion of
constructors that establish that environment (invariant) and acquire the
resources needed. Destructors reverse that process (releasing resources).
These ideas are at the root of the design of exceptions and resource
management. For example, see the new Appendix E: "Standard-Library
Exception Safety" of The C++ Programming Language.[3] That appendix can
be downloaded from my home pages.[4]

Based on that line of thinking, C with Classes also allowed you to define
a call() function that was called before entry into a member function and
a return() function that was called after exit from a member function.
The call()/return() mechanism was meant to allow a programmer to manage
resources needed for an individual member function invocation. This
allowed me to implement monitors for the first task library. A task's
call() grabbed a lock and its matching return() released the lock. The
idea came partly from Lisp's :before and :after methods. However, the
notion wasn't perfectly general -- for example, you couldn't access
arguments for a member function call from call(). Worse, I completely
failed to convince people of the usefulness of this notion, so I removed
call() and return() when I defined C++.
</quote>

The last sentence is what has me baffled.

why do we need it as a standard mechanism? Cant we have the call to
call() at the begining of every member function and return() before
every return? May be something like
#define RETURN returnf(); return

It may prove significant that call() is invoked _before_ the member
function, and that return() is invoked _after_ the return has completed.
I'm thinking in terms of synchronization points. Another issue would be
what to do about exceptions. I don't claim to be any kind of an expert on
this matter. I've very briefly looked at some discussions of how this is
used in CLOS. In that case there is at lease one other function
called "around" which seems to provide parameter interception. The part of
call/return that appealed to me was that it seems like a good way to
support concurrency.

I will note that there are very few references listed in the Java Language
Specification. Among them is the CLOS Specification. Only one author
appears with more than one title.
 
P

Pete Becker

Steven said:
It may prove significant that call() is invoked _before_ the member
function, and that return() is invoked _after_ the return has completed.
I'm thinking in terms of synchronization points. Another issue would be
what to do about exceptions. I don't claim to be any kind of an expert on
this matter. I've very briefly looked at some discussions of how this is
used in CLOS. In that case there is at lease one other function
called "around" which seems to provide parameter interception. The part of
call/return that appealed to me was that it seems like a good way to
support concurrency.

You should look closely at Java's experience with synchronized methods.
Library designers have moved away from them, because the lock almost
always occurs too soon, killing performance. It's much better to defer
locking until you've finished some preliminaries, and possibly decided
that a lock isn't even needed.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
S

Steven T. Hatton

Pete said:
You should look closely at Java's experience with synchronized methods.
Library designers have moved away from them, because the lock almost
always occurs too soon, killing performance. It's much better to defer
locking until you've finished some preliminaries, and possibly decided
that a lock isn't even needed.

So I've read. So far the only difference between Java's threading and
threading in C++ that I've noticed is that I was able to make use of what
Java provides. Can you provide detailed information describing the adverse
impact of Java's threading model in typical applications? The only
hands-on experience I have with a functioning large-scale concurrent
application is the component that provides AKO (Army Knowledge Online) with
access to the US Army's personnel database. We used BEA WebLogic.

There are a lot of issues I have not been able to explore regarding
threading in C++. I'm suspicious of claims of significant performance
enhancements in the general case that require computing the need for
locking at runtime. You will need to pay for that computation somehow.

It's not clear to me whether a distinction between read locks and write
locks would be useful in concurrent programs. Java has no concept of
constness beyond immutability. That, in itself, suggests C++ could use the
same basic threading model and provide superior performance. There are
probably many cases in which the need for locking could be determined at
design time, or at compile time.

When all is said and done, it seems likely there will be a need to take
action "within" synchronization points.
 
W

wkaras

Steven said:
I don't believe I've ever made such a claim.

Sorry, I didn't mean to imply that you did. It did seem that you
were (seriously) saying that C++ was negatively impacted
because the designer thought that a strong consensus of expert
users trumphed his own intuition. (Hence the double irony if
you only meant it ironically.)
What is most evident to me
right now regarding the faults of C++ is not really inherent to the
language. When I first started trying to learn C++ I bought a copy of the
Standard. Many people told me that reading the Standard was the wrong way
to go about learning C++. My own experience tells me that it was somewhat
beneficial, but not completely effective.

Some of the observations I made back then were that the Standard lacked
clarity, that terms were not well defined and that some of the wording was
overly cleaver. I was told that the failing was on my part, and that the
Standard was written in highly specialized language only accessible to
experts.

http://groups.google.com/group/comp.lang.c++.moderated/msg/f5836121a85f07b6

Well, mal de muchos, consuelo de tontos, but the C++ Standard is easier
to use than alot of the other technical standards I've had to deal
with. So
the problem is not specific to C++. And anyway, C++ was an important,
usable, and surprisingly portable language for many years before the
1998 Standard was issued.
 
S

Steven T. Hatton

Sorry, I didn't mean to imply that you did. It did seem that you
were (seriously) saying that C++ was negatively impacted
because the designer thought that a strong consensus of expert
users trumphed his own intuition. (Hence the double irony if
you only meant it ironically.)

My comment was "Bruno was burned at the stake, wasn't he?" If you find any
angle of irony in the various possible interpretations it was probably
intended.
http://groups.google.com/group/comp.lang.c++.moderated/msg/f5836121a85f07b6

Well, mal de muchos, consuelo de tontos, but the C++ Standard is easier
to use than alot of the other technical standards I've had to deal
with. So
the problem is not specific to C++. And anyway, C++ was an important,
usable, and surprisingly portable language for many years before the
1998 Standard was issued.

The wording of the C++ Standard could and should be better. A formal
glossary of terms will help the authors express their exact meanings more
effectively. It will help avoid ambiguities in the specification. It will
help implementers to correctly, consistently and efficiently write
compilers. It will make the language easier to teach and to learn. It will
facilitate adding or modifying features (in the _rare_ cases when that is
needed). It will help identify and eliminate design flaws. And most
importantly, it will make the language easier and more enjoyable to use.

IMO comparing C++ (or the Standard document) to other languages is less
beneficial in most cases than comparing it to its potential.
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,147
Latest member
CarenSchni
Top