By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,635 Members | 2,174 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,635 IT Pros & Developers. It's quick & easy.

Hypothetical: All code in classes but main()

P: n/a
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, rather than
in namespace scope (obviously classes themselves are an exception to this),
and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program? Are there any benefits to doing things that way (other
than survival)?

BTW, yes, I /do/ favor this approach.
--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #1
Share this Question
Share on Google+
45 Replies


P: n/a

"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:gJ********************@speakeasy.net...
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, rather than in namespace scope (obviously classes themselves are an exception to this), and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program? Are there any benefits to doing things that way (other
than survival)?

BTW, yes, I /do/ favor this approach.


wow, finally I meet somebody who likes (c++) classes like me :). I am "with
you" ... I never really liked that c-style programming, if you can do the
same thing with classes, but this just my opinion and taste - I am not
saying, that I have the truth in this issue. Maybe its like that somebody
likes tea, but somebody else might hate tea but like coffee :).

I dont see eny limitations in "normal programming" - I would defenitely
choose class route if possible . I was jus thinking, that some very critical
fast code might need pure c-code because of efficiency. For example in chess
game programming you calculate 2 000 000 moves per second, so classes might
not be suitable in all programming because they might be a little bit too
slow ... but to be honest with you, I am not sure of this ... Does somebody
know if this is true or not?
Jul 22 '05 #2

P: n/a

"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:gJ********************@speakeasy.net...
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, rather than in namespace scope (obviously classes themselves are an exception to this), and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program? Are there any benefits to doing things that way (other
than survival)?

BTW, yes, I /do/ favor this approach.


wow, finally I meet somebody who likes (c++) classes like me :). I am "with
you" ... I never really liked that c-style programming, if you can do the
same thing with classes, but this just my opinion and taste - I am not
saying, that I have the truth in this issue. Maybe its like that somebody
likes tea, but somebody else might hate tea but like coffee :).

I dont see eny limitations in "normal programming" - I would defenitely
choose class route if possible . I was jus thinking, that some very critical
fast code might need pure c-code because of efficiency. For example in chess
game programming you calculate 2 000 000 moves per second, so classes might
not be suitable in all programming because they might be a little bit too
slow ... but to be honest with you, I am not sure of this ... Does somebody
know if this is true or not?
Jul 22 '05 #3

P: n/a
Steven T. Hatton wrote:
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, rather than
in namespace scope (obviously classes themselves are an exception to this),
and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program? Are there any benefits to doing things that way (other
than survival)?

BTW, yes, I /do/ favor this approach.


I almost always have a single object to represent the whole application,
and use main() only as an entry point. That said, forcing _everything_
into classes seems to disallow use of some of my favorite C++ features
and programming styles. For example, many operator overloads belong
outside the class.

template< typename T >
int add_one( T const& t )
{
return 1 + t; // If T is a UDT, where is operator + defined?
}
Jul 22 '05 #4

P: n/a
Steven T. Hatton wrote:
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, rather than
in namespace scope (obviously classes themselves are an exception to this),
and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program? Are there any benefits to doing things that way (other
than survival)?

BTW, yes, I /do/ favor this approach.


I almost always have a single object to represent the whole application,
and use main() only as an entry point. That said, forcing _everything_
into classes seems to disallow use of some of my favorite C++ features
and programming styles. For example, many operator overloads belong
outside the class.

template< typename T >
int add_one( T const& t )
{
return 1 + t; // If T is a UDT, where is operator + defined?
}
Jul 22 '05 #5

P: n/a

I normally don't jump into hypothetical discussions like this, but parts
of this just rankled me.

Juha Kettunen wrote:
"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:gJ********************@speakeasy.net...
[snip]
If you were forced at gunpoint to put all your code in classes, rather


than
in namespace scope (obviously classes themselves are an exception to


this),
and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program? Are there any benefits to doing things that way (other
than survival)?


Personally, I can see no practical functional limitations or benefits.

[snip]
I dont see eny limitations in "normal programming" - I would defenitely
choose class route if possible . I was jus thinking, that some very critical
fast code might need pure c-code because of efficiency. For example in chess
game programming you calculate 2 000 000 moves per second, so classes might
not be suitable in all programming because they might be a little bit too
slow ... but to be honest with you, I am not sure of this ... Does somebody
know if this is true or not?


Where this whole thing starts to spiral out of control is here. "C-code"
by itself is no slower or faster than the equivalent "C++-code" (ie,
class-based code). If you wanted to, you could write "slow" or "fast"
code in either. In fact, writing the theoretical "fastest" program is
possible in C and C++ - your compiler and your algorithm are what
determine how "fast" your code will run.

For the record, I make games, and I need "efficient" code to move big
chunks of data around very quickly. I use classes with impunity - the
things I usually watch for are polymorphism and virtual functions, and
hidden code (destructors and constructors that aren't immediately
obvious). And even these I use in some cases.

But being told to put all your code into classes is as illogical to me
as being told to use only words and phrases from Shakepeaean iambic
pentameter as variable names. Or, more practically but no less obtuse,
hungarian notation. Does it help anything? Not really. Does it hurt
anything? Not really. And if it does either it does them in equal
measure. So why insist on it?

I mean, compare the elegance of this:

int max(int a, int b) { return (a > b) ? a : b; }

int larger = max(1, 2);

To this:

class Math
{
public:
static int max(int a, int b) { return (a > b) ? a : b; }
};

int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.

Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.

What it is, is a design issue. What you're telling me is that there are
such things as "Math" objects. In order to find the max of two numbers,
I have to go get a "Math" and use the "Math"'s "max" operation. Or, in
the static case, that "Math"'s have a behaviour or mechanism that is not
specific to any one "Math", but is nonetheless "Math" object-specific
behaviour.

On the other hand, the free function tells me that "max" is an operation
in category (ie, namespace) "Math". In other words, "max" is a "Math"
operation.

Doesn't the latter just make more sense?

So in conclusion, what the hell are the benefits of such arbitrary
constraints? Write your program so that it makes logical sense and
models the problem it is trying to solve as closely as possible. If the
language has the tools, and if they don't lead to bad design and
maintennance problems, use them.

If you really feel the need to apply arbitrary constraints, why not
write your code in morse code ( http://www.ioccc.org/1986/hague.c )?

mark

Jul 22 '05 #6

P: n/a

I normally don't jump into hypothetical discussions like this, but parts
of this just rankled me.

Juha Kettunen wrote:
"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:gJ********************@speakeasy.net...
[snip]
If you were forced at gunpoint to put all your code in classes, rather


than
in namespace scope (obviously classes themselves are an exception to


this),
and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program? Are there any benefits to doing things that way (other
than survival)?


Personally, I can see no practical functional limitations or benefits.

[snip]
I dont see eny limitations in "normal programming" - I would defenitely
choose class route if possible . I was jus thinking, that some very critical
fast code might need pure c-code because of efficiency. For example in chess
game programming you calculate 2 000 000 moves per second, so classes might
not be suitable in all programming because they might be a little bit too
slow ... but to be honest with you, I am not sure of this ... Does somebody
know if this is true or not?


Where this whole thing starts to spiral out of control is here. "C-code"
by itself is no slower or faster than the equivalent "C++-code" (ie,
class-based code). If you wanted to, you could write "slow" or "fast"
code in either. In fact, writing the theoretical "fastest" program is
possible in C and C++ - your compiler and your algorithm are what
determine how "fast" your code will run.

For the record, I make games, and I need "efficient" code to move big
chunks of data around very quickly. I use classes with impunity - the
things I usually watch for are polymorphism and virtual functions, and
hidden code (destructors and constructors that aren't immediately
obvious). And even these I use in some cases.

But being told to put all your code into classes is as illogical to me
as being told to use only words and phrases from Shakepeaean iambic
pentameter as variable names. Or, more practically but no less obtuse,
hungarian notation. Does it help anything? Not really. Does it hurt
anything? Not really. And if it does either it does them in equal
measure. So why insist on it?

I mean, compare the elegance of this:

int max(int a, int b) { return (a > b) ? a : b; }

int larger = max(1, 2);

To this:

class Math
{
public:
static int max(int a, int b) { return (a > b) ? a : b; }
};

int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.

Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.

What it is, is a design issue. What you're telling me is that there are
such things as "Math" objects. In order to find the max of two numbers,
I have to go get a "Math" and use the "Math"'s "max" operation. Or, in
the static case, that "Math"'s have a behaviour or mechanism that is not
specific to any one "Math", but is nonetheless "Math" object-specific
behaviour.

On the other hand, the free function tells me that "max" is an operation
in category (ie, namespace) "Math". In other words, "max" is a "Math"
operation.

Doesn't the latter just make more sense?

So in conclusion, what the hell are the benefits of such arbitrary
constraints? Write your program so that it makes logical sense and
models the problem it is trying to solve as closely as possible. If the
language has the tools, and if they don't lead to bad design and
maintennance problems, use them.

If you really feel the need to apply arbitrary constraints, why not
write your code in morse code ( http://www.ioccc.org/1986/hague.c )?

mark

Jul 22 '05 #7

P: n/a
Jeff Schwab wrote:
Steven T. Hatton wrote:
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, rather
than in namespace scope (obviously classes themselves are an exception to
this), and 'bootstrap' your program by instantiating a single application
object in main(), would that place any limitations on what you could
accomplish
with your program? Are there any benefits to doing things that way
(other than survival)?

BTW, yes, I /do/ favor this approach.


I almost always have a single object to represent the whole application,
and use main() only as an entry point. That said, forcing _everything_
into classes seems to disallow use of some of my favorite C++ features
and programming styles. For example, many operator overloads belong
outside the class.

template< typename T >
int add_one( T const& t )
{
return 1 + t; // If T is a UDT, where is operator + defined?
}


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.
--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #8

P: n/a
Jeff Schwab wrote:
Steven T. Hatton wrote:
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, rather
than in namespace scope (obviously classes themselves are an exception to
this), and 'bootstrap' your program by instantiating a single application
object in main(), would that place any limitations on what you could
accomplish
with your program? Are there any benefits to doing things that way
(other than survival)?

BTW, yes, I /do/ favor this approach.


I almost always have a single object to represent the whole application,
and use main() only as an entry point. That said, forcing _everything_
into classes seems to disallow use of some of my favorite C++ features
and programming styles. For example, many operator overloads belong
outside the class.

template< typename T >
int add_one( T const& t )
{
return 1 + t; // If T is a UDT, where is operator + defined?
}


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.
--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #9

P: n/a
Mark A. Gibbs wrote:

I normally don't jump into hypothetical discussions like this, but parts
of this just rankled me.

Juha Kettunen wrote: [snip]
Personally, I can see no practical functional limitations or benefits.
I believe there actually are two. I already mentioned them in another post
in this thread.
Where this whole thing starts to spiral out of control is here. "C-code"
by itself is no slower or faster than the equivalent "C++-code" (ie,
class-based code). If you wanted to, you could write "slow" or "fast"
code in either. In fact, writing the theoretical "fastest" program is
possible in C and C++ - your compiler and your algorithm are what
determine how "fast" your code will run.
As you correctly pointed out below, virtual function calls have some
overhead beyond static calls. A static call to a member should be just as
fast as a global 'C'-style call, as far as I know.
But being told to put all your code into classes is as illogical to me
as being told to use only words and phrases from Shakepeaean iambic
pentameter as variable names. Or, more practically but no less obtuse,
hungarian notation. Does it help anything? Not really. Does it hurt
anything? Not really. And if it does either it does them in equal
measure. So why insist on it?
One argument would be for the sake of uniformity. But I guess that's just
the soldier in me talking.
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.
There are advantages to having the static Math class in Java. It provides
for an easy point of reference. It's kind of like having a directory
structure and using it to organize your data. Personally, the following is
my idea of what a more complete set of mathematical operators looks like in
a programming language. But MMA is a specialized language:

http://documents.wolfram.com/v5/TheM...tax/A.2.7.html
Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.
Other than the fact that people tend to be sloppy with namespaces.
What it is, is a design issue. What you're telling me is that there are
such things as "Math" objects.
No. It's saying there are mathematical operators which can be classified as
such.
In order to find the max of two numbers,
I have to go get a "Math" and use the "Math"'s "max" operation. Or, in
the static case, that "Math"'s have a behaviour or mechanism that is not
specific to any one "Math", but is nonetheless "Math" object-specific
behaviour.
You don't instantiate Math. It is a utilities class.
On the other hand, the free function tells me that "max" is an operation
in category (ie, namespace) "Math". In other words, "max" is a "Math"
operation.
And how does this differ from Java's use of a class where you use a
namespace?
Doesn't the latter just make more sense?
It depends how it's managed. Java takes the functional operator approach to
mathematical syntax, whereas C++ allows for infix notation. I find that
far more significant in terms of how it 'feels' to use. An interesting
parallel to this is found in Misner, Thorne and Wheeler's _Gravitation_
where three notational forms are used in parallel through out the text:

http://www.reviewcentre.com/review57645.html
So in conclusion, what the hell are the benefits of such arbitrary
constraints? Write your program so that it makes logical sense and
models the problem it is trying to solve as closely as possible. If the
language has the tools, and if they don't lead to bad design and
maintennance problems, use them.


Actually, this was a hypothetical proposition. One reason for putting
everything in classes is that it usually makes refactoring easier (with the
possible exception of helper functions), and also makes reuse easier.

--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #10

P: n/a
Mark A. Gibbs wrote:

I normally don't jump into hypothetical discussions like this, but parts
of this just rankled me.

Juha Kettunen wrote: [snip]
Personally, I can see no practical functional limitations or benefits.
I believe there actually are two. I already mentioned them in another post
in this thread.
Where this whole thing starts to spiral out of control is here. "C-code"
by itself is no slower or faster than the equivalent "C++-code" (ie,
class-based code). If you wanted to, you could write "slow" or "fast"
code in either. In fact, writing the theoretical "fastest" program is
possible in C and C++ - your compiler and your algorithm are what
determine how "fast" your code will run.
As you correctly pointed out below, virtual function calls have some
overhead beyond static calls. A static call to a member should be just as
fast as a global 'C'-style call, as far as I know.
But being told to put all your code into classes is as illogical to me
as being told to use only words and phrases from Shakepeaean iambic
pentameter as variable names. Or, more practically but no less obtuse,
hungarian notation. Does it help anything? Not really. Does it hurt
anything? Not really. And if it does either it does them in equal
measure. So why insist on it?
One argument would be for the sake of uniformity. But I guess that's just
the soldier in me talking.
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.
There are advantages to having the static Math class in Java. It provides
for an easy point of reference. It's kind of like having a directory
structure and using it to organize your data. Personally, the following is
my idea of what a more complete set of mathematical operators looks like in
a programming language. But MMA is a specialized language:

http://documents.wolfram.com/v5/TheM...tax/A.2.7.html
Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.
Other than the fact that people tend to be sloppy with namespaces.
What it is, is a design issue. What you're telling me is that there are
such things as "Math" objects.
No. It's saying there are mathematical operators which can be classified as
such.
In order to find the max of two numbers,
I have to go get a "Math" and use the "Math"'s "max" operation. Or, in
the static case, that "Math"'s have a behaviour or mechanism that is not
specific to any one "Math", but is nonetheless "Math" object-specific
behaviour.
You don't instantiate Math. It is a utilities class.
On the other hand, the free function tells me that "max" is an operation
in category (ie, namespace) "Math". In other words, "max" is a "Math"
operation.
And how does this differ from Java's use of a class where you use a
namespace?
Doesn't the latter just make more sense?
It depends how it's managed. Java takes the functional operator approach to
mathematical syntax, whereas C++ allows for infix notation. I find that
far more significant in terms of how it 'feels' to use. An interesting
parallel to this is found in Misner, Thorne and Wheeler's _Gravitation_
where three notational forms are used in parallel through out the text:

http://www.reviewcentre.com/review57645.html
So in conclusion, what the hell are the benefits of such arbitrary
constraints? Write your program so that it makes logical sense and
models the problem it is trying to solve as closely as possible. If the
language has the tools, and if they don't lead to bad design and
maintennance problems, use them.


Actually, this was a hypothetical proposition. One reason for putting
everything in classes is that it usually makes refactoring easier (with the
possible exception of helper functions), and also makes reuse easier.

--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #11

P: n/a

Steven T. Hatton wrote:
Mark A. Gibbs wrote:
Personally, I can see no practical functional limitations or benefits.

I believe there actually are two. I already mentioned them in another post
in this thread.


Two what? Limitations or benefits? Are you referring to your comments on
assymetrical binary operations? That is not a design issue, that's an
implementation issue. If you want an operation a @ b to be valid for
objects of type A and B in any order you either have to define
operator@(A) in B and operator@(B) in A (thus coupling the two), or
define operator@(B) in A and operator@(A,B) globally (still coupling the
two), or define operator@(A,B) and operator@(B,A) globally (leaving the
classes uncoupled). To me, this *supports* non-class functions.

But whatever you decide out of the above options, you are limited by the
language. you could write add(A,B) and add(B,A) as class members (of
either class) with no problems. If you are talking about limitations of
possible implementations due to constraints of the language, count me
out. I have no intention of discussing alterations to the language. I
was talking about limitations on possible designs and program structures.

Your second argument, if I understood it, makes no sense. "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." So does that support your argument or not?

If a function requires access to member data, then by all means make it
a member function. But static functions can't access member data, now
can they? If they require access to static data, well that's different.
But if you have a function that does not require instance-specific data,
and does not require a class-global data (such as max()), you can choose
to use either a static member function or a non-class function without
concern.
Where this whole thing starts to spiral out of control is here. "C-code"
by itself is no slower or faster than the equivalent "C++-code" (ie,
class-based code). If you wanted to, you could write "slow" or "fast"
code in either. In fact, writing the theoretical "fastest" program is
possible in C and C++ - your compiler and your algorithm are what
determine how "fast" your code will run.

As you correctly pointed out below, virtual function calls have some
overhead beyond static calls. A static call to a member should be just as
fast as a global 'C'-style call, as far as I know.


That is the idea. It is possible for a theoretical implementation to do
something different, I suppose, but for all practical purposes it is
safe to assume that the only functional difference between a global
function and a class static function is that that the class static
function has access to private and protected class static data and
functions.

So in the context of this discussion, there are no performance differences.
But being told to put all your code into classes is as illogical to me
as being told to use only words and phrases from Shakepeaean iambic
pentameter as variable names. Or, more practically but no less obtuse,
hungarian notation. Does it help anything? Not really. Does it hurt
anything? Not really. And if it does either it does them in equal
measure. So why insist on it?

One argument would be for the sake of uniformity. But I guess that's just
the soldier in me talking.


Being a former soldier myself, I should point out that while uniformity
is generally a good thing, there are many different types of soldiers,
some specializing in airborne drops, some specializing in beach
landings, not to mention the wildly varying trades like pilots,
artillery, armoured, mechanized infantry etc. etc. etc.

By all means, be uniform, but if the job calls for artillery, don't send
in the infantry.
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.

There are advantages to having the static Math class in Java. It provides
for an easy point of reference. It's kind of like having a directory
structure and using it to organize your data. Personally, the following is


?

You could replace "static Math class in Java" with "Math namespace in
C++" in your statement, and it would still be valid. The *only* reason
there is a static Math class in Java (as opposed to a Math namespace) is
that Java does not support free functions.

Given that C++ has the option, what are the advantages here?
Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.

Other than the fact that people tend to be sloppy with namespaces.


People can be just as sloppy with anything in C++, and it's usually the
same people. Is there any emperical evidence that people tend to
sloppiness when namespaces are introduced?

But let me give the benefit of the doubt and ask sloppy in what way?
What it is, is a design issue. What you're telling me is that there are
such things as "Math" objects.

No. It's saying there are mathematical operators which can be classified as
such.


Yes, but there are many ways of doing this in C++. You could use a
"Math" class, or you could use a "Math" namespace, or you could prefix
global functions with "Math_". Each of these methods groups certain
operations together, and each tell me different things about that
grouping. The class tells me that "Math"'s are things, ie, objects -
it's not called object-oriented programming for giggles - just like
class Student, class smart_ptr_policy or class ifstream. The namespace
tells me that these functions are conceptually grouped in some way, but
otherwise gives me no further indications of how - which is fine, all I
really need to understand is that they are all "Math" functions.

The last? I guess it just tells me that someone's a rotten programmer,
unless they have a better excuse.
In order to find the max of two numbers,
I have to go get a "Math" and use the "Math"'s "max" operation. Or, in
the static case, that "Math"'s have a behaviour or mechanism that is not
specific to any one "Math", but is nonetheless "Math" object-specific
behaviour.

You don't instantiate Math. It is a utilities class.


Of course I understand that, it was my argument after all. But a class
describes a (surprise, surprise) class of objects. The ONLY valid
reasons I can think of for having a non-instantiable (static) class is
when that body of operations MUST NOT be extended, and/or they all make
use of some kind of private data/algorithms that MUST NOT be visible to
the rest of the program. There are plenty of situations that satisfy
those constraints. I don't believe max() (or sin(), or round() etc.)
does. Explain to me why you do.
On the other hand, the free function tells me that "max" is an operation
in category (ie, namespace) "Math". In other words, "max" is a "Math"
operation.

And how does this differ from Java's use of a class where you use a
namespace?


? what do you mean "Java's use of a class where you use a namespace"?

[Taking a guess at what you meant]

As I mentioned before, Java has no choice but to do max() with static
class members. You have a choice in C++.

Let me make this absolutely clear. I believe there is no difference
between designs that use non-class-functions and those that do in terms
of functionality, efficiency and maintainability. If anyone disagrees,
let me know. As far as I'm concerned this discussion is over the
benefits of Class::function() vs. Namespace::function(), and nothing more.

So to answer what I think your question was: it doesn't. It's the same
damn thing. There are no functional benefits either way.

But to me at least, you are making a statement when you create a class
vs. a namespace. A class describes a "thing", an object. A namespace
describes a group. To me, mathematical operations can be grouped. But a
"Math" doesn't have a "cosh()" capability. This is the basis of my
argument for putting these functions in namespaces as opposed to classes.

On the other hand, if I were to create a MemoryManager that was static
(non-instantiable), that's a different story. A "MemoryManager" is a
thing, an object. By making it a static class, I am making clear that
there is only one MemoryManager available, and you are not responsible
for creating or destroying it. Likewise, you are not to add functions to
it (make your own damn MemoryManager). It is a single, global interface
to some hidden memory system that needs managing. The static functions
in that class provide some operation or functionality of this monolithic
MemoryManager thing. Things like allocate(), get_free_memory(). That is
the language of objects.

Do not try to bend the Math into an object. That is impossible. Instead,
try to remember the truth.

There is no Math.
Doesn't the latter just make more sense?

It depends how it's managed. Java takes the functional operator approach to
mathematical syntax, whereas C++ allows for infix notation. I find that
far more significant in terms of how it 'feels' to use. An interesting
parallel to this is found in Misner, Thorne and Wheeler's _Gravitation_
where three notational forms are used in parallel through out the text:

http://www.reviewcentre.com/review57645.html


wha?

[Attempting to decode]

If you prefer to use functional notation as opposed to operators, go
nuts. I think a + b is more understandable than operator+(a, b), but
hey, that's me.

But how is any of that relevant to keeping all the code in classes?
So in conclusion, what the hell are the benefits of such arbitrary
constraints? Write your program so that it makes logical sense and
models the problem it is trying to solve as closely as possible. If the
language has the tools, and if they don't lead to bad design and
maintennance problems, use them.

Actually, this was a hypothetical proposition. One reason for putting
everything in classes is that it usually makes refactoring easier (with the
possible exception of helper functions), and also makes reuse easier.


I understand that it was hypothetical, so was my proposed "morse coding
standard". I am learning here, too. If you can convince me that
class-only design is better in some way than using global functions, I
may change my evil ways. But so far, all I have seen are wishy-washy
pseudo-statements like "the 'fact' that people *tend* to be *sloppy*
with namespace" or "putting everything in classes is that it *usually*
makes refactoring *easier*" (emphasis added in all cases), or assertions
to the tune of "that's how Java does it, so it must be good".

So tell me what you mean by "easier" refactoring or reuse, and how a
collection of static class functions makes this possible over a namespace.

For the record, Java is designed to run in distributed and network
environments. Because of the constraints of this environment, everything
*has* to be a class. They didn't make class Math cause it was a good
idea. They did it cause they needed the functions and had no other way
to make them.

But is it a good idea? I don't know, but I don't think so. Explain to me
why I might be wrong.

mark

Jul 22 '05 #12

P: n/a

Steven T. Hatton wrote:
Mark A. Gibbs wrote:
Personally, I can see no practical functional limitations or benefits.

I believe there actually are two. I already mentioned them in another post
in this thread.


Two what? Limitations or benefits? Are you referring to your comments on
assymetrical binary operations? That is not a design issue, that's an
implementation issue. If you want an operation a @ b to be valid for
objects of type A and B in any order you either have to define
operator@(A) in B and operator@(B) in A (thus coupling the two), or
define operator@(B) in A and operator@(A,B) globally (still coupling the
two), or define operator@(A,B) and operator@(B,A) globally (leaving the
classes uncoupled). To me, this *supports* non-class functions.

But whatever you decide out of the above options, you are limited by the
language. you could write add(A,B) and add(B,A) as class members (of
either class) with no problems. If you are talking about limitations of
possible implementations due to constraints of the language, count me
out. I have no intention of discussing alterations to the language. I
was talking about limitations on possible designs and program structures.

Your second argument, if I understood it, makes no sense. "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." So does that support your argument or not?

If a function requires access to member data, then by all means make it
a member function. But static functions can't access member data, now
can they? If they require access to static data, well that's different.
But if you have a function that does not require instance-specific data,
and does not require a class-global data (such as max()), you can choose
to use either a static member function or a non-class function without
concern.
Where this whole thing starts to spiral out of control is here. "C-code"
by itself is no slower or faster than the equivalent "C++-code" (ie,
class-based code). If you wanted to, you could write "slow" or "fast"
code in either. In fact, writing the theoretical "fastest" program is
possible in C and C++ - your compiler and your algorithm are what
determine how "fast" your code will run.

As you correctly pointed out below, virtual function calls have some
overhead beyond static calls. A static call to a member should be just as
fast as a global 'C'-style call, as far as I know.


That is the idea. It is possible for a theoretical implementation to do
something different, I suppose, but for all practical purposes it is
safe to assume that the only functional difference between a global
function and a class static function is that that the class static
function has access to private and protected class static data and
functions.

So in the context of this discussion, there are no performance differences.
But being told to put all your code into classes is as illogical to me
as being told to use only words and phrases from Shakepeaean iambic
pentameter as variable names. Or, more practically but no less obtuse,
hungarian notation. Does it help anything? Not really. Does it hurt
anything? Not really. And if it does either it does them in equal
measure. So why insist on it?

One argument would be for the sake of uniformity. But I guess that's just
the soldier in me talking.


Being a former soldier myself, I should point out that while uniformity
is generally a good thing, there are many different types of soldiers,
some specializing in airborne drops, some specializing in beach
landings, not to mention the wildly varying trades like pilots,
artillery, armoured, mechanized infantry etc. etc. etc.

By all means, be uniform, but if the job calls for artillery, don't send
in the infantry.
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.

There are advantages to having the static Math class in Java. It provides
for an easy point of reference. It's kind of like having a directory
structure and using it to organize your data. Personally, the following is


?

You could replace "static Math class in Java" with "Math namespace in
C++" in your statement, and it would still be valid. The *only* reason
there is a static Math class in Java (as opposed to a Math namespace) is
that Java does not support free functions.

Given that C++ has the option, what are the advantages here?
Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.

Other than the fact that people tend to be sloppy with namespaces.


People can be just as sloppy with anything in C++, and it's usually the
same people. Is there any emperical evidence that people tend to
sloppiness when namespaces are introduced?

But let me give the benefit of the doubt and ask sloppy in what way?
What it is, is a design issue. What you're telling me is that there are
such things as "Math" objects.

No. It's saying there are mathematical operators which can be classified as
such.


Yes, but there are many ways of doing this in C++. You could use a
"Math" class, or you could use a "Math" namespace, or you could prefix
global functions with "Math_". Each of these methods groups certain
operations together, and each tell me different things about that
grouping. The class tells me that "Math"'s are things, ie, objects -
it's not called object-oriented programming for giggles - just like
class Student, class smart_ptr_policy or class ifstream. The namespace
tells me that these functions are conceptually grouped in some way, but
otherwise gives me no further indications of how - which is fine, all I
really need to understand is that they are all "Math" functions.

The last? I guess it just tells me that someone's a rotten programmer,
unless they have a better excuse.
In order to find the max of two numbers,
I have to go get a "Math" and use the "Math"'s "max" operation. Or, in
the static case, that "Math"'s have a behaviour or mechanism that is not
specific to any one "Math", but is nonetheless "Math" object-specific
behaviour.

You don't instantiate Math. It is a utilities class.


Of course I understand that, it was my argument after all. But a class
describes a (surprise, surprise) class of objects. The ONLY valid
reasons I can think of for having a non-instantiable (static) class is
when that body of operations MUST NOT be extended, and/or they all make
use of some kind of private data/algorithms that MUST NOT be visible to
the rest of the program. There are plenty of situations that satisfy
those constraints. I don't believe max() (or sin(), or round() etc.)
does. Explain to me why you do.
On the other hand, the free function tells me that "max" is an operation
in category (ie, namespace) "Math". In other words, "max" is a "Math"
operation.

And how does this differ from Java's use of a class where you use a
namespace?


? what do you mean "Java's use of a class where you use a namespace"?

[Taking a guess at what you meant]

As I mentioned before, Java has no choice but to do max() with static
class members. You have a choice in C++.

Let me make this absolutely clear. I believe there is no difference
between designs that use non-class-functions and those that do in terms
of functionality, efficiency and maintainability. If anyone disagrees,
let me know. As far as I'm concerned this discussion is over the
benefits of Class::function() vs. Namespace::function(), and nothing more.

So to answer what I think your question was: it doesn't. It's the same
damn thing. There are no functional benefits either way.

But to me at least, you are making a statement when you create a class
vs. a namespace. A class describes a "thing", an object. A namespace
describes a group. To me, mathematical operations can be grouped. But a
"Math" doesn't have a "cosh()" capability. This is the basis of my
argument for putting these functions in namespaces as opposed to classes.

On the other hand, if I were to create a MemoryManager that was static
(non-instantiable), that's a different story. A "MemoryManager" is a
thing, an object. By making it a static class, I am making clear that
there is only one MemoryManager available, and you are not responsible
for creating or destroying it. Likewise, you are not to add functions to
it (make your own damn MemoryManager). It is a single, global interface
to some hidden memory system that needs managing. The static functions
in that class provide some operation or functionality of this monolithic
MemoryManager thing. Things like allocate(), get_free_memory(). That is
the language of objects.

Do not try to bend the Math into an object. That is impossible. Instead,
try to remember the truth.

There is no Math.
Doesn't the latter just make more sense?

It depends how it's managed. Java takes the functional operator approach to
mathematical syntax, whereas C++ allows for infix notation. I find that
far more significant in terms of how it 'feels' to use. An interesting
parallel to this is found in Misner, Thorne and Wheeler's _Gravitation_
where three notational forms are used in parallel through out the text:

http://www.reviewcentre.com/review57645.html


wha?

[Attempting to decode]

If you prefer to use functional notation as opposed to operators, go
nuts. I think a + b is more understandable than operator+(a, b), but
hey, that's me.

But how is any of that relevant to keeping all the code in classes?
So in conclusion, what the hell are the benefits of such arbitrary
constraints? Write your program so that it makes logical sense and
models the problem it is trying to solve as closely as possible. If the
language has the tools, and if they don't lead to bad design and
maintennance problems, use them.

Actually, this was a hypothetical proposition. One reason for putting
everything in classes is that it usually makes refactoring easier (with the
possible exception of helper functions), and also makes reuse easier.


I understand that it was hypothetical, so was my proposed "morse coding
standard". I am learning here, too. If you can convince me that
class-only design is better in some way than using global functions, I
may change my evil ways. But so far, all I have seen are wishy-washy
pseudo-statements like "the 'fact' that people *tend* to be *sloppy*
with namespace" or "putting everything in classes is that it *usually*
makes refactoring *easier*" (emphasis added in all cases), or assertions
to the tune of "that's how Java does it, so it must be good".

So tell me what you mean by "easier" refactoring or reuse, and how a
collection of static class functions makes this possible over a namespace.

For the record, Java is designed to run in distributed and network
environments. Because of the constraints of this environment, everything
*has* to be a class. They didn't make class Math cause it was a good
idea. They did it cause they needed the functions and had no other way
to make them.

But is it a good idea? I don't know, but I don't think so. Explain to me
why I might be wrong.

mark

Jul 22 '05 #13

P: n/a
Steven T. Hatton wrote:
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.


What purpose would that serve?
Jul 22 '05 #14

P: n/a
Steven T. Hatton wrote:
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.


What purpose would that serve?
Jul 22 '05 #15

P: n/a
Mark A. Gibbs wrote:
If you want an operation a @ b to be valid for
objects of type A and B in any order you either have to define
operator@(A) in B and operator@(B) in A (thus coupling the two), or
define operator@(B) in A and operator@(A,B) globally (still coupling the
two), or define operator@(A,B) and operator@(B,A) globally (leaving the
classes uncoupled). To me, this *supports* non-class functions.
My point exactly. Though I'm not sure there isn't a third approach which
might actually address the situation better than either of the two shown
above.
Your second argument, if I understood it, makes no sense. "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." So does that support your argument or not?
Yes it supports the point I was making.
If a function requires access to member data, then by all means make it
a member function. But static functions can't access member data, now
can they?
Of course they can.

As you correctly pointed out below, virtual function calls have some
overhead beyond static calls. A static call to a member should be just
as fast as a global 'C'-style call, as far as I know.


That is the idea. It is possible for a theoretical implementation to do
something different, I suppose, but for all practical purposes it is
safe to assume that the only functional difference between a global
function and a class static function is that that the class static
function has access to private and protected class static data and
functions.


A static function has access to all member data. Am I missing something
here? I only have a couple months of real C++ experience, so I may have
misunderstood something, but I'm almost certain a static member function
can access all member data of instances of the class.
Being a former soldier myself, I should point out that while uniformity
is generally a good thing, there are many different types of soldiers,
some specializing in airborne drops, some specializing in beach
landings, not to mention the wildly varying trades like pilots,
artillery, armoured, mechanized infantry etc. etc. etc.
But there are certain attributes every solder shares with all others.
Ironically, the model I used for notions of inheritance when first learning
about the concepts of OO was the military organizational structure. There
were no OO programming languages available to the average user at the time.
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.

There are advantages to having the static Math class in Java. It provides
for an easy point of reference. It's kind of like having a directory
structure and using it to organize your data. Personally, the following
is


?


If you have a reasonably good IDE its very easy to type:
java.[get a listing of available packages and classes]

select

java.Math.[get a listing of available members with their type displayed]

select what you want.

If you don't like the fully qualified name in the body of your source, just
type /Math.operation(arguments)/, highlight it (it will be displayed with
an indication that the IDE doesn't know about /Math/) hit a specific key
combination to invoke the display of all candidates available in your
classpath. Select java.lang.Math from the list, and it is #imported in the
heading of the source file.

If you don't have an IDE just use bash to hook into the same support
features the IDE uses to search the classpath, and to display member
signatures, etc. It's a bit more work, but with a few scripts, it really
is quite easy.
You could replace "static Math class in Java" with "Math namespace in
C++" in your statement, and it would still be valid. The *only* reason
there is a static Math class in Java (as opposed to a Math namespace) is
that Java does not support free functions.
One might argue that the real difference is that in Java you have another
level of encapsulation. I find 'free' functions to be of questionable
value. Some people seem to think of them as global functions.
Given that C++ has the option, what are the advantages here?
Perhaps. There is the advantage of predictability. That is, since there
are fewer options, it's easier to determine how something is structured.
It also enforces certain structural rules that programmers might otherwise
violate.
Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.

Other than the fact that people tend to be sloppy with namespaces.


People can be just as sloppy with anything in C++, and it's usually the
same people. Is there any emperical evidence that people tend to
sloppiness when namespaces are introduced?


The STL.
But let me give the benefit of the doubt and ask sloppy in what way?
What it is, is a design issue. What you're telling me is that there are
such things as "Math" objects.

No. It's saying there are mathematical operators which can be classified
as such.


Yes, but there are many ways of doing this in C++. You could use a
"Math" class, or you could use a "Math" namespace, or you could prefix
global functions with "Math_".


And (some) C++ programmers believe the last is a viable option.
Each of these methods groups certain
operations together, and each tell me different things about that
grouping. The class tells me that "Math"'s are things, ie, objects -
it's not called object-oriented programming for giggles - just like
class Student, class smart_ptr_policy or class ifstream. The namespace
tells me that these functions are conceptually grouped in some way, but
otherwise gives me no further indications of how - which is fine, all I
really need to understand is that they are all "Math" functions.
But when you have disorganized your collection of operators as described
above, it is more difficult to work with. As far as OO goes, if you really
understand what Java is doing, you would understand that it is very much OO
to do things that way. But even if you only look at the surface, there is
nothing non-OO about using utilities classes. It's just another way of
using tools effectively.
Of course I understand that, it was my argument after all. But a class
describes a (surprise, surprise) class of objects.
So if there is only one instance of a class, does that mean OO has been
missused? I find that argument against the use of the Math class to be
silly. Ever wonder why the German cognate for the English /dish/ means
table? There is a lesson there.
The ONLY valid
reasons I can think of for having a non-instantiable (static) class is
when that body of operations MUST NOT be extended, and/or they all make
use of some kind of private data/algorithms that MUST NOT be visible to
the rest of the program.
I tend to believe the onus falls in the other direction as far as the
visibility of data. But that's just what the standard texts on OO say.
As I mentioned before, Java has no choice but to do max() with static
class members. You have a choice in C++.
One might argue that you have the illusion of choice in C++. How many
main() functions can exist in a C++ program? How do you specify the
namespace for that function? That sounds like a restraction, not a liberty
to me.
Let me make this absolutely clear. I believe there is no difference
between designs that use non-class-functions and those that do in terms
of functionality, efficiency and maintainability. If anyone disagrees,
let me know. As far as I'm concerned this discussion is over the
benefits of Class::function() vs. Namespace::function(), and nothing more.
That was what I was intending in the immediate discussion. My inclination is
to view namespaces as fairly unstructured in comparison to classes.
So to answer what I think your question was: it doesn't. It's the same
damn thing. There are no functional benefits either way.

But to me at least, you are making a statement when you create a class
vs. a namespace. A class describes a "thing", an object. A namespace
describes a group. To me, mathematical operations can be grouped. But a
"Math" doesn't have a "cosh()" capability.
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.
Do not try to bend the Math into an object. That is impossible. Instead,
try to remember the truth.
I don't find that to be a compelling argument. The name Math is just a
shorthand for mathematical utilities. It works reasonably well. I was
horrified when I first saw Java's vecmath (well actually it took a few days
for the horror to sink in). There are some things that are simply awkward
in it. Operator overloading would, perhaps, be a welcome enhancement, but
when I simply accepted it for what it was, a lot of the superficial
objections came to appear irrelevant.
There is no Math.
I sure have a lot of math books about nothing then.
Doesn't the latter just make more sense?

It depends how it's managed. Java takes the functional operator approach
to
mathematical syntax, whereas C++ allows for infix notation. I find that
far more significant in terms of how it 'feels' to use. An interesting
parallel to this is found in Misner, Thorne and Wheeler's _Gravitation_
where three notational forms are used in parallel through out the text:

http://www.reviewcentre.com/review57645.html


wha?

[Attempting to decode]

If you prefer to use functional notation as opposed to operators, go
nuts. I think a + b is more understandable than operator+(a, b), but
hey, that's me.


Yup, you understood the intent. There are some advantages to the functional
operator approach to mathematical symbolism.
I understand that it was hypothetical, so was my proposed "morse coding
standard".
Can you provide an example of a successfull general purpose programming
language that used such an approach?
I am learning here, too. If you can convince me that
class-only design is better in some way than using global functions,
I could rest my case right here.
So tell me what you mean by "easier" refactoring or reuse, and how a
collection of static class functions makes this possible over a namespace.
If you read my comment about namespaces you may notice I already addressed
that. But, namespaces do have on additional drawback in that they are can
easily be concatanated, sometimes in less than obvious ways.
For the record, Java is designed to run in distributed and network
environments. Because of the constraints of this environment, everything
*has* to be a class. They didn't make class Math cause it was a good
idea. They did it cause they needed the functions and had no other way
to make them.


I'm not sure of all the cause and effect, but, yes, Java pretty much forces
the creation of Math. There, of course, are a few alternatives, such as
making a class for each operator, or for some subset of operators. I'll
grant that Java lacks a lot of the available finesse in C++. But that
feature of C++ comes at a cost.

--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #16

P: n/a
Mark A. Gibbs wrote:
If you want an operation a @ b to be valid for
objects of type A and B in any order you either have to define
operator@(A) in B and operator@(B) in A (thus coupling the two), or
define operator@(B) in A and operator@(A,B) globally (still coupling the
two), or define operator@(A,B) and operator@(B,A) globally (leaving the
classes uncoupled). To me, this *supports* non-class functions.
My point exactly. Though I'm not sure there isn't a third approach which
might actually address the situation better than either of the two shown
above.
Your second argument, if I understood it, makes no sense. "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." So does that support your argument or not?
Yes it supports the point I was making.
If a function requires access to member data, then by all means make it
a member function. But static functions can't access member data, now
can they?
Of course they can.

As you correctly pointed out below, virtual function calls have some
overhead beyond static calls. A static call to a member should be just
as fast as a global 'C'-style call, as far as I know.


That is the idea. It is possible for a theoretical implementation to do
something different, I suppose, but for all practical purposes it is
safe to assume that the only functional difference between a global
function and a class static function is that that the class static
function has access to private and protected class static data and
functions.


A static function has access to all member data. Am I missing something
here? I only have a couple months of real C++ experience, so I may have
misunderstood something, but I'm almost certain a static member function
can access all member data of instances of the class.
Being a former soldier myself, I should point out that while uniformity
is generally a good thing, there are many different types of soldiers,
some specializing in airborne drops, some specializing in beach
landings, not to mention the wildly varying trades like pilots,
artillery, armoured, mechanized infantry etc. etc. etc.
But there are certain attributes every solder shares with all others.
Ironically, the model I used for notions of inheritance when first learning
about the concepts of OO was the military organizational structure. There
were no OO programming languages available to the average user at the time.
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.

There are advantages to having the static Math class in Java. It provides
for an easy point of reference. It's kind of like having a directory
structure and using it to organize your data. Personally, the following
is


?


If you have a reasonably good IDE its very easy to type:
java.[get a listing of available packages and classes]

select

java.Math.[get a listing of available members with their type displayed]

select what you want.

If you don't like the fully qualified name in the body of your source, just
type /Math.operation(arguments)/, highlight it (it will be displayed with
an indication that the IDE doesn't know about /Math/) hit a specific key
combination to invoke the display of all candidates available in your
classpath. Select java.lang.Math from the list, and it is #imported in the
heading of the source file.

If you don't have an IDE just use bash to hook into the same support
features the IDE uses to search the classpath, and to display member
signatures, etc. It's a bit more work, but with a few scripts, it really
is quite easy.
You could replace "static Math class in Java" with "Math namespace in
C++" in your statement, and it would still be valid. The *only* reason
there is a static Math class in Java (as opposed to a Math namespace) is
that Java does not support free functions.
One might argue that the real difference is that in Java you have another
level of encapsulation. I find 'free' functions to be of questionable
value. Some people seem to think of them as global functions.
Given that C++ has the option, what are the advantages here?
Perhaps. There is the advantage of predictability. That is, since there
are fewer options, it's easier to determine how something is structured.
It also enforces certain structural rules that programmers might otherwise
violate.
Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.

Other than the fact that people tend to be sloppy with namespaces.


People can be just as sloppy with anything in C++, and it's usually the
same people. Is there any emperical evidence that people tend to
sloppiness when namespaces are introduced?


The STL.
But let me give the benefit of the doubt and ask sloppy in what way?
What it is, is a design issue. What you're telling me is that there are
such things as "Math" objects.

No. It's saying there are mathematical operators which can be classified
as such.


Yes, but there are many ways of doing this in C++. You could use a
"Math" class, or you could use a "Math" namespace, or you could prefix
global functions with "Math_".


And (some) C++ programmers believe the last is a viable option.
Each of these methods groups certain
operations together, and each tell me different things about that
grouping. The class tells me that "Math"'s are things, ie, objects -
it's not called object-oriented programming for giggles - just like
class Student, class smart_ptr_policy or class ifstream. The namespace
tells me that these functions are conceptually grouped in some way, but
otherwise gives me no further indications of how - which is fine, all I
really need to understand is that they are all "Math" functions.
But when you have disorganized your collection of operators as described
above, it is more difficult to work with. As far as OO goes, if you really
understand what Java is doing, you would understand that it is very much OO
to do things that way. But even if you only look at the surface, there is
nothing non-OO about using utilities classes. It's just another way of
using tools effectively.
Of course I understand that, it was my argument after all. But a class
describes a (surprise, surprise) class of objects.
So if there is only one instance of a class, does that mean OO has been
missused? I find that argument against the use of the Math class to be
silly. Ever wonder why the German cognate for the English /dish/ means
table? There is a lesson there.
The ONLY valid
reasons I can think of for having a non-instantiable (static) class is
when that body of operations MUST NOT be extended, and/or they all make
use of some kind of private data/algorithms that MUST NOT be visible to
the rest of the program.
I tend to believe the onus falls in the other direction as far as the
visibility of data. But that's just what the standard texts on OO say.
As I mentioned before, Java has no choice but to do max() with static
class members. You have a choice in C++.
One might argue that you have the illusion of choice in C++. How many
main() functions can exist in a C++ program? How do you specify the
namespace for that function? That sounds like a restraction, not a liberty
to me.
Let me make this absolutely clear. I believe there is no difference
between designs that use non-class-functions and those that do in terms
of functionality, efficiency and maintainability. If anyone disagrees,
let me know. As far as I'm concerned this discussion is over the
benefits of Class::function() vs. Namespace::function(), and nothing more.
That was what I was intending in the immediate discussion. My inclination is
to view namespaces as fairly unstructured in comparison to classes.
So to answer what I think your question was: it doesn't. It's the same
damn thing. There are no functional benefits either way.

But to me at least, you are making a statement when you create a class
vs. a namespace. A class describes a "thing", an object. A namespace
describes a group. To me, mathematical operations can be grouped. But a
"Math" doesn't have a "cosh()" capability.
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.
Do not try to bend the Math into an object. That is impossible. Instead,
try to remember the truth.
I don't find that to be a compelling argument. The name Math is just a
shorthand for mathematical utilities. It works reasonably well. I was
horrified when I first saw Java's vecmath (well actually it took a few days
for the horror to sink in). There are some things that are simply awkward
in it. Operator overloading would, perhaps, be a welcome enhancement, but
when I simply accepted it for what it was, a lot of the superficial
objections came to appear irrelevant.
There is no Math.
I sure have a lot of math books about nothing then.
Doesn't the latter just make more sense?

It depends how it's managed. Java takes the functional operator approach
to
mathematical syntax, whereas C++ allows for infix notation. I find that
far more significant in terms of how it 'feels' to use. An interesting
parallel to this is found in Misner, Thorne and Wheeler's _Gravitation_
where three notational forms are used in parallel through out the text:

http://www.reviewcentre.com/review57645.html


wha?

[Attempting to decode]

If you prefer to use functional notation as opposed to operators, go
nuts. I think a + b is more understandable than operator+(a, b), but
hey, that's me.


Yup, you understood the intent. There are some advantages to the functional
operator approach to mathematical symbolism.
I understand that it was hypothetical, so was my proposed "morse coding
standard".
Can you provide an example of a successfull general purpose programming
language that used such an approach?
I am learning here, too. If you can convince me that
class-only design is better in some way than using global functions,
I could rest my case right here.
So tell me what you mean by "easier" refactoring or reuse, and how a
collection of static class functions makes this possible over a namespace.
If you read my comment about namespaces you may notice I already addressed
that. But, namespaces do have on additional drawback in that they are can
easily be concatanated, sometimes in less than obvious ways.
For the record, Java is designed to run in distributed and network
environments. Because of the constraints of this environment, everything
*has* to be a class. They didn't make class Math cause it was a good
idea. They did it cause they needed the functions and had no other way
to make them.


I'm not sure of all the cause and effect, but, yes, Java pretty much forces
the creation of Math. There, of course, are a few alternatives, such as
making a class for each operator, or for some subset of operators. I'll
grant that Java lacks a lot of the available finesse in C++. But that
feature of C++ comes at a cost.

--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #17

P: n/a
Jeff Schwab wrote:
Steven T. Hatton wrote:
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.


What purpose would that serve?


Binding a helper function to a class, and still exclude it from protected
and private access to data members.
--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #18

P: n/a
Jeff Schwab wrote:
Steven T. Hatton wrote:
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.


What purpose would that serve?


Binding a helper function to a class, and still exclude it from protected
and private access to data members.
--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #19

P: n/a
On Sat, 10 Apr 2004 17:47:46 GMT in comp.lang.c++, "Mark A. Gibbs"
<x_*********@rogers.com_x> wrote,
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.


Yes, obviously should be

int larger = std::max(1, 2);
Jul 22 '05 #20

P: n/a
On Sat, 10 Apr 2004 17:47:46 GMT in comp.lang.c++, "Mark A. Gibbs"
<x_*********@rogers.com_x> wrote,
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.


Yes, obviously should be

int larger = std::max(1, 2);
Jul 22 '05 #21

P: n/a
* "Steven T. Hatton" <su******@setidava.kushan.aa> schriebt:

If you were forced at gunpoint to put all your code in classes, rather than
in namespace scope (obviously classes themselves are an exception to this),
and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program?
Yes, AFAIK you cannot put 'extern "C"' in a class, which severely limits
what you can then accomplish with only standard C++.

Apart from that there are issues of design (information hiding) and of
practical stuff like binary operators. Although that doesn't limit what
your executable code can accomplish it limits the usability of that code
in client code, and it impacts negatively on maintainance & performance.

Are there any benefits to doing things that way (other than survival)?


In a real world project much of the grunt work is typically done by less
experienced programmers, who tend to use static storage and namespace scope
functions unless forbidden. As an example, in one mainly Java project many
classes were designed as singletons using static storage for the instances.
That created problems in performance testing where a large number of logins
to the system had to be simulated using threads instead of processes.

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #22

P: n/a
* "Steven T. Hatton" <su******@setidava.kushan.aa> schriebt:

If you were forced at gunpoint to put all your code in classes, rather than
in namespace scope (obviously classes themselves are an exception to this),
and 'bootstrap' your program by instantiating a single application object
in main(), would that place any limitations on what you could accomplish
with your program?
Yes, AFAIK you cannot put 'extern "C"' in a class, which severely limits
what you can then accomplish with only standard C++.

Apart from that there are issues of design (information hiding) and of
practical stuff like binary operators. Although that doesn't limit what
your executable code can accomplish it limits the usability of that code
in client code, and it impacts negatively on maintainance & performance.

Are there any benefits to doing things that way (other than survival)?


In a real world project much of the grunt work is typically done by less
experienced programmers, who tend to use static storage and namespace scope
functions unless forbidden. As an example, in one mainly Java project many
classes were designed as singletons using static storage for the instances.
That created problems in performance testing where a large number of logins
to the system had to be simulated using threads instead of processes.

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #23

P: n/a
David Harmon wrote:
On Sat, 10 Apr 2004 17:47:46 GMT in comp.lang.c++, "Mark A. Gibbs"
<x_*********@rogers.com_x> wrote,
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.


Yes, obviously should be

int larger = std::max(1, 2);


Hey! Whose side are you on here?
--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #24

P: n/a
David Harmon wrote:
On Sat, 10 Apr 2004 17:47:46 GMT in comp.lang.c++, "Mark A. Gibbs"
<x_*********@rogers.com_x> wrote,
int larger = Math::max(1, 2);

Only Java programmers could find the latter more legible.


Yes, obviously should be

int larger = std::max(1, 2);


Hey! Whose side are you on here?
--
p->m == (*p).m == p[0].m
http://www.kdevelop.org
http://www.suse.com
http://www.mozilla.org
Jul 22 '05 #25

P: n/a
Steven T. Hatton wrote:
Jeff Schwab wrote:

Steven T. Hatton wrote:

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.


What purpose would that serve?

Binding a helper function to a class, and still exclude it from protected
and private access to data members.


A function doesn't need to be a member of a class to be associated with
it. Just declare the function in the same namespace as the class, but
outside the definition.

class C { /* ... */ };

void helper_function( C const& );
Jul 22 '05 #26

P: n/a
Steven T. Hatton wrote:
Jeff Schwab wrote:

Steven T. Hatton wrote:

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.


What purpose would that serve?

Binding a helper function to a class, and still exclude it from protected
and private access to data members.


A function doesn't need to be a member of a class to be associated with
it. Just declare the function in the same namespace as the class, but
outside the definition.

class C { /* ... */ };

void helper_function( C const& );
Jul 22 '05 #27

P: n/a
Jeff Schwab wrote:
Steven T. Hatton wrote:
Jeff Schwab wrote:

Steven T. Hatton wrote:
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.

What purpose would that serve?

Binding a helper function to a class, and still exclude it from protected
and private access to data members.


A function doesn't need to be a member of a class to be associated with
it. Just declare the function in the same namespace as the class, but
outside the definition.

class C { /* ... */ };

void helper_function( C const& );


Well, sure. But then we have people running around thinking of namespace
scope as 'global' and doing unconscionable things such as using::std at
global scope.

Your example is exactly the functionality I was trying to preserve while
more tightly associating the helper function with the specific class. The
idea of having a bunch of classes at namespace scope and a bunch of helper
functions which apply to one or some, but not all the classes seems
unstructured to me.

Certainly if care is taken in naming and choosing members of the namespace,
it is workable. But, from what I've seen, programmers often start grouping
things with category_subcategory_type names. These should more correctly be
category::subcategory::type.

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #28

P: n/a
Jeff Schwab wrote:
Steven T. Hatton wrote:
Jeff Schwab wrote:

Steven T. Hatton wrote:
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.

What purpose would that serve?

Binding a helper function to a class, and still exclude it from protected
and private access to data members.


A function doesn't need to be a member of a class to be associated with
it. Just declare the function in the same namespace as the class, but
outside the definition.

class C { /* ... */ };

void helper_function( C const& );


Well, sure. But then we have people running around thinking of namespace
scope as 'global' and doing unconscionable things such as using::std at
global scope.

Your example is exactly the functionality I was trying to preserve while
more tightly associating the helper function with the specific class. The
idea of having a bunch of classes at namespace scope and a bunch of helper
functions which apply to one or some, but not all the classes seems
unstructured to me.

Certainly if care is taken in naming and choosing members of the namespace,
it is workable. But, from what I've seen, programmers often start grouping
things with category_subcategory_type names. These should more correctly be
category::subcategory::type.

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #29

P: n/a
Steven T. Hatton wrote:
Jeff Schwab wrote:

Steven T. Hatton wrote:
Jeff Schwab wrote:

Steven T. Hatton wrote:

>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.

What purpose would that serve?
Binding a helper function to a class, and still exclude it from protected
and private access to data members.
A function doesn't need to be a member of a class to be associated with
it. Just declare the function in the same namespace as the class, but
outside the definition.

class C { /* ... */ };

void helper_function( C const& );

Well, sure. But then we have people running around thinking of namespace
scope as 'global' and doing unconscionable things such as using::std at
global scope.


I don't follow your logic. Using namespaces to group related functions
and classes doesn't cause people to misunderstand namespaces. In fact,
this is exactly the canonical usage.

You can't prohibit people from abusing "using" directives. Your
approach prohibits clients placing them even within a single function;
isn't that throwing the baby out with the bath water? Anyway, trying to
prevent your clients from using common coding styles you don't like
seems a little pedantic. It's important to support clients by providing
structure, but it's equally important to respect them, and to allow
flexibility.
Your example is exactly the functionality I was trying to preserve while
more tightly associating the helper function with the specific class. The
idea of having a bunch of classes at namespace scope and a bunch of helper
functions which apply to one or some, but not all the classes seems
unstructured to me.
But changing the word "namespace" to "class" would fix the perceived
problem?
Certainly if care is taken in naming and choosing members of the namespace,
it is workable. But, from what I've seen, programmers often start grouping
things with category_subcategory_type names. These should more correctly be
category::subcategory::type.


How would grouping items in classes instead of namespaces change this?
Jul 22 '05 #30

P: n/a
Steven T. Hatton wrote:
Jeff Schwab wrote:

Steven T. Hatton wrote:
Jeff Schwab wrote:

Steven T. Hatton wrote:

>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.

What purpose would that serve?
Binding a helper function to a class, and still exclude it from protected
and private access to data members.
A function doesn't need to be a member of a class to be associated with
it. Just declare the function in the same namespace as the class, but
outside the definition.

class C { /* ... */ };

void helper_function( C const& );

Well, sure. But then we have people running around thinking of namespace
scope as 'global' and doing unconscionable things such as using::std at
global scope.


I don't follow your logic. Using namespaces to group related functions
and classes doesn't cause people to misunderstand namespaces. In fact,
this is exactly the canonical usage.

You can't prohibit people from abusing "using" directives. Your
approach prohibits clients placing them even within a single function;
isn't that throwing the baby out with the bath water? Anyway, trying to
prevent your clients from using common coding styles you don't like
seems a little pedantic. It's important to support clients by providing
structure, but it's equally important to respect them, and to allow
flexibility.
Your example is exactly the functionality I was trying to preserve while
more tightly associating the helper function with the specific class. The
idea of having a bunch of classes at namespace scope and a bunch of helper
functions which apply to one or some, but not all the classes seems
unstructured to me.
But changing the word "namespace" to "class" would fix the perceived
problem?
Certainly if care is taken in naming and choosing members of the namespace,
it is workable. But, from what I've seen, programmers often start grouping
things with category_subcategory_type names. These should more correctly be
category::subcategory::type.


How would grouping items in classes instead of namespaces change this?
Jul 22 '05 #31

P: n/a
Jeff Schwab wrote:
Steven T. Hatton wrote:
Well, sure. But then we have people running around thinking of namespace
scope as 'global' and doing unconscionable things such as using::std at
global scope.


I don't follow your logic. Using namespaces to group related functions
and classes doesn't cause people to misunderstand namespaces. In fact,
this is exactly the canonical usage.


First off I meant to write /using namespace std;/ My brain does weird stuff
like that.

It's ok if used frugally. I still find it to be a bit too permissive and
unstructured.
You can't prohibit people from abusing "using" directives. Your
approach prohibits clients placing them even within a single function;
No. I didn't suggest doing away with them completely. I don't like the way
they concatonate and did make a few whimsical suggestions in that
direction,
isn't that throwing the baby out with the bath water? Anyway, trying to
prevent your clients from using common coding styles you don't like
seems a little pedantic. It's important to support clients by providing
structure, but it's equally important to respect them, and to allow
flexibility.


I wasn't really thinking in those terms. I was just trying to determine
what the technical implications, pro and con, of the all objects approach
are. I'm not even thouroughly convinced there would be that much
difference if namespaces were completely removed from the language, and in
their place people used classes. I'm not suggesting that be done, but I am
suggesting that it is a worthwhile thought experiment.
Your example is exactly the functionality I was trying to preserve while
more tightly associating the helper function with the specific class. The
idea of having a bunch of classes at namespace scope and a bunch of
helper functions which apply to one or some, but not all the classes
seems unstructured to me.


But changing the word "namespace" to "class" would fix the perceived
problem?


What I'm saying is that, for example, ::std is a collection of templates
(which I intended as well when I wrote 'class' and 'function') with only
the fact that they are part of the Standard Library as a common
characteristic. Yes, one purpose for namespaces is simply a mechanism for
avoiding name collisions. But limiting their use to that goal puts us back
in the same fix of having a bunch of unrelated entities all laying around
on a common floor.

Changing the name would not necessarily fix the problem. Disallowing
functions at namespace scope, however, would be an interesting exercise.
Certainly if care is taken in naming and choosing members of the
namespace,
it is workable. But, from what I've seen, programmers often start
grouping things with category_subcategory_type names. These should more
correctly be category::subcategory::type.


How would grouping items in classes instead of namespaces change this?


It was really a suggestion of how to address my concerns /without/ putting
everything in namespaces. I do believe having a rule of thumb that
everything that could be in a class should be in a class would lead to
tighter designs with cleaner demarkation.

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #32

P: n/a
Jeff Schwab wrote:
Steven T. Hatton wrote:
Well, sure. But then we have people running around thinking of namespace
scope as 'global' and doing unconscionable things such as using::std at
global scope.


I don't follow your logic. Using namespaces to group related functions
and classes doesn't cause people to misunderstand namespaces. In fact,
this is exactly the canonical usage.


First off I meant to write /using namespace std;/ My brain does weird stuff
like that.

It's ok if used frugally. I still find it to be a bit too permissive and
unstructured.
You can't prohibit people from abusing "using" directives. Your
approach prohibits clients placing them even within a single function;
No. I didn't suggest doing away with them completely. I don't like the way
they concatonate and did make a few whimsical suggestions in that
direction,
isn't that throwing the baby out with the bath water? Anyway, trying to
prevent your clients from using common coding styles you don't like
seems a little pedantic. It's important to support clients by providing
structure, but it's equally important to respect them, and to allow
flexibility.


I wasn't really thinking in those terms. I was just trying to determine
what the technical implications, pro and con, of the all objects approach
are. I'm not even thouroughly convinced there would be that much
difference if namespaces were completely removed from the language, and in
their place people used classes. I'm not suggesting that be done, but I am
suggesting that it is a worthwhile thought experiment.
Your example is exactly the functionality I was trying to preserve while
more tightly associating the helper function with the specific class. The
idea of having a bunch of classes at namespace scope and a bunch of
helper functions which apply to one or some, but not all the classes
seems unstructured to me.


But changing the word "namespace" to "class" would fix the perceived
problem?


What I'm saying is that, for example, ::std is a collection of templates
(which I intended as well when I wrote 'class' and 'function') with only
the fact that they are part of the Standard Library as a common
characteristic. Yes, one purpose for namespaces is simply a mechanism for
avoiding name collisions. But limiting their use to that goal puts us back
in the same fix of having a bunch of unrelated entities all laying around
on a common floor.

Changing the name would not necessarily fix the problem. Disallowing
functions at namespace scope, however, would be an interesting exercise.
Certainly if care is taken in naming and choosing members of the
namespace,
it is workable. But, from what I've seen, programmers often start
grouping things with category_subcategory_type names. These should more
correctly be category::subcategory::type.


How would grouping items in classes instead of namespaces change this?


It was really a suggestion of how to address my concerns /without/ putting
everything in namespaces. I do believe having a rule of thumb that
everything that could be in a class should be in a class would lead to
tighter designs with cleaner demarkation.

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #33

P: n/a
Steven T. Hatton wrote:
It was really a suggestion of how to address my concerns /without/ putting
everything in namespaces.

replace namespaces with class. I'm having one of those days! :-/

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #34

P: n/a
Steven T. Hatton wrote:
It was really a suggestion of how to address my concerns /without/ putting
everything in namespaces.

replace namespaces with class. I'm having one of those days! :-/

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #35

P: n/a

Steven T. Hatton wrote:
Mark A. Gibbs wrote:
Your second argument, if I understood it, makes no sense. "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." So does that support your argument or not?

Yes it supports the point I was making.


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

I mean, this is how I look at it. If I have a class Foo and a function
bar(), there is no coupling unless there needs to be, and if there needs
to be a relationship, there needs to be a relationship.
If a function requires access to member data, then by all means make it
a member function. But static functions can't access member data, now
can they?

Of course they can.


I did not say class static functions, I said static functions, which is
equivalent to globabl functions. I was being very careful not to do this
in order to not muddy the waters, but this one slipped by.

Globabl functions cannot access member data. So there is no imperative
to make them members. It is completely optional.
something different, I suppose, but for all practical purposes it is
safe to assume that the only functional difference between a global
function and a class static function is that that the class static
function has access to private and protected class static data and
functions.

A static function has access to all member data. Am I missing something
here? I only have a couple months of real C++ experience, so I may have
misunderstood something, but I'm almost certain a static member function
can access all member data of instances of the class.


class Foo
{
public:
static void foo();
static int foo_and_bar_can_see_me;
int foo_cannot_see_me1;
protected:
static int foo_can_see_me1;
int foo_cannot_see_me2;
private:
static int foo_can_see_me2;
int foo_cannot_see_me3;
};

void bar();

Given an instance of Foo f in foo or bar:

void foo()
{
foo_and_bar_can_see_me = 1; // ok
foo_can_see_me1 = 1; // ok
foo_can_see_me2 = ; // ok

Foo f;
f.foo_cannot_see_me1 = 1; // ok
f.foo_cannot_see_me2 = 1; // ok
f.foo_cannot_see_me3 = 1; // ok
}
void bar()
{
foo_and_bar_can_see_me = 1; // ok
// foo_can_see_me1 = 1; // bad
// foo_can_see_me2 = ; // bad

Foo f;
f.foo_cannot_see_me1 = 1; // ok
// f.foo_cannot_see_me2 = 1; // bad
// f.foo_cannot_see_me3 = 1; // bad
}

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?

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. 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. In C++ you don't even need
to rely on the compiler's whims and fancies, just make the accessor
functions inline.

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).
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?

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?

I type "top" then a "::" and the IDE looks for a class or namespace
called top. It finds the namespace named top and pops up a charming
little list box of all namespaces, classes and functions in namespace
top. Then I click on the "math" namespace, and the box refreshes, now
with a list of all the namespaces, classes and functions in namespace
top::math. I could scroll down, but I'm too lazy, so I type "s". the
field is narrowed considerably. There's sec(), sin(), sqrt() and more. I
could click, but I paid a lot for this snazzy IDE, so I type the "i".
Now the field is narrowed down to sin(), sinh() and a couple others. So
I click on the "sin". Now I see a list of all the overloads of "sin".

Now, none of my IDE's do it, but I've never been impressed by IDE's, so
my compilers often have none to speak of (or I don't use them often, as
in the case of CodeWarrior). I suppose I could get a better editor. So
I'm not an authority on the subject, but there's probably an IDE out
there right now that does it for C++. If not, there's no practical
reason why there can't be, once someone is willing to put in the work.

select

java.Math.[get a listing of available members with their type displayed]
java.lang.Math perhaps?
You could replace "static Math class in Java" with "Math namespace in
C++" in your statement, and it would still be valid. The *only* reason
there is a static Math class in Java (as opposed to a Math namespace) is
that Java does not support free functions.

One might argue that the real difference is that in Java you have another
level of encapsulation. I find 'free' functions to be of questionable
value. Some people seem to think of them as global functions.


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.

An external function that uses a class is just another client of that
class. It sees the same interface as anyone else. If that interface
changes, well you broke your program anyway, that's not the function's
fault.
Given that C++ has the option, what are the advantages here?

Perhaps. There is the advantage of predictability. That is, since there
are fewer options, it's easier to determine how something is structured.
It also enforces certain structural rules that programmers might otherwise
violate.


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.

The only possible plausible argument in your favour is that having a
Math class means that all the math functions must be declared in a
*single translation unit* (or a single header file, in practice). Yeah,
I suppose there's some merit to that - you know exactly where to look
for a function. But that comes at a price.

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, ALL files that use ANY math functions
will now need to be rechecked by the compiler. So much for predefined
headers.

Plus the obvious maintennance headaches trying to maintain one HUGE
header file instead of a dozen smaller ones.

You have not decreased coupling, you have increased it.
Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.
Other than the fact that people tend to be sloppy with namespaces.


People can be just as sloppy with anything in C++, and it's usually the
same people. Is there any emperical evidence that people tend to
sloppiness when namespaces are introduced?

The STL.


Ok, that's not even a complete sentence. The STL what? Sucks? R0x0rs?
Tastes like candy? What makes the STL empirical evidence that namespaces
cause sloppyness? And once again, sloppy in what way? What is sloppy?
Yes, but there are many ways of doing this in C++. You could use a
"Math" class, or you could use a "Math" namespace, or you could prefix
global functions with "Math_".

And (some) C++ programmers believe the last is a viable option.


Your point? Some Java programmers believe that public data members are a
viable option. I wouldn't hire from either group.
Each of these methods groups certain
operations together, and each tell me different things about that
grouping. The class tells me that "Math"'s are things, ie, objects -
it's not called object-oriented programming for giggles - just like
class Student, class smart_ptr_policy or class ifstream. The namespace
tells me that these functions are conceptually grouped in some way, but
otherwise gives me no further indications of how - which is fine, all I
really need to understand is that they are all "Math" functions.

But when you have disorganized your collection of operators as described
above, it is more difficult to work with. As far as OO goes, if you really
understand what Java is doing, you would understand that it is very much OO
to do things that way. But even if you only look at the surface, there is
nothing non-OO about using utilities classes. It's just another way of
using tools effectively.


How have I disorganized anything? From what I can read it's perfectly
well organized. The only difference between your organization and mine is:

// mine
namespace Math {
// organization
}

// yours
class Math {
public:
static // organization
};

I understand perfectly well what Java is doing. And why. And while I
could argue over whether it may or may not be "the" OO way to do things
(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.

As for utilities classes not being "non-OO", that's quite open to
debate, but I am not going to debate it. Instead I am going to take you
up on your final statement. "It's just another way of using tools
effectively."

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.

In Java, all you have is the hammer, so what can you do but use it
everywhere. In C++ (WHICH IS NOT AN "OO" LANGUAGE - it supports multiple
paradigms), you have a whole array of tools. Why stick to the hammer?
Of course I understand that, it was my argument after all. But a class
describes a (surprise, surprise) class of objects.

So if there is only one instance of a class, does that mean OO has been
missused? I find that argument against the use of the Math class to be
silly. Ever wonder why the German cognate for the English /dish/ means
table? There is a lesson there.


I am not an OO expert, so I really can't speak on that authoritatively.
Personally, I don't think singletons violate OO design. But we're back
again to insisting that you can create a "Math" (although we're now
insisting there can be only one (from the Matrix to Highlander)). And
once more I say, there is no Math. But prove me wrong, make one.

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?
The ONLY valid
reasons I can think of for having a non-instantiable (static) class is
when that body of operations MUST NOT be extended, and/or they all make
use of some kind of private data/algorithms that MUST NOT be visible to
the rest of the program.

I tend to believe the onus falls in the other direction as far as the
visibility of data. But that's just what the standard texts on OO say.


Wha?

What onus? What other direction? I mean, if the body of operations CAN
be extended, and if they do not make use of any private data or
functions (that cannot be contained within the function of course), why
do the "standard texts on OO" say that they must be in a class instead
of a namespace?
As I mentioned before, Java has no choice but to do max() with static
class members. You have a choice in C++.

One might argue that you have the illusion of choice in C++. How many
main() functions can exist in a C++ program? How do you specify the
namespace for that function? That sounds like a restraction, not a liberty
to me.


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.

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 to me at least, you are making a statement when you create a class
vs. a namespace. A class describes a "thing", an object. A namespace
describes a group. To me, mathematical operations can be grouped. But a
"Math" doesn't have a "cosh()" capability.

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.


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.

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?
Yup, you understood the intent. There are some advantages to the functional
operator approach to mathematical symbolism.
Unless, of course, you're doing math.
I understand that it was hypothetical, so was my proposed "morse coding
standard".

Can you provide an example of a successfull general purpose programming
language that used such an approach?


After you provide me with a coherent and compelling argument in favour
of ditching non-class functions.
I'm not sure of all the cause and effect, but, yes, Java pretty much forces
the creation of Math. There, of course, are a few alternatives, such as
making a class for each operator, or for some subset of operators. I'll
grant that Java lacks a lot of the available finesse in C++. But that
feature of C++ comes at a cost.


Yes, more complicated compilers and a shortage of IDE's that are smart
enough to automatically guess the function you intend to use from part
of the qualified name.

Frankly, I don't care how hard my compiler vendor has to work to make me
a working compiler. I mean, props to the dudes at Edison, but I don't
see how that's relevant to my design process. So Java lacks a lot of the
finesse of C++, that doesn't explain to me why you would choose to dumb
down C++ now to make it more like Java.

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++?

mark

Jul 22 '05 #36

P: n/a

Steven T. Hatton wrote:
Mark A. Gibbs wrote:
Your second argument, if I understood it, makes no sense. "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." So does that support your argument or not?

Yes it supports the point I was making.


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

I mean, this is how I look at it. If I have a class Foo and a function
bar(), there is no coupling unless there needs to be, and if there needs
to be a relationship, there needs to be a relationship.
If a function requires access to member data, then by all means make it
a member function. But static functions can't access member data, now
can they?

Of course they can.


I did not say class static functions, I said static functions, which is
equivalent to globabl functions. I was being very careful not to do this
in order to not muddy the waters, but this one slipped by.

Globabl functions cannot access member data. So there is no imperative
to make them members. It is completely optional.
something different, I suppose, but for all practical purposes it is
safe to assume that the only functional difference between a global
function and a class static function is that that the class static
function has access to private and protected class static data and
functions.

A static function has access to all member data. Am I missing something
here? I only have a couple months of real C++ experience, so I may have
misunderstood something, but I'm almost certain a static member function
can access all member data of instances of the class.


class Foo
{
public:
static void foo();
static int foo_and_bar_can_see_me;
int foo_cannot_see_me1;
protected:
static int foo_can_see_me1;
int foo_cannot_see_me2;
private:
static int foo_can_see_me2;
int foo_cannot_see_me3;
};

void bar();

Given an instance of Foo f in foo or bar:

void foo()
{
foo_and_bar_can_see_me = 1; // ok
foo_can_see_me1 = 1; // ok
foo_can_see_me2 = ; // ok

Foo f;
f.foo_cannot_see_me1 = 1; // ok
f.foo_cannot_see_me2 = 1; // ok
f.foo_cannot_see_me3 = 1; // ok
}
void bar()
{
foo_and_bar_can_see_me = 1; // ok
// foo_can_see_me1 = 1; // bad
// foo_can_see_me2 = ; // bad

Foo f;
f.foo_cannot_see_me1 = 1; // ok
// f.foo_cannot_see_me2 = 1; // bad
// f.foo_cannot_see_me3 = 1; // bad
}

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?

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. 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. In C++ you don't even need
to rely on the compiler's whims and fancies, just make the accessor
functions inline.

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).
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?

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?

I type "top" then a "::" and the IDE looks for a class or namespace
called top. It finds the namespace named top and pops up a charming
little list box of all namespaces, classes and functions in namespace
top. Then I click on the "math" namespace, and the box refreshes, now
with a list of all the namespaces, classes and functions in namespace
top::math. I could scroll down, but I'm too lazy, so I type "s". the
field is narrowed considerably. There's sec(), sin(), sqrt() and more. I
could click, but I paid a lot for this snazzy IDE, so I type the "i".
Now the field is narrowed down to sin(), sinh() and a couple others. So
I click on the "sin". Now I see a list of all the overloads of "sin".

Now, none of my IDE's do it, but I've never been impressed by IDE's, so
my compilers often have none to speak of (or I don't use them often, as
in the case of CodeWarrior). I suppose I could get a better editor. So
I'm not an authority on the subject, but there's probably an IDE out
there right now that does it for C++. If not, there's no practical
reason why there can't be, once someone is willing to put in the work.

select

java.Math.[get a listing of available members with their type displayed]
java.lang.Math perhaps?
You could replace "static Math class in Java" with "Math namespace in
C++" in your statement, and it would still be valid. The *only* reason
there is a static Math class in Java (as opposed to a Math namespace) is
that Java does not support free functions.

One might argue that the real difference is that in Java you have another
level of encapsulation. I find 'free' functions to be of questionable
value. Some people seem to think of them as global functions.


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.

An external function that uses a class is just another client of that
class. It sees the same interface as anyone else. If that interface
changes, well you broke your program anyway, that's not the function's
fault.
Given that C++ has the option, what are the advantages here?

Perhaps. There is the advantage of predictability. That is, since there
are fewer options, it's easier to determine how something is structured.
It also enforces certain structural rules that programmers might otherwise
violate.


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.

The only possible plausible argument in your favour is that having a
Math class means that all the math functions must be declared in a
*single translation unit* (or a single header file, in practice). Yeah,
I suppose there's some merit to that - you know exactly where to look
for a function. But that comes at a price.

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, ALL files that use ANY math functions
will now need to be rechecked by the compiler. So much for predefined
headers.

Plus the obvious maintennance headaches trying to maintain one HUGE
header file instead of a dozen smaller ones.

You have not decreased coupling, you have increased it.
Both can run just as fast (if you inline the former; the latter is
intrinsically inlined), so it's not a speed issue. Namespace Math::max
provides (essentially) the same amount of collision protection and
encapsulation as class Math::max, so it's not a maintennance issue.
Other than the fact that people tend to be sloppy with namespaces.


People can be just as sloppy with anything in C++, and it's usually the
same people. Is there any emperical evidence that people tend to
sloppiness when namespaces are introduced?

The STL.


Ok, that's not even a complete sentence. The STL what? Sucks? R0x0rs?
Tastes like candy? What makes the STL empirical evidence that namespaces
cause sloppyness? And once again, sloppy in what way? What is sloppy?
Yes, but there are many ways of doing this in C++. You could use a
"Math" class, or you could use a "Math" namespace, or you could prefix
global functions with "Math_".

And (some) C++ programmers believe the last is a viable option.


Your point? Some Java programmers believe that public data members are a
viable option. I wouldn't hire from either group.
Each of these methods groups certain
operations together, and each tell me different things about that
grouping. The class tells me that "Math"'s are things, ie, objects -
it's not called object-oriented programming for giggles - just like
class Student, class smart_ptr_policy or class ifstream. The namespace
tells me that these functions are conceptually grouped in some way, but
otherwise gives me no further indications of how - which is fine, all I
really need to understand is that they are all "Math" functions.

But when you have disorganized your collection of operators as described
above, it is more difficult to work with. As far as OO goes, if you really
understand what Java is doing, you would understand that it is very much OO
to do things that way. But even if you only look at the surface, there is
nothing non-OO about using utilities classes. It's just another way of
using tools effectively.


How have I disorganized anything? From what I can read it's perfectly
well organized. The only difference between your organization and mine is:

// mine
namespace Math {
// organization
}

// yours
class Math {
public:
static // organization
};

I understand perfectly well what Java is doing. And why. And while I
could argue over whether it may or may not be "the" OO way to do things
(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.

As for utilities classes not being "non-OO", that's quite open to
debate, but I am not going to debate it. Instead I am going to take you
up on your final statement. "It's just another way of using tools
effectively."

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.

In Java, all you have is the hammer, so what can you do but use it
everywhere. In C++ (WHICH IS NOT AN "OO" LANGUAGE - it supports multiple
paradigms), you have a whole array of tools. Why stick to the hammer?
Of course I understand that, it was my argument after all. But a class
describes a (surprise, surprise) class of objects.

So if there is only one instance of a class, does that mean OO has been
missused? I find that argument against the use of the Math class to be
silly. Ever wonder why the German cognate for the English /dish/ means
table? There is a lesson there.


I am not an OO expert, so I really can't speak on that authoritatively.
Personally, I don't think singletons violate OO design. But we're back
again to insisting that you can create a "Math" (although we're now
insisting there can be only one (from the Matrix to Highlander)). And
once more I say, there is no Math. But prove me wrong, make one.

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?
The ONLY valid
reasons I can think of for having a non-instantiable (static) class is
when that body of operations MUST NOT be extended, and/or they all make
use of some kind of private data/algorithms that MUST NOT be visible to
the rest of the program.

I tend to believe the onus falls in the other direction as far as the
visibility of data. But that's just what the standard texts on OO say.


Wha?

What onus? What other direction? I mean, if the body of operations CAN
be extended, and if they do not make use of any private data or
functions (that cannot be contained within the function of course), why
do the "standard texts on OO" say that they must be in a class instead
of a namespace?
As I mentioned before, Java has no choice but to do max() with static
class members. You have a choice in C++.

One might argue that you have the illusion of choice in C++. How many
main() functions can exist in a C++ program? How do you specify the
namespace for that function? That sounds like a restraction, not a liberty
to me.


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.

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 to me at least, you are making a statement when you create a class
vs. a namespace. A class describes a "thing", an object. A namespace
describes a group. To me, mathematical operations can be grouped. But a
"Math" doesn't have a "cosh()" capability.

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.


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.

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?
Yup, you understood the intent. There are some advantages to the functional
operator approach to mathematical symbolism.
Unless, of course, you're doing math.
I understand that it was hypothetical, so was my proposed "morse coding
standard".

Can you provide an example of a successfull general purpose programming
language that used such an approach?


After you provide me with a coherent and compelling argument in favour
of ditching non-class functions.
I'm not sure of all the cause and effect, but, yes, Java pretty much forces
the creation of Math. There, of course, are a few alternatives, such as
making a class for each operator, or for some subset of operators. I'll
grant that Java lacks a lot of the available finesse in C++. But that
feature of C++ comes at a cost.


Yes, more complicated compilers and a shortage of IDE's that are smart
enough to automatically guess the function you intend to use from part
of the qualified name.

Frankly, I don't care how hard my compiler vendor has to work to make me
a working compiler. I mean, props to the dudes at Edison, but I don't
see how that's relevant to my design process. So Java lacks a lot of the
finesse of C++, that doesn't explain to me why you would choose to dumb
down C++ now to make it more like Java.

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++?

mark

Jul 22 '05 #37

P: n/a


Steven T. Hatton wrote:

First off I meant to write /using namespace std;/ My brain does weird stuff
like that.

It's ok if used frugally. I still find it to be a bit too permissive and
unstructured.
Then don't use it. That doesn't preclude the use of namespaces or
namespace global functions.
I wasn't really thinking in those terms. I was just trying to determine
what the technical implications, pro and con, of the all objects approach
are. I'm not even thouroughly convinced there would be that much
difference if namespaces were completely removed from the language, and in
their place people used classes. I'm not suggesting that be done, but I am
suggesting that it is a worthwhile thought experiment.
I can tell you what would happen, the same thing that would happen if
you removed packages from Java. A mess.
What I'm saying is that, for example, ::std is a collection of templates
(which I intended as well when I wrote 'class' and 'function') with only
the fact that they are part of the Standard Library as a common
characteristic. Yes, one purpose for namespaces is simply a mechanism for
avoiding name collisions. But limiting their use to that goal puts us back
in the same fix of having a bunch of unrelated entities all laying around
on a common floor.
Except now there are no more name collisions.

If I'm reading you correctly your concern with namespaces is that people
don't use them enough. You would have preferred if there were
std::container and std::algorithm namespaces. Correct?

In the context of the STL namespace, anything more than std is not
necessary anyway. After all, you're not supposed to add anything to it.
And what do I gain by typing std::container::vector over std::vector?
Changing the name would not necessarily fix the problem. Disallowing
functions at namespace scope, however, would be an interesting exercise.
Interesting in the sense of the old chinese curse, perhaps. I maintain
that it adds no functionality and takes away design choices. Ergo, it
has no benefits.

What I'm still waiting for you to explain to me is how it could possibly
decrease the possibility of bugs, or increase clarity - SOMETHING,
ANYTHING - to justify it.
everything in namespaces. I do believe having a rule of thumb that
everything that could be in a class should be in a class would lead to
tighter designs with cleaner demarkation.


But just what is a "tighter" design? How do I measure this "tight"ness?
What are the benefits of "tight" vs. "loose" code? How does
Class::function() provide cleaner demarcation than Namespace::function()?

Just answer me this: can you provide me with any HARD arguments or
PROVABLE facts that support your argument, or is this all just based on
what you "feel" would be "better"?

mark

Jul 22 '05 #38

P: n/a
Mark A. Gibbs wrote:

Steven T. Hatton wrote:
Yes it supports the point I was making.
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?

One might argue that the real difference is that in Java you have another
level of encapsulation. I find 'free' functions to be of questionable
value. Some people seem to think of them as global functions.


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.

Perhaps. There is the advantage of predictability. That is, since there
are fewer options, it's easier to determine how something is structured.
It also enforces certain structural rules that programmers might
otherwise violate.


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-me.../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.

One might argue that you have the illusion of choice in C++. How many
main() functions can exist in a C++ program? How do you specify the
namespace for that function? That sounds like a restraction, not a
liberty to me.


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.
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.


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.
Yup, you understood the intent. There are some advantages to the
functional operator approach to mathematical symbolism.


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.

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #39

P: n/a


Steven T. Hatton wrote:
Mark A. Gibbs wrote:
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.


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.
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?


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.
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.


*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.
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().


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/j...s/jogl/GL.html

[WARNING! May crash some browsers due to it's size]
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-me.../Matrix3f.html


*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?)
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.


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<string> const& args);
Yup, you understood the intent. There are some advantages to the
functional operator approach to mathematical symbolism.


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

Jul 22 '05 #40

P: n/a
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/s...doc.html#44557

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #41

P: n/a
"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:gJ********************@speakeasy.net...
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.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 22 '05 #42

P: n/a
Mark A. Gibbs wrote:
*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.
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.


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.
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.


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++.
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #43

P: n/a

Steven T. Hatton wrote:
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?
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.


In your mind. A maintennance programmer would balk at needlessly
expanding classes, access specifier or no.
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.


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.
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.


The hell part of "it's design is hardly relevant, except, perhaps, as a
curiosity" did you not understand?
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.


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
Jul 22 '05 #44

P: n/a
Mark A. Gibbs wrote:

Steven T. Hatton wrote:
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.


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?
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.


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.
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.


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.
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #45

P: n/a
"Mark A. Gibbs" <x_*********@rogers.com_x>
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
Jul 22 '05 #46

This discussion thread is closed

Replies have been disabled for this discussion.