Re: Hypothetical: All code in classes but main()

From: Mark A. Gibbs (x_gibbsmark_at_rogers.com_x)
Date: 04/10/04


Date: Sat, 10 Apr 2004 20:33:13 GMT


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



Relevant Pages

  • Re: Hypothetical: All code in classes but main()
    ... >>gain access to member data and potentially become bound to it. ... >>the argument Stroustrup gives for having helper functions at namespace ... I have heard some Java wags claim that for performance ... Then I click on the "math" namespace, and the box refreshes, now ...
    (comp.lang.cpp)
  • Re: Hypothetical: All code in classes but main()
    ... > gain access to member data and potentially become bound to it. ... >> There are advantages to having the static Math class in Java. ... >> Other than the fact that people tend to be sloppy with namespaces. ...
    (comp.lang.cpp)
  • Re: Hypothetical: All code in classes but main()
    ... > all data members, if it needs to access private and protected instance ... > the use of public data members in good OO design. ... > namespace math in a namespace top? ...
    (comp.lang.cpp)
  • Re: C# vs VB.Net
    ... CSC students code in java for most classes. ... C# puts in "namespace MyCompany.Technology.Args" for you. ... there is no simple way of telling the runtime not to serialize ... VB.NET has no within-the-line comment syntax ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Connecting to Analysis Services with Java XML
    ... I said to change the "namespace" and not the content (you may also need to ... The xmlns specifies a namespace (sort of like a Java package). ... Is there a way of looking at the request stream ... "DataSourceInfo". ...
    (microsoft.public.data.xmlanalysis)