Hypothetical: All code in classes but main()

S

Steven T. Hatton

Mark said:
What point? And supports it how? It still makes no sense to me.

The point you think it supports. I was explaining why there is a problem
with implementing the hypothesis.

I did not say class static functions, I said static functions, which is
equivalent to globabl functions.

I'm not familiar with that usage. It certainly wasn't what was implied by
the context.
While you are technically right, that a class static function can access
all data members, if it needs to access private and protected instance
members, why is it a class static function?

One reason for having a static member function is to implement a singleton
design pattern.

From GoF page 129:

The Singleton class is declared as

class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};

The corresponding implementation is

Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance () {
if (_instance == 0) {
_instance = new Singleton;
}
return _instance;
}

Actually, that brings up another area that you're way out in left field
on. Public data members. I was actually shaking my head in disbelief at
your proposed "associated" extension. I have never heard any recommend
the use of public data members in good OO design.

The suggestion was based on Stroustrup's advice to "[p]refer nonmember
functions over member functions for operations that do not need access to
the representation". And "use namespaces to associate helper functions with
'their' class".

My statement was:
"I actually proposed another access specifier in addition to private,
protected, public and firend. I suggested /associated/ which would allow a
function to be a member, but it would only have access to public members of
its own class."

Observe that I did not specify member *data*, but merely /members/.
It violates
encapsulation. I have heard some Java wags claim that for performance
reasons the cost of the accessor methods can be too much, but even that
has been debunked as nonsense. Just declare your accessor methods final
and most compilers will optimize them away.

And what happens to inheritance?
There are no benefits to public data members except for backwards
compatability with old C code (and that is not an issue in this
discussion).

How bout public member functions? But, please take this one up with
Stroustrup. He's the one who made the original recommendation about helper
functions not having unnecessary access to the private and protected
members.
If you have a reasonably good IDE its very easy to type:
java.[get a listing of available packages and classes]

Oh my lord. Your justification for a restrictive design constraint to be
applied to an entire body of work is that it makes it easier to make
flashy IDE's?

No, that wasn't my point. But I have advocated making IDE support a formal
considderation when designing the language.
But I'll tell you what, I'll play along.

Why is it not possible for a C++ ide to detect a function sin() in a
namespace math in a namespace top?

Did I say it wasn't?

There is no other level of encapsulation, encapsulation happens (as it
does in Java) at the class level. If you expose the guts of your class,
that is hardly the fault of an external function.

You missed the point.

I thought the structure was quite clear. All the math functions are in
the Math namespace.

What you're telling me is that you think having all the math functions
in the Math class is more structured than having all the math functions
in the Math namespace. But they're the same thing.

No. It's more structured than std::tanh().
The price is that I now have to include ALL the math functions in a
source file, even if I just want sqrt(). Also, if I have 1000+ math
functions (which is not inconceivable, what with overloads and all), and
I want to change or add just one,

I would never advocate putting 1000+ functions in a flat structure. But,
for people who think like that, there is really no cure.

Your point? Some Java programmers believe that public data members are a
viable option. I wouldn't hire from either group.

As you will:

http://java.sun.com/products/java-m...3D_1_3_API/j3dapi/javax/vecmath/Matrix3f.html
(because OO is not exactly written in stone, you know, there are many
interpretations of the OO gospel), I will point out instead that OO is
hardly the last word in software design theory. Just search for object
oriented critiques, and alternatives.

[This response intentionally left blank]
The problem with that is that you're not using the tools effectively. In
fact, you're not using the tools at all. Namespace-scope functions are
tools, too. They are designed to solve a specific problem: operations
that are not associated with class data. You're tossing the screwdriver
aside and using the hammer to drive screws.

[This response intentionally left blank]

And no, I've never wondered why any german thinker for english crockery
would mean table, and for what. And I'm sure there is a lesson there,
there are lessons everywhere. The questions should, is it a good lesson?
And, is it relevant?

It derives from the same Latin word which was a post with an eating surface
on top which the Roman soldiers (Many of whom were Germanic) used. As time
went on, the word came to mean two distinct things in the respective
Germanic languages. The point is that ideas associated with words change
over time, and space. This is especially true if words are used in
evolving fields.

There is no illusion. You can have as many main() functions as you want.
You specify namespaces for main() functions the same way as for any
other function. You can only have one *entry point*, but that's true for
Java too (in the least illogical case). The only "restriction" here is
that the main() function in the global namespace is the entry point.

I meant the main() in the global namespace. There is no point in having a
non-global main() in C++. I simply assumed that was a foregone conclusion,
so I didn't bother to go into the details.
Java's restriction is no less restricting: the entry point must be a
static function called main in your startup class. You can have static
functions called main in other classes if you want. You can have free
main functions in other namespaces if you want. What's the problem?

But you can call ClassName.main(String[] args), or otherwise use any class
with a function main() without recompiling.
It could also be argued that the world is a flat plate resting on the
back of an infinitely high pile of turtles, and that there are fairies
whose job it is to catch us when we fall off one side and put us on the
other and to alter all of our memories and measurements to keep the
truth from us. That doesn't make it right.

Well, there are different categorizations of the general field of
Mathematics which are called for example Vector Math, Discrete Math,
Applied Math...
If you really understood object oriented terminology, you'd be laughing
at the idea of instantiating math. What's next, inheriting from Humour?
Extending Peace? Overriding Truth?

That is, if I cared to consider any of the foregoing diversion.
Unless, of course, you're doing math.

This is just the first hit on a google for "functional operator":
http://nyjm.albany.edu:8000/j/1999/5-12.pdf
And of course, it doesn't answer the cardinal question. If Java is the
model that C++ should follow, why does Java keep evolving to look more
like C++?

Who suggested C++ should be more like Java? The only reason I've been
discussing Java in this context is because it provides a relevant example
of a programming language that requires the *hypothetical* proposition.
 
M

Mark A. Gibbs

Steven said:
One reason for having a static member function is to implement a singleton
design pattern.

That is about the only reason I could have come up with, too.
Actually, that brings up another area that you're way out in left field
on. Public data members. I was actually shaking my head in disbelief at
your proposed "associated" extension. I have never heard any recommend
the use of public data members in good OO design.


The suggestion was based on Stroustrup's advice to "[p]refer nonmember
functions over member functions for operations that do not need access to
the representation". And "use namespaces to associate helper functions with
'their' class".

My statement was:
"I actually proposed another access specifier in addition to private,
protected, public and firend. I suggested /associated/ which would allow a
function to be a member, but it would only have access to public members of
its own class."

Observe that I did not specify member *data*, but merely /members/.

Ah, now I'm finally understanding you.
And what happens to inheritance?

Same thing as would happen if you'd used a public data member. Accessor
functions in their purest form are just encapsulation. The fact that you
can extend them with behaviour beyond the capabilities of a public data
member (such as by making them polymorphically smart) is the icing on
that cake.
How bout public member functions? But, please take this one up with
Stroustrup. He's the one who made the original recommendation about helper
functions not having unnecessary access to the private and protected
members.

*Ahem* you're warping Stroustrup's comments way out of what he meant
when he made them. In fact, he's disagreeing with you. Stroustrup is
saying that if you have an operation that doesn't need to be a member,
don't make it one, make it a free function.

Frankly, I agree. Putting those helper functions in the class simply
bloats the class, making it more difficult to maintain.

But in the end, none of this supports or challenges your position
anyway. In this context, our debate simply becomes:

class Foo
{
public:
void foo();
// other foo interface functions
};

class FooHelper
{
public:
static void foo_helper();
// other foo interface functions
};

vs:

namespace foospace {

class Foo
{
public:
void foo();
// other foo interface functions
};

void foo_helper();
// other foo interface functions

}

And you haven't taken a single step further in your support of your
position.
No, that wasn't my point. But I have advocated making IDE support a formal
considderation when designing the language.

A consideration? Sure. After capability, portability, ease of use and
efficiency, of course.
No. It's more structured than std::tanh().

That goes without saying, but the STL is a special case. You're not
going to be rewriting it, so it's design is hardly relevant, except,
perhaps, as a curiosity.

What is relevant is code that you and I will design, and why
objects-only design is better than objects-and-free-functions design (or
am I in the wrong thread)? I, and I imagine you also, would not do
something like:

namespace everything {
// and put every damn thing free in it
}

I, and I imagine you also (if you were doing things my way), would do it
more like this:

namespace everything {
namespace math {
// and put every math function here
}
}

You may even choose to put sub-namespaces in math, such as vector_math,
calculus, the_new_math, and lies, damn_lies and statistics.

All of this is irrelevant to the discussion. I ask again (and again, and
again) - and each time I have to make the request more pedantically
clear, so here is the next step - given a reasonably intelligently
designed class and namespace hierarcy (or class and package hierarchy if
you prefer), what are the concrete advantages of taking all the free
functions from their requisite namespaces (in my version) and putting
them into non-instantiable classes as class-static functions? Don't
quote me the Java API - this is C++ - don't quote me physics or maths
theories, military practice, nordic linguistics, Kierkegaard, Chomsky or
Jim Morrison, and for the love of god, don't stray foul of Godwin's Law.

Let me help you along with a recap of what (I hope) we agree on so far.
- Neither paradigm offers runtime performance benefits.
- Neither paradigm offers functionality that the other cannot also provide.
- Neither paradigm increases or decreases the level of encapsulation or
coupling in classes *used by* (my version) free functions or (your
version) class static functions (assuming you follow Stroustrup's advice
and do not put helper functions in the original class - that you instead
put them in another class (and don't you agree with me (and good old
Bjarne) that that's wise?)).
I would never advocate putting 1000+ functions in a flat structure. But,
for people who think like that, there is really no cure.

I wholeheartedly agree.

http://www.cse.unsw.edu.au/~cs3421/jogl/javadoc_public/net/java/games/jogl/GL.html

[WARNING! May crash some browsers due to it's size]

*sigh*

And this makes it intelligent?

(It does make it amusing though, since Sun has withdrawn support for
Java3D in favour of JOGL (see the link I posted above for a peek at
*that* atrocity). Would you call JOGL an improvement over Java3D? Sun
thinks so, and gosh darn it, they *must* be right, right?)
I meant the main() in the global namespace. There is no point in having a
non-global main() in C++. I simply assumed that was a foregone conclusion,
so I didn't bother to go into the details.

Before I say anything else, let me point out that this has nothing to do
with your thesis.

But, for the record. Standard C++ does not allow for multiple entry
points. You're comparing apples and oranges. C++ does not know anything
about dynamically linked libraries (or .class files, which are the same
thing) either.

HOWEVER. If you wanted you could have as many entry points as you needed
in your program. It's not hard, and it's not unheard of. Virtually
everything I do in windows ends up as a bunch of .dll's with at least
one .exe. Usually I have one entry point - one main - in the standard
startup exe, and another entry point - another main - in a "debug mode"
startup exe. Most of the time the debug's main calls the standard main
after setting some stuff up.

As for how to actually go about doing it:
a) it has nothing to do with this discussion
and
b) it has nothing to do with this newsgroup
But you can call ClassName.main(String[] args), or otherwise use any class
with a function main() without recompiling.
ClassName::main(vector said:
Unless, of course, you're doing math.


This is just the first hit on a google for "functional operator":
http://nyjm.albany.edu:8000/j/1999/5-12.pdf

But did you read it? It has no relevance here.

All I have to do in my programs is a little bit of vector algebra, some
trigonometry and a couple of numeric method estimations.

And tell me honestly, what is more legible:

vector3d a(1, 2, 3);
vector3d b(4, 5, 6);
float a_dot_a = a.x() * a.x() +
a.y() * a.y() +
a.z() * a.z();
float a_dot_b = a.x() * b.x() +
a.y() * b.y() +
a.z() * b.z();
vector3d proj_b_onto_a = (a_dot_b / a_dot_a) * a;

Or:

vector3d a(1, 2, 3);
vector3d b(4, 5, 6);
float a_dot_a = add(add(multiply(a.x(), a.x()),
multiply(a.y(), a.y())),
multiply(a.z(), a.z()));
float a_dot_b = add(add(multiply(a.x(), b.x()),
multiply(a.y(), b.y())),
multiply(a.z(), b.z()));
vector3d proj_b_onto_a = multiply(divide(a_dot_b, a_dot_a), a);

Besides, if operator overloading is so bad, why does Java break it's own
rules to allow String classes to do it?
Who suggested C++ should be more like Java? The only reason I've been
discussing Java in this context is because it provides a relevant example
of a programming language that requires the *hypothetical* proposition.

The last iteration of Java I did any extensive work with was 1.4, which
was proud of it's shiny new "assert". Before that, Java was all hot and
bothered about it's neat stream library (which looks remarkably like the
ostream hierarchy), and another time it was it's "Iterator" concept.
When I last looked at Java, there was very serious talk of adding
templates to the language, by way of an experimental language called
(honestly) Pizza, along with enumerations (about time) and variable
length argument functions. Yes, that's right, they were seriously
discussing variable length argument functions.

mark
 
S

Steven T. Hatton

Steven T. Hatton wrote:


I could be argued that /a/ math does have a cosine. But I would tend to
argue that for practical purposes, there is only one (singleton) math.
Math /is/ actually instantiated implicitly in Java.

I want to clarify this statement because it is technically incorrect. The
class is initialized, but not actually instantiated. In the case of a
class with all static members, the distinction is negligible. My point is
that the class is available in memory. And yes, this is a cost of the
hypothetical proposition.

http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html#44557
 
C

Cy Edmunds

Steven T. Hatton said:
This is a purely *hypothetical* question. That means, it's /pretend/,
CP. ;-)

If you were forced at gunpoint to put all your code in classes,
[snip]

I would have to be convinced the gun was loaded and the person holding it
was very, very serious.

Some things are just naturally functions and other things are just naturally
classes. Expressing one as the other just obfuscates the code.
 
S

Steven T. Hatton

Mark said:
*Ahem* you're warping Stroustrup's comments way out of what he meant
when he made them. In fact, he's disagreeing with you. Stroustrup is
saying that if you have an operation that doesn't need to be a member,
don't make it one, make it a free function.

No, I am not warping what Stroustrup said. I am addressing the reasoning
behind the guideline. The reason is that he believes it is bad to have the
potential for binding helper functions unnecessarily to the
representation(private and protected data).
Frankly, I agree. Putting those helper functions in the class simply
bloats the class, making it more difficult to maintain.

It is specifically an issue of preventing unnecessary dependencies between
the functions and the representation.
And you haven't taken a single step further in your support of your
position.

I'm not really sure what you are talking about. If it's the proposition
regarding an /associated/ access specifier I don't believe you understand
the situation well enough to judge.
A consideration? Sure. After capability, portability, ease of use and
efficiency, of course.

Ease of use and IDE support are inseparable for all intents and purposes.
That goes without saying, but the STL is a special case. You're not
going to be rewriting it, so it's design is hardly relevant, except,
perhaps, as a curiosity.

The design of the STL is not ideal from an ease of use perspective, and it
sets a very bad precedent IMO. The reason it is the way it is, probably
his historical, and reflects so kind of early limitation. I hope it is
changed in C++0X.
I, and I imagine you also (if you were doing things my way), would do it
more like this:

namespace everything {
namespace math {
// and put every math function here
}
}

Yes, I would do basically that.
You may even choose to put sub-namespaces in math, such as vector_math,
calculus, the_new_math, and lies, damn_lies and statistics.
Yup.

All of this is irrelevant to the discussion. I ask again (and again, and
again) - and each time I have to make the request more pedantically
clear, so here is the next step - given a reasonably intelligently
designed class and namespace hierarcy (or class and package hierarchy if
you prefer), what are the concrete advantages of taking all the free
functions from their requisite namespaces (in my version) and putting
them into non-instantiable classes as class-static functions?

Yes, you understand the question I asked. Answering that question was the
goal of posing the hypothetical proposition.
Let me help you along with a recap of what (I hope) we agree on so far.
- Neither paradigm offers runtime performance benefits.
- Neither paradigm offers functionality that the other cannot also
provide. - Neither paradigm increases or decreases the level of
encapsulation or coupling in classes *used by* (my version) free functions
or (your version) class static functions (assuming you follow Stroustrup's
advice and do not put helper functions in the original class - that you
instead put them in another class (and don't you agree with me (and good
old Bjarne) that that's wise?)).

Since I've already acknowledged that helper functions present a problem, the
exercise of putting them in another class is not something I would
consider, unless it happened to be a base class of the classes being
operated on. But I haven't thought the consequences of that proposition
through, so it is not intended as anything more than a speculation.

*sigh*

And this makes it intelligent?

(It does make it amusing though, since Sun has withdrawn support for
Java3D in favour of JOGL (see the link I posted above for a peek at
*that* atrocity). Would you call JOGL an improvement over Java3D? Sun
thinks so, and gosh darn it, they *must* be right, right?)

Well, this is going off topic, but basically that's far from clear. Java3D
and Jogl are not comperable products. Jogl is in interface to OpenGL, and
does not provide any of the highlevel API that Java3D does. Additionally,
the package I posted a link to was not javax.media.j3d. It just happens to
be bundled with java3d.
Before I say anything else, let me point out that this has nothing to do
with your thesis.

But, for the record. Standard C++ does not allow for multiple entry
points.
Yes, I know that. It is specified in Clause 3.6.1 of ISO/IEC 14882-2003(E)
which I have sitting right here in my lap. As I said.
You're comparing apples and oranges. C++ does not know anything
about dynamically linked libraries (or .class files, which are the same
thing) either.
No.

HOWEVER. If you wanted you could have as many entry points as you needed
in your program. It's not hard, and it's not unheard of. Virtually
everything I do in windows ends up as a bunch of .dll's with at least
one .exe. Usually I have one entry point - one main - in the standard
startup exe, and another entry point - another main - in a "debug mode"
startup exe. Most of the time the debug's main calls the standard main
after setting some stuff up.

[basic.start.main] 3.6.1 Main function

1 A program shall contain a global function called main, which is the
designated start of the program. It is implementation-defined whether a
program in a freestanding environment is required to define a main
function. [Note: in a freestanding environment, start-up and termination is
implementation-defined; startup contains the execution of constructors for
objects of namespace scope with static storage duration; termination
contains the execution of destructors for objects with static storage
duration. ]

2 An implementation shall not predefine the main function. This function
shall not be overloaded. It shall have a return type of type int, but
otherwise its type is implementation-defined. All implementations shall
allow both of the following definitions of main:

int main() { /* ... */ }

and

int main(int argc, char* argv[]) { /* ... */ }

In the latter form argc shall be the number of arguments passed to the
program from the environment in which the program is run. If argc is
nonzero these arguments shall be supplied in argv[0] through argv[argc-1]
as pointers to the initial characters of null-terminated multibyte strings
(NTMBSs) (17.3.2.1.3.2) and argv[0] shall be the pointer to the initial
character of a NTMBS that represents the name used to invoke the program or
"". The value of argc shall be nonnegative. The value of argv[argc] shall
be 0. [Note: it is recommended that any further (optional) parameters be
added after argv. ]

3 The function main shall not be used (3.2) within a program. The linkage
(3.5) of main is implementation-defined. A program that declares main to be
inline or static is ill-formed. The name main is not otherwise reserved.
[Example: member functions, classes, and enumerations can be called main,
as can entities in other namespaces. ]

4 Calling the function void exit(int); declared in <cstdlib> (18.3)
terminates the program without leaving the current block and hence without
destroying any objects with automatic storage duration (12.4). If exit is
called to end a program during the destruction of an object with static
storage duration, the program has undefined behavior.

5 A return statement in main has the effect of leaving the main function
(destroying any objects with automatic storage duration) and calling exit
with the return value as the argument. If control reaches the end of main
without encountering a return statement, the effect is that of executing
return 0;

Now I have to leave this thread and get back to reading informed texts on
the subject of C++.
 
M

Mark A. Gibbs

Steven said:
No, I am not warping what Stroustrup said. I am addressing the reasoning
behind the guideline. The reason is that he believes it is bad to have the
potential for binding helper functions unnecessarily to the
representation(private and protected data).

Given your odd "associated" access specifier, I can see how you think
this supports your position. As I've made quite clear, I refuse to
discuss extending the language with you. Not only am I not enough of an
expert to do so properly - and I don't believe you are, either - this is
not a forum for discussing changing the standard, it is a forum for
discussing using it. I tend to believe that Stroustrup's statement was
also not intended to support adding another access specifier when it is
not necessary, but I'll let him speak for himself on that one.

So, given that we are actually discussing C++ in comp.lang.c++, I see no
rational interpretation of that point that does not support free functions.

Besides, given:

class A {};
class B {};

void helper(A, B);

Where does helper() go?
It is specifically an issue of preventing unnecessary dependencies between
the functions and the representation.

In your mind. A maintennance programmer would balk at needlessly
expanding classes, access specifier or no.
I'm not really sure what you are talking about. If it's the proposition
regarding an /associated/ access specifier I don't believe you understand
the situation well enough to judge.

I find it odd that you are so confident of your "couple months of real
C++ experience" that you so casually write of my several years' worth. I
find it quite bizarre, and more than slightly arrogant, that you believe
a "couple months of real C++ experience" endows you with enough wisdom
and practice to begin proposing extensions to the core of the language.
I am not amused by this unwarranted condenscention from one who finds it
necessary to slip crib notes on properly accessing struct members via a
pointer in his signature.

I was not talking about any mythical "associated" access specifier, I
was - remarkably enough - talking about C++ and the hypothetical
benefits and concerns of putting all program code into classes (except
main), which are - even more remarkably - the topics of this forum, and
this thread specifically. And, as I mentioned, you have not even come
close to a reasonable defense of your position.
Ease of use and IDE support are inseparable for all intents and purposes.

Bullshit. Language simplicity may be correlated to IDE coolness, but not
ease of use. Java is a very simple language. It is also very hard to use
in some cases - for example, RAII. Ease of use does not necessarily
equal simplicity.

C++ is a very complex language, and it can be very difficult to use - or
it can be a snap, depending on what you want to do.

Forcing all functions to be in classes offers some kind of simplicity to
the language, but it does not improve its ease of use - after all, how
can you increase something's ease of use when you take functionality
away? Denying programmers a tool does not help them. If the tool is
problematic, then they can be cautioned to not use it unless absolutely
necessary. I am growing old waiting to hear how free functions are
problematic.
The design of the STL is not ideal from an ease of use perspective, and it
sets a very bad precedent IMO. The reason it is the way it is, probably
his historical, and reflects so kind of early limitation. I hope it is
changed in C++0X.

The hell part of "it's design is hardly relevant, except, perhaps, as a
curiosity" did you not understand?
Yes, you understand the question I asked. Answering that question was the
goal of posing the hypothetical proposition.

Is this a joke? After me begging and pleading and damn near demanding
that you provide *some* kind of answer, all you can say is "yes, you're
right, an answer is needed"? This is downright surreal.
Since I've already acknowledged that helper functions present a problem, the
exercise of putting them in another class is not something I would
consider, unless it happened to be a base class of the classes being
operated on. But I haven't thought the consequences of that proposition
through, so it is not intended as anything more than a speculation.

You claimed it was a problem without backing it up at all. That may work
in politics and religion, but not in science.

And I have invited you repeatedly to think more on your proposition. To
date, as noted elsewhere, nothing.
Before I say anything else, let me point out that this has nothing to do
with your thesis.

But, for the record. Standard C++ does not allow for multiple entry
points.

Yes, I know that. It is specified in Clause 3.6.1 of ISO/IEC 14882-2003(E)
which I have sitting right here in my lap. As I said.
[snip]
HOWEVER. If you wanted you could have as many entry points as you needed
in your program. It's not hard, and it's not unheard of. Virtually
everything I do in windows ends up as a bunch of .dll's with at least
one .exe. Usually I have one entry point - one main - in the standard
startup exe, and another entry point - another main - in a "debug mode"
startup exe. Most of the time the debug's main calls the standard main
after setting some stuff up.


[basic.start.main] 3.6.1 Main function

[snip]

So after I stated that the information posted was not really relevant to
the discussion, AND that it was not standard C++, you post almost 50
lines of standard text that you could have summed up in less than five
(including directing me to the relevant sections, of course).

I posted that outline to be instructive, to demonstrate the flexibility
that is possible. So you know, at no point - ANYWHERE - do I violate the
letter of the standard (ie, any of the 50-odd lines you posted) in
achieving this flexibility insofar as it applies to having multiple
mains (of course, I do so by using DLL's, but they are not technically
necessary). That's right, I have more than one main, I can start the
program with any of them - determined at run time even - and I can do
all this without even bending standard law. I don't even NEED windows to
do it, but the windows solution is closer in spirit to the Java one,
which is why I mentioned it.

It's not magic, it's just knowing the language. And knowing the language
is a wise step to take before criticising it.

Curious as to how to do it? Well, I'd love to tell you, but...
Now I have to leave this thread and get back to reading informed texts on
the subject of C++.

Ah well. So much for learning anything here.

I hope they teach you more than I got out of this chat. Otherwise, I
hope you didn't pay much for them.

mark
 
S

Steven T. Hatton

Mark said:
Given your odd "associated" access specifier, I can see how you think
this supports your position.

I merely mentioned the suggestion because it served as a means for
highlighting the issue.
As I've made quite clear, I refuse to
discuss extending the language with you. Not only am I not enough of an
expert to do so properly - and I don't believe you are, either - this is
not a forum for discussing changing the standard, it is a forum for
discussing using it.

More correctly, it is not the forum for directly attempting to change the
Standard. The idea that I have to limit my discussions to chapter and verse
of the standard, and not discuss any possible changes to it, is simply a
misunderstand of the FAQ.
I tend to believe that Stroustrup's statement was
also not intended to support adding another access specifier when it is
not necessary, but I'll let him speak for himself on that one.

But you were arguing agains the reasoning which was shared by both
solutions.
In your mind. A maintennance programmer would balk at needlessly
expanding classes, access specifier or no.

And they would not balk at the same number of helper functions placed in the
namespace a peers of their related classes as well as unrelated classes?
I find it odd that you are so confident of your "couple months of real
C++ experience" that you so casually write of my several years' worth.

But I have over 2 decades of experience in the computer field. (Some of that
was working with 'embedded systems', not 'computers' per se). I also have
a degree in computer science. It's really not a question of confidence. I
simply had an idea, and suggested it. I didn't really expect it to be
given too much serious consideration. It's biggest drawback is getting
anybody to understand it. I suspect that's why Stroustrup didn't do it in
the first place.
I
find it quite bizarre, and more than slightly arrogant, that you believe
a "couple months of real C++ experience" endows you with enough wisdom
and practice to begin proposing extensions to the core of the language.
I am not amused by this unwarranted condenscention from one who finds it
necessary to slip crib notes on properly accessing struct members via a
pointer in his signature.

So ad homenim is a valid consideration in assessing the merits of a logical
proposition?
I was not talking about any mythical "associated" access specifier,
http://www.dict.org

I
was - remarkably enough - talking about C++ and the hypothetical
benefits and concerns of putting all program code into classes (except
main), which are - even more remarkably - the topics of this forum, and
this thread specifically. And, as I mentioned, you have not even come
close to a reasonable defense of your position.

It was not posed as a debate. The most I've said, is that I tend to favor
the approach. There are other reasons that I have not mentioned, but, at
this point I don't care to continue the exercise.
Bullshit. Language simplicity may be correlated to IDE coolness, but not
ease of use. Java is a very simple language. It is also very hard to use
in some cases - for example, RAII. Ease of use does not necessarily
equal simplicity.

It seems pretty easy to use and simple to me. But what you are failing to
understand is that computers are tools for infomation processing,
management, storage and retrieval. Programming libraries are examples of
stored information. IDEs which can query such stores of information, and
present it to the programmer in an effective way.
C++ is a very complex language, and it can be very difficult to use - or
it can be a snap, depending on what you want to do.

Forcing all functions to be in classes offers some kind of simplicity to
the language, but it does not improve its ease of use - after all, how
can you increase something's ease of use when you take functionality
away?

There's really no point in trying to answer that question.
Is this a joke? After me begging and pleading and damn near demanding
that you provide *some* kind of answer, all you can say is "yes, you're
right, an answer is needed"? This is downright surreal.

No. It's simply a misunderstanding on your part.
 
B

Bjarne Stroustrup

Mark A. Gibbs said:
So, given that we are actually discussing C++ in comp.lang.c++, I see no
rational interpretation of that point that does not support free functions.

Besides, given:

class A {};
class B {};

void helper(A, B);

Where does helper() go?

Two comments:

(1) I have never been seriously tempted to put all functions into
classes. Doing so would simply lead to the kind of workarounds/hacks
that you find in Java (e.g. the standard math functions). Lots of
functions really don't have state and shouldn't pretend to by being
part of a class. Versions of the brief argument above is present in my
writings on C++ from the earliest days. A slightly stronger version is
that in the absence of ordinary ("free-standing") functions, a binary
operator, say +, would have to have two separate definitions (one in
each argument class) to be symmetric.

(2) In this discussion, there have been some conjectures made about my
"real opinions". I tend to dislike such conjectures in general, and I
find them rather odd when juxtaposed with statements to the effect
that the person making them hasn't read "The Design and Evolution of
C++". D&E isn't perfect, of course, but it is a clearer statement of
my intent vis-avis C++ than you can find for most languages.

- Bjarne Stroustrup; http://www.research.att.com/~bs
 
S

Steven T. Hatton

Bjarne Stroustrup wrote:

Two comments:

(1) I have never been seriously tempted to put all functions into
classes. Doing so would simply lead to the kind of workarounds/hacks
that you find in Java (e.g. the standard math functions).

What aspect of Java are you specifically referring to? If it has to do with
the less than consice mechanisms involved with wrapping and unwrapping
primitive types, I can appreciate your position. Much of the awkwardness
of Java's math operators is due to the lack of user defined operator
overloading. Add to that, the less flexible type conversion, and Java's
Mathematical operations end up looking very different from traditional
mathematical expressions. OTOH, some of it is simply an issue of learning a
different approach to working with symbols to accomplish the same thing.

I haven't had a chance to really get into C++ 3D graphics. I downloaded
coin3d last night/this morning, and got most of it to compile. The reason
I mention this is that I have worked with Java3D which can be awkward to a
point of near absurdity at times. I sincerely hope I find in C++ a way to
apply transformations and perform other multivariable operations in a more
intuitive and _consice_ way. But that hope is based on the facilities for
operator overloading not namespace local 'free-standing' operators.
Lots of
functions really don't have state and shouldn't pretend to by being
part of a class. Versions of the brief argument above is present in my
writings on C++ from the earliest days. A slightly stronger version is
that in the absence of ordinary ("free-standing") functions, a binary
operator, say +, would have to have two separate definitions (one in
each argument class) to be symmetric.

"I believe there is actually a technical limitation met when binary
operators (ones that take two arguments) are forced to be class
members.  I need to review the section, but I believe there are some
symmetries that are lost. IOW A@B works but B@A doesn't for cases such as
'+' and '*'.  Another problem is the fact that functions which were
external to a class now gain access to member data and potentially become
bound to it.  This is the argument Stroustrup gives for having helper
functions at namespace scope."

"I actually proposed another access specifier in addition to private,
protected, public and firend.  I suggested /associated/ which would allow a
function to be a member, but it would only have access to public members of
its own class."

To address the broken symmetry, I wold follow the reasoning of abstract
algebra and class thing which obey the same operation semantics together.
(2) In this discussion, there have been some conjectures made about my
"real opinions".

After carefully reviewing the thread, I found the following statement to be
the only conjectural statement regarding your opinions:

I simply had an idea, and suggested it.  I didn't really expect it to be
given too much serious consideration.  It's biggest drawback is getting
anybody to understand it.  I suspect that's why Stroustrup didn't do it in
the first place.

If this is the conjectural opinion you have taken issue with, I apologize. I
merely assumed you most likely had considered something along the lines of
what I was thinking.
I tend to dislike such conjectures in general, and I
find them rather odd when juxtaposed with statements to the effect
that the person making them hasn't read "The Design and Evolution of
C++". D&E isn't perfect, of course, but it is a clearer statement of
my intent vis-avis C++ than you can find for most languages.

I don't believe the following can be taken as conjecture:

"The suggestion was based on Stroustrup's advice to '[p]refer nonmember
functions over member functions for operations that do not need access to
the representation'. And 'se namespaces to associate helper functions
with 'their' class'."

I will admit there may be problems with what I proposed. OTOH,
classification practices in abstract algebra give me some confidence that
it really would work. As regards whether doing so is OO, or whether it is
appropriate to represent the collection of functions and Static values
found in java.lang.Math as a non-instantiable class, that is a
philosophical argument. I find little fault with that choice of the Java
designers. This falls under the same heading as the rather misguided notion
that the default equivalence method in Java does not represent equality.
It certainly does in the sense of a formal definition of equality used in
higher math. And it makes sense from a pragmatic standpoint as well.

I will have to review the technical implications of implementing
the /associated/ access modifier I suggested. And compare it with the
current use of namespaces to accomplish much the same thing. I find the
current combination of namespaces and headers in C++ to be a significant
challenge. It seems to encourage bad structure. I read Clause 3 of
ISO/IEC 14882:2003(E).
 
S

Steven T. Hatton

Steven said:
Bjarne Stroustrup wrote:


I read Clause 3 of ISO/IEC 14882:2003(E).

Here is a good graphical representation of how I view the current state of
affairs vis-a-vis header files and namespaces:

http://members.aol.com/KEN63728/bulks.htm

It's not too late to fix it...I hope.

I acknowledge that I could be wrong about these issues. Thusfar the retorts
have consisted mostly of invective ad hominem.

"Thanks for your message and good wishes had fine weather since leaving -
Smith" Captain Smith of H.M.S. Titanic to the Commander of the Baltic on 14
April 1912
 
S

Steven T. Hatton

Steven said:
I acknowledge that I could be wrong about these issues. Thusfar the
retorts have consisted mostly of invective ad hominem.

"Thanks for your message and good wishes had fine weather since leaving -
Smith" Captain Smith of H.M.S. Titanic to the Commander of the Baltic on
14 April 1912

To demonstrate both that I do make mistakes, and that I acknowledge them, as
well as to correct a mistake I made, I would like to clarify that the name
of the ship I was using as an example of a design that fails to
sufficiently isolate modules is not 'H.M.S. Titanic'. The correct name is
the /Royal Mail Steamer Titanic/ as in the following:

"Keep out! Shut up! You're jamming my signal! I'm working Cape Race" -
Wireless operator of The R.M.S. Titanic in response to an ice warning from
the Californian. This was the last ice warning the R.M.S Titanic received.
The wireless operator's response signified that the Californian's ice
warning message was interfering with personal messages to and from
passengers.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top