Article Discussion
The C++ Style Sweet Spot
Summary: Bjarne Stroustrup talks with Bill Venners about the perils of staying too low level and venturing too object-oriented in C++ programming style.
65 posts.
The ability to add new comments in this discussion is temporarily disabled.
Most recent reply: February 22, 2004 10:11 AM by David W.
    Bill
     
    Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
    The C++ Style Sweet Spot
    October 12, 2003 9:29 AM      
    In this interview, C++ creator Bjarne Stroustrup suggests C++ programmers can get the most from C++ by avoiding the perils of staying too low level and venturing too object-oriented in C++ programming style.

    http://www.artima.com/intv/goldilocks.html

    What do you think of Bjarne's comments?
    • Mark
       
      Posts: 2 / Nickname: codegopher / Registered: October 13, 2003 10:25 AM
      Re: The C++ Style Sweet Spot
      October 13, 2003 3:04 PM      
      Stroustrup has indirectly exposed the core reason why engineering has yet to truly come into its own as a valid profession and in most corporate settings remains sadly trapped between management and paradigms such as OOPS. His admonitions about overdoing the creation of classes will never be accepted on the same level as object oriented engineering itself. They require a mature thoughtfullness and passion would result in very fine design and coding in any language or paradigm. These qualities cannot be directly controlled by customers or corporate management and thus do not represent, nor should they, a commodity that they are interested in purchasing. For this, we need leadership from passionate individuals within the engineering community itself and directly on the product development floor. It is up to the engineers to stop waiting for management to ask them to do it and to stop waiting for a better paradigm. We must take responsibility entirely for these matters and show the world what we can do.

      -codegopher :-)
      mcrane@iii.com
    • Mark
       
      Posts: 2 / Nickname: codegopher / Registered: October 13, 2003 10:25 AM
      Re: The C++ Style Sweet Spot
      October 13, 2003 4:44 PM      
      Oops! I meant "OOP", not OOPS. I hope my typos and grammatical lapses to not obscure my point too much.

      -codegopher :-)
    • Vincent
       
      Posts: 40 / Nickname: vincent / Registered: November 13, 2002 7:25 AM
      Re: The C++ Style Sweet Spot
      October 13, 2003 1:26 AM      
      > In this interview...
      > http://www.artima.com/intv/goldilocks.html

      Goldilocks?
      • Bill
         
        Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
        Re: The C++ Style Sweet Spot
        October 13, 2003 6:08 PM      
        > > In this interview...
        > > http://www.artima.com/intv/goldilocks.html
        >
        > Goldilocks?

        I chose the filename because the article reminded me of Goldilocks and the Three Bears, in that one C++ program is too low level, another one is to object-oriented, and a third one is just right:

        http://www.ongoing-tales.com/SERIALS/oldtime/FAIRYTALES/goldilocks.html

        The "Sweet Spot" title came from my teenage readings about tennis. I read somewhere that a tennis racket has an oval area in the lower center called the "sweet spot." When you hit the ball there, you get the maximum power out of the tool. And it sounds and feels good too. Thok. I felt that metaphor fit well with the point Bjarne was trying to make about C++ style.
    • Chris
       
      Posts: 6 / Nickname: mouse / Registered: December 3, 2002 8:33 AM
      Re: The C++ Style Sweet Spot
      October 13, 2003 5:24 PM      
      This is probably the best interview with Bjarne Stroustrup I've ever seen. I think often he's put in a position of "now that new craze X has come along, can you defend C++ as a language given what's been learned from the new craze". In this interview, Venners is following the track of "what makes good design in C++" and "how can people write better C++", and the responses he gets are incredible!

      I think in part this shows Venner's experience with interviewing others. He's also using a lot of pair-programming type language to get clarification on Stroustrup's points.

      Bill Venners: You said that the invariant helps you decide what goes into the interface.

      I read back and didn't see where he said that. But it's an interesting idea. Which was followed up with:

      Bill Venners: Could you elaborate on how? Let me attempt to restate what you said, and see if I understand it. The functions that are taking any responsibility for maintaining the invariant should be in the class.

      Bjarne Stroustrup: Yes.

      Bill Venners: Anything that's just using the data, but not defending the invariant, doesn't need to be in the class.
      (Followed by Stroustrup's elaboration.)

      Wow. This is a new way of thinking about designing objects for me. It's too new to know whether I agree with it or not. If you needed 50 methods, you still need that functionality, don't you? Where do you put it?

      Stroustrup mentions static methods as a possibility for Java, but they have some ring of ugliness to them. Is there some convention or heuristic that can be followed?
      • Ian
         
        Posts: 1 / Nickname: witz / Registered: October 13, 2003 8:44 PM
        Re: The C++ Style Sweet Spot
        October 14, 2003 0:52 AM      
        The advice Scott Meyers gives iirc is to have any supplementary functions that don't need direct access to the class data (and hence don't need to be member functions) in the same namespace as the class. He explains it better than i do so perhaps a quick google is in order. Perhaps you could start with his artima interview, again on that elusive 'sweet spot'.

        http://www.artima.com/intv/mincomp4.html
    • Don
       
      Posts: 2 / Nickname: puffybsd / Registered: October 14, 2003 7:17 AM
      Re: The C++ Style Sweet Spot
      October 14, 2003 0:38 PM      
      He isn't lying when he says he's been advocating this approach to design for a while.

      I guess I was hoping for juicer questions:

      1.) Would you quit programming if you were forced to program in java?

      2.) Who would win in a fight: Larry Wall, Yukihiro Matsumoto or Ken Thompson...

      Actually, I would have really liked to know what kind of projects he has been working on and what other languages he uses besides C++.
    • gangadhar
       
      Posts: 2 / Nickname: gangadhar / Registered: September 30, 2003 2:25 AM
      Re: The C++ Style Sweet Spot
      October 15, 2003 6:12 AM      
      Continuing on the topic of refactoring of a CWnd kind of a class, Why cant the splitting the functionality of the class into multiple classes and making them friends of each other can be done ? How bad/ good an approach is this ? Or is it that the OOP-purists would shy away from friend classes ?
    • Trevor
       
      Posts: 2 / Nickname: trevoredle / Registered: October 12, 2003 5:17 PM
      Re: The C++ Style Sweet Spot
      October 12, 2003 9:29 PM      
      Thanks for posting this article, it made for interesting reading.

      I'm relatively new to C++ and am curious about the libc++ library referred to on the first page of the article. Is this libstdc++ or something else? I don't see the callbacks, signals, and slots he's referring to in the implementation I'm using. I've attempted a web search using google with the pertinent phrases, but struck out. Likewise, with my C++ books.

      Any pointers or beatings with the clue stick would be appreciated.

      Trevor
      • Russell
         
        Posts: 1 / Nickname: johnstrr / Registered: October 13, 2003 2:24 PM
        Re: The C++ Style Sweet Spot
        October 13, 2003 6:30 PM      
        That's libsigc++, which is an independent project separate from the standard C++ library. See link to sourceforge project at the end of the interview (does this qualify as beating with a stick?). It's a cool library.

        This is a great interview, by the way. Thanks!

        Russell
        • Trevor
           
          Posts: 2 / Nickname: trevoredle / Registered: October 12, 2003 5:17 PM
          Re: The C++ Style Sweet Spot
          October 13, 2003 7:30 PM      
          Thanks for the gentle bruising with the clue stick :-) AFAIT, the article got updated to include the correct library name and reference since yesterday, no, no, honestly...

          Trevor
          • Bill
             
            Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
            Re: The C++ Style Sweet Spot
            October 13, 2003 8:07 PM      
            > Thanks for the gentle bruising with the clue stick :-)
            > AFAIT, the article got updated to include the correct
            > library name and reference since yesterday, no, no,
            > honestly...
            >
            Yes, a reader emailed me suspecting it was a typo. Bjarne agreed. I fixed it and added the link in the resources section.
            • Uwe
               
              Posts: 4 / Nickname: uwe / Registered: August 27, 2003 8:00 PM
              Re: The C++ Style Sweet Spot
              October 17, 2003 5:21 AM      
              > > Thanks for the gentle bruising with the clue stick :-)
              > > AFAIT, the article got updated to include the correct
              > > library name and reference since yesterday, no, no,
              > > honestly...
              > >
              > Yes, a reader emailed me suspecting it was a typo. Bjarne
              > agreed. I fixed it and added the link in the resources
              > section.

              BTW, there's also a new signal/slot library added to Boost. And not mentioning Boost when talking about C++ libraries which offer what the standard library doesn't is a severe shortcoming, IMHO.
              • Bjarne
                 
                Posts: 48 / Nickname: bjarne / Registered: October 17, 2003 3:32 AM
                Re: The C++ Style Sweet Spot
                October 17, 2003 8:52 AM      
                > BTW, there's also a new signal/slot library added to
                > Boost. And not mentioning Boost when talking about C++
                > libraries which offer what the standard library doesn't > is a severe shortcoming, IMHO.

                I usually refer to BOOST in my talks and if I remember rightly I mention it later in this interview - you haven't seen half of it yet.

                Anyway, there is much more to C++, its use, its libraries, and its tools than can be mentioned in an interview. For more see: my home pages: http://www.research.att.com/~bs
                • Matt
                   
                  Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
                  Re: The C++ Style Sweet Spot
                  October 17, 2003 11:40 AM      
                  > can't imagine a 1/2 GB string in Java, Python...

                  I just tried it in the Python interpreter and it works fine. Deleting it frees up the memory pretty quick, too.

                  Nevertheless, you'd still want to use C/C++ for such large strings, because in languages where strings are immutable, it is pretty easy to end up with lots of intermediate copies if you aren't careful and since modifying a string means copying it, the C/C++ alternative will be much faster.

                  Once again, it gets down to using the best tool for the task. Right now C/C++ is best for 500MB strings, but in a decade languages like Python and Ruby will be (and then we'll be talking about using C/C++ for 500GB (or perhaps 500TB?!?) strings).

                  As for the shootout links, the neatest thing about them is you can look at code for the same algorithms in a lot of different languages. That's a good way to find languages that strike your fancy and merit more investigation.

                  Of course, some of those implementations are not very optimal. Or maybe it is that implementation across languages is uniform, which can be an advantage, disadvantage or neutral, depending on the language/platform. For example the Fibonacci example seems to only test which language is best at recursion, but it certainly is not the best approach for solving the problem in many languages (see http://www.artima.com/forums/flat.jsp?forum=32&thread=4996&message=16761&redirect=true&hilite=true&q=Fibonacci). What's more interesting to me is that some problems seem to work better in some languages, because the sub-optimal implementation, but when implemented more optimally for each language, different winners will emerge. For example, with a better Fibonacci implementation, you quickly get to numbers that you cannot handle in C/C++ without creating or finding a BigInt class (with the better implementation than recursive one, you quickly get out of the unsigned long range) and you find that Python works with them much more efficiently than Java.
                  • Merriodoc
                     
                    Posts: 14 / Nickname: brandybuck / Registered: March 24, 2003 6:00 AM
                    Re: The C++ Style Sweet Spot
                    October 17, 2003 0:25 PM      
                    > Of course, some of those implementations are not very
                    > optimal. Or maybe it is that implementation across
                    > languages is uniform, which can be an advantage,
                    > disadvantage or neutral, depending on the
                    > language/platform. For example the Fibonacci example
                    > seems to only test which language is best at recursion,
                    > but it certainly is not the best approach for solving the
                    > problem in many languages (see
                    > http://www.artima.com/forums/flat.jsp?forum=32&thread=4996&
                    > essage=16761&redirect=true&hilite=true&q=Fibonacci).
                    > What's more interesting to me is that some problems seem
                    > m to work better in some languages, because the
                    > sub-optimal implementation, but when implemented more
                    > optimally for each language, different winners will
                    > emerge. For example, with a better Fibonacci
                    > implementation, you quickly get to numbers that you cannot
                    > handle in C/C++ without creating or finding a BigInt class
                    > (with the better implementation than recursive one, you
                    > quickly get out of the unsigned long range) and you
                    > find that Python works with them much more efficiently
                    > than Java.

                    I remember the whole fibonacci debate. And it was at the simplicity and efficiency of this example in that discussion


                    fibs = [0,1,1]
                    def smartFib(n):
                    for i in range(len(fibs),n+1):
                    fibs.append( fibs[-1] + fibs[-2] )
                    return fibs[n]


                    that I went wow. And this is where I got the notion that in learning any language (still new to Python and still enjoying the learning process :-) that it is very helpful to know how things in it really work. I've always thought blanket statements in matters of development were bad and this, more than any other single example and discussion I've seen to date, really made it hit home. There are general principles that are good to follow and that can be applied across a wide swath of problems, but the need to dig deep into a problem and get the best solution to your particular instance sometimes requires bending the rules. Or figuring out how to best apply those principles using the tools available, which may in some ways contradict the conventional wisdom.

                    I think everybody learns the fibonacci recursion example and thinks that how it should always be written because that's how you first learn it. Never mind that two classes later you learn about how recursion can be a performance nightmare and you can use a stack to easily remove tail recursion. Everybody goes back to the CS101 recursive version when talking about fibonacci numbers, even though everbody learned in CS309 that it probably isn't the best, most efficient way to implement it.

                    I found something similar with creating primes in Python. I ran across this link http://www.networkcomputing.com/unixworld/tutorial/005/005.html and liked the prime number example, so I figured I would try it on 1,000,000. Well, it finishes, but it's not very fast (or even half-fast), so I tinkered with it for a few minutes and came up with

                    def MyPrime(limit):
                    limit = limit + 1
                    PrimeDict = {2:'Y'}

                    #initialize prime dictionary
                    for x in range(3,limit):
                    PrimeDict[x] = 'Y'

                    RetList = []
                    #tag all non-prime numbers
                    for x in range(2,limit):
                    if PrimeDict[x] <> 'N':
                    RetList.append(x)
                    for y in range(2*x,limit,x):
                    PrimeDict[y] = 'N'

                    RetList.sort()
                    return RetList


                    which does goes up to 1,000,000 and returns all 78498 primes between 2 and 1,000,000 in about 4 seconds. I felt happy :-) I'm no phd like the author of the article, but I like tinkering with Primes too. Mine just happens to be a lot more memory intensive where his is more CPU intensive. At least that's what my performance monitor tells me.

                    Anyway, I agree with you that it gets down to using the best tool for the job. That's why I like having a lot of tools in my toolbelt. It's even better if you really know how to use the tool.

                    I inadvertently typed

                    >>> x = primes.MyPrime(10001000)

                    in the python interpreter and it came back after a few minutes.
                    >>> x[-1]
                    10000993
                    I never knew 10,000,993 was a prime number (can't say I ever really cared...) and that there were 664640 prime numbers

                    >>> len(x)
                    664640

                    up to 10,001,000. And I love the negative slicing in python sequences. That language feature ROCKS! It's such a silly little thing when you think about it, but I love it.

                    I think you have to look at the shootout links with a grain of salt, mostly because of the reason sited in your link to the fibonacci debate. Optimal solutions tend to look different from one language to the next, and in some cases the language is a good fit for the problem and in others you look at the solution and go huh? I think if you really want to get a feel for a language, you need to look at optimal solutions for problems in them. That'll tell you what the language can really do. This is why I never was a big perl fan. There are probably as many optimal solutions for a problem as there are good perl developers.

                    This is also why .NET perplexes me a bit. Why bother developing a CLR and bolting different languages onto it? You have to in some cases shoehorn your language into the runtime and in the process destroy some of the things that are good and right about it. I don't know if the Python on .NET initiative has really gone anywhere, but I remember reading about some of the initial attempts and the concessions you have to make to get Python running right in the CLR causes some serious problems with it. Last I knew the best bet was to follow active perl and have a bridge so you can access the runtime from Python and vice versa. Ah, I digress...

                    My condolences to any fellow Red Sox fans out there. Go Marlins!
                    • Isaac
                       
                      Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
                      Re: The C++ Style Sweet Spot
                      October 17, 2003 3:17 PM      
                      > For example the Fibonacci example
                      > seems to only test which language is best at recursion

                      That was his intention - to test how well languages handle recursion. Other micro-benchmarks were intended to test array access... etc More reasonable to complain that they don't test what they were intended to - for example hash.

                      > some implementations are not very optimal
                      some implementations have simple mistakes ;-)
                      some implementations are too optimised - they are no longer idiomatic

                      Yes, the coolest thing is that you can see code from 40 languages. Hopefully the number of language implementations will continue to grow - Fortran? compiled Lisp/Scheme? Intel C, faster MLs, ...
                      • Matt
                         
                        Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
                        Re: The C++ Style Sweet Spot
                        October 17, 2003 3:39 PM      
                        Batch files, WinBatch, COBAL, C-Shell, Assembly...
                        • Matt
                           
                          Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
                          Re: The C++ Style Sweet Spot
                          October 18, 2003 7:09 AM      
                          Here's the Fibonacci as a batch file!

                          @echo off
                          setlocal
                          if [%1]==[] goto syntax
                          set x=1
                          set y=1
                          set fib=1
                          set count=1
                          if /i %1 leq 1 goto done

                          :loop
                          set /a count=%count%+1
                          set /a fib=%x%+%y%
                          set x=%y%
                          set y=%fib%
                          if /i %count% geq %1 goto done
                          goto loop

                          :syntax
                          echo Specify a number (up to 47 works well) to get the
                          echo corresponding Fibonacci value.
                          goto end
                          :done
                          echo Fibonacci of %1 is %fib%
                          goto end
                          :end
                          endlocal
                      • Bjarne
                         
                        Posts: 48 / Nickname: bjarne / Registered: October 17, 2003 3:32 AM
                        Re: The C++ Style Sweet Spot
                        October 18, 2003 8:27 AM      
                        >
                        > > some implementations are not very optimal
                        > some implementations have simple mistakes ;-)
                        > some implementations are too optimised - they are no
                        > longer idiomatic
                        >
                        > Yes, the coolest thing is that you can see code from 40
                        > languages. Hopefully the number of language
                        > implementations will continue to grow - Fortran? compiled
                        > Lisp/Scheme? Intel C, faster MLs, ...

                        The C++ examples seem to be C style. To contrast, here is a Fibonachi class. The constructor makes a sequence of the first n Fibonachi numbers stating with n1 and n2:

                        template<class T> class Fib
                        {
                        vector<T> seq;
                        public:
                        Fib(int n, const T& n1 = T(2), const T& n2 = T(2))
                        {
                        seq.push_back(n1);
                        seq.push_back(n2);
                        for (int i = 1; i<n; ++i) seq.push_back(seq[ i]+seq[i-1]);
                        }
                        const T& operator[](int i) { return seq; }
                        int size() { return seq.size(); }
                        };

                        Given that you can make Fibonachi sequences of any type supporting addition. For example:

                        Fib<int> si(10);
                        Fib<string> ss(10,"a","b");

                        This is of course just a "silly example" but it does illustrate my point that there is good C++ that is neither C-style nor based on class hierarchies.

                        - Bjarne Stroustrup; http://www.research.att.com/~bs
                        • Isaac
                           
                          Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
                          Re: The C++ Style Sweet Spot
                          October 18, 2003 8:38 AM      
                          > The C++ examples seem to be C style. To contrast, here is
                          > a Fibonachi class

                          Please email it to dada@perl.it
                          (Aldo can only post code that he receives direct from the author)

                          He'll be so overwhelmed that he might actually get around to updating the website ;-)
                        • Isaac
                           
                          Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
                          Re: The C++ Style Sweet Spot
                          October 18, 2003 8:52 AM      
                          Seemed to me like a combination of Objects and ADTs
                          - simple class (representation and invariant)
                          - ADT (functions that act on the object)
                    • Tor
                       
                      Posts: 3 / Nickname: ext / Registered: July 10, 2003 9:32 PM
                      Re: The C++ Style Sweet Spot
                      October 21, 2003 11:40 AM      
                      <code>
                      fibs = [0,1,1]
                      def smartFib(n):
                      for i in range(len(fibs),n+1):
                      fibs.append( fibs[-1] + fibs[-2] )
                      return fibs[n]
                      </code>
                      This is O(n) space and time. You can improve to O(1) space like this:
                      <code>
                      (a, b) = (1, 1)
                      def smarterFib(n):
                      if (n == 0)
                      return 0
                      for i in range(3, n+1)
                      (a, b) = (b, a+b)
                      return b
                      </code>
                      Then you can improve to O(ln(n)) time like this:
                      <code>
                      (a, b, c, d) = (1, 0, 0, 1)
                      def f(n):
                      global a, b, c, d
                      if (n > 1):
                      f(n/2)
                      (a, b, c, d) = (a*a + b*c, a*b + b*d, c*a + d*c, c*b + d*d)
                      if (n%2):
                      (a, b, c, d) = (a+b, a, c+d, c)
                      def evenSmarterFib(n):
                      global a, b, c, d
                      (a, b, c, d) = (1, 0, 0, 1)
                      f(n)
                      return d
                      </code>
                      smartFib will not compute the 1,000,000th Fibonacci number on my computer; it runs out of memory and is killed. The second version will compute the 1,000,000th Fibonacci number, but I need to go make coffee in order to wait long enough for it to finish. The last version computes the 1,000,000th Fibonacci in less than 1 minute. This method is based on the matrix identities for Fibonacci numbers and an optimaztion of taking the exponent of a matrix. You could get even faster than this by using some of the modular identities, or identities involving Lucas numbers, etc. Many of these methods(or at least the identities) are discussed in volume 1 of Knuth.
                      • Tor
                         
                        Posts: 3 / Nickname: ext / Registered: July 10, 2003 9:32 PM
                        Re: The C++ Style Sweet Spot
                        October 21, 2003 11:51 AM      

                        fibs = [0,1,1]
                        def smartFib(n):
                        for i in range(len(fibs),n+1):
                        fibs.append( fibs[-1] + fibs[-2] )
                        return fibs[n]


                        This is O(n) space and time. You can improve to O(1) space like this:

                        (a, b) = (1, 1)
                        def smarterFib(n):
                        if (n == 0)
                        return 0
                        for i in range(3, n+1):
                        (a, b) = (b, a+b)
                        return b

                        Then you can improve to O(ln(n)) time like this:

                        (a, b, c, d) = (1, 0, 0, 1)
                        def f(n):
                        global a, b, c, d
                        if (n > 1):
                        f(n/2)
                        (a, b, c, d) = (a*a + b*c, a*b + b*d, c*a + d*c, c*b + d*d)
                        if (n%2):
                        (a, b, c, d) = (a+b, a, c+d, c)
                        def evenSmarterFib(n):
                        global a, b, c, d
                        (a, b, c, d) = (1, 0, 0, 1)
                        f(n)
                        return d


                        smartFib will not compute the 1,000,000th Fibonacci number on my computer; it runs out of memory and is killed. The second version will compute the 1,000,000th Fibonacci number, but I need to go make coffee in order to wait long enough for it to finish. The last version computes the 1,000,000th Fibonacci in less than 1 minute. This method is based on the matrix identities for Fibonacci numbers and an optimaztion of taking the exponent of a matrix. You could get even faster than this by using some of the modular identities, or identities involving Lucas numbers, etc. Many of these methods(or at least the identities) are discussed in volume 1 of Knuth.
                        • Matt
                           
                          Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
                          Re: The C++ Style Sweet Spot
                          October 21, 2003 0:55 PM      
                          A little context is missing: smarterFib() and evenSmarterFib() are not going to be very smart about calculating the Fibonacci of n=100001 right after calcuating the one for n=100000. The original problem was testing the function in a loop, computing the first Fibonacci, then the second, then the third and so on. In that case, there was an advantage to caching the previous results. Of course, you could argue that you only need to cache the last two results, but that might be going overboard on specificity to the original problem. (By the way, if you're concerned about space, shouldn't you use xrange() instead of range()?)

                          Anyway, I think the salient point is that the original recursive implementation is a ridiculous way to evaluate the value of a language.
                          • Isaac
                             
                            Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
                            Re: The C++ Style Sweet Spot
                            October 21, 2003 3:10 PM      
                            the original recursive implementation is a ridiculous way to evaluate the value of a language

                            Indeed, it would be ridiculous to use one micro-benchmark to evaluate the value of a language.

                            However including recursive implementations as part of a benchmark suite seems reasonable - the Hennessy benchmarks in Bench++ include recursive problems.
                            http://www.research.att.com/~orost/bench_plus_plus/paper.html
                          • Matt
                             
                            Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
                            Re: The C++ Style Sweet Spot
                            October 21, 2003 1:40 PM      
                            By the way, evenSmarterFib() is fast; I can do a million in a little over 5 seconds. However, two million is over 16 seconds. That's not O(ln(n)), is it?


                            N Time in Milliseconds
                            --- --------------------
                            100000 140
                            200000 437
                            300000 734
                            400000 1313
                            500000 1719
                            1000000 5265
                            2000000 16203
                            • Matt
                               
                              Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
                              Re: The C++ Style Sweet Spot
                              October 21, 2003 11:59 PM      
                              > ... That's not O(ln(n)), is it?

                              Ah ha. Whilst riding home on my bicycle, I had a moment to contemplate the universe and another to spare for this question. Naturally, for the former I came to the predictable conclusion of 42 and for the latter to the conclusion that the problem is that large numbers themselves are the problem (or at least a part of the solution). This Knuth character naïvely* assumes that operations on numbers take the same amount of time, regardless of the size of the numbers involved. Of course, this isn't really the case as soon as the numbers are larger than the word size of the processor and particularly not so when they are huge in comparison, as in this case. (Anyone who's written a BigInt class in C++ Programming 101, knows this).

                              * For those who don't realize that this is tongue-in-cheek, please note: this is tongue-in-cheek!
                • Bill
                   
                  Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
                  Re: The C++ Style Sweet Spot
                  October 27, 2003 3:23 PM      
                  > > BTW, there's also a new signal/slot library added to
                  > > Boost. And not mentioning Boost when talking about C++
                  > > libraries which offer what the standard library doesn't
                  > > is a severe shortcoming, IMHO.
                  >
                  > I usually refer to BOOST in my talks and if I remember
                  > rightly I mention it later in this interview - you haven't
                  > seen half of it yet.
                  >
                  Actually, Bjarne mentioned Boost in this installment, but I over-ambitiously edited it out. I have put the mention to Boost back in (on Page 1 of the interview), and linked to Boost from the resources section.
    • Eduardo
       
      Posts: 1 / Nickname: davila / Registered: October 23, 2003 1:54 AM
      Re: The C++ Style Sweet Spot
      October 24, 2003 8:26 AM      
      Where can I find the second part of the interview?
      • Matt
         
        Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
        Re: The C++ Style Sweet Spot
        October 24, 2003 9:41 AM      
        The question is when, not where: I believe the second installment will appear on the Artima home page this Monday.
        • Bill
           
          Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
          Re: The C++ Style Sweet Spot
          October 24, 2003 10:11 PM      
          > The question is when, not where: I believe
          > the second installment will appear on the Artima home page
          > this Monday.

          Actually, this coming Monday will be Part I one of Bertrand Meyer. Bjarne's Part II should appear within a few weeks.

          The best way to be notified when articles come out is probably to subscribe to the newsletter. Just click on Your Settings in the upper left hand corner of this page (after you log in), then scroll down to Your Subscriptions and click the checkbox next to Artima Newsletter. In this weekly email I announce and make a short comment about the new articles.
          • Vincent
             
            Posts: 40 / Nickname: vincent / Registered: November 13, 2002 7:25 AM
            Re: The C++ Style Sweet Spot
            October 29, 2003 0:30 AM      
            > > The question is when, not where: I
            > believe
            > > the second installment will appear on the Artima home
            > page
            > > this Monday.
            >
            > Actually, this coming Monday will be Part I one of
            > Bertrand Meyer. Bjarne's Part II should appear within a
            > few weeks.
            >
            I assume that the majority of these interviews were done in a single 'take'. I must admit that I find the Artima format of splitting interviews and releasing them over a period of time, in order to artificially give the impression of a continuous drip feed of 'new' information, increasingly frustrating.

            (Apart from that, Artima is still my favourite Java oriented web site.)

            Vince.
            • Bill
               
              Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
              Re: The C++ Style Sweet Spot
              October 31, 2003 0:30 PM      
              > > > The question is when, not where: I
              > > believe
              > > > the second installment will appear on the Artima home
              > > page
              > > > this Monday.
              > >
              > > Actually, this coming Monday will be Part I one of
              > > Bertrand Meyer. Bjarne's Part II should appear within a
              > > few weeks.
              > >
              > I assume that the majority of these interviews were done
              > in a single 'take'. I must admit that I find the Artima
              > format of splitting interviews and releasing them over a
              > period of time, in order to artificially give the
              > impression of a continuous drip feed of 'new' information,
              > increasingly frustrating.
              >
              Yes, I was going for the literary equivalent of Chinese water torture. Actually, the situation is this. First of all, I want to do in-depth interviews. I speak with people for about 90 minutes. That comes out to about 12,000 to 15,000 words give or take, which in practice is too much for a single article. People won't read that long of an article. 3000 words is already really long. I aim for 1500 to 2500 words per article on Artima.com. So with the interviews, given I want them to be in-depth, either I cut out a lot of stuff (which I do anyway), or I split them up.

              I chose to split them and that has worked rather well, with a few hickups. First, when I started, I did one interview at a time. So for six weeks I published an interview with Bob Scheifler. Then the next six weeks were Ken Arnold. Then the next six weeks were Martin Fowler, and so on. That seemed to work well until I got to Dave Thomas and Andy Hunt. Perhaps because there were two of them, and they kept responding to each other, I ended up with 2 hours of really good material that I wanted to publish. So that interview went on for 10 weeks straight. It was getting to the point where I figured I should just rename the site DaveAndAndy.com. It was too much. A similar thing happened somehow with Rusty Harold. I tried to find parts to cut out, but I felt that I needed to publish all I published for it to be a cohesive whole. So Rusty's interview just seemed to go on and on.

              So that's when I decided to start staggering people. Because I felt that it was too monotone to have the same voice week after week. It may be that I have gone too far in the other direction, though, because now it is hard to follow a single interview. I now have Anders, James, Bjarne, Bertrand, Matz, and Ward going at the same time. So if all you care about is Bjarne, you have an article only once every six weeks. I do provide easy ways to be notified of articles, though. You can subscribe to the newsletter or the NewAtArtima RSS feed. But by the time you read Bjarne II, you've probably forgotten what was in Bjarne I.

              But here's the thing. When I split up these interviews, I try very hard to make each article a cohesive whole, if possible, focused on one subject. So they are a series, but they're also independent.

              My real goal is to give voice to a lot of perspectives and provide a forum in which people can discuss ideas and opinions, and hopefully get insights and learn from each other things that can help us in our day to day work. That's the real reason there's a different interviewee each week, is to provide that kind of stimulus of differing opinions and perspectives. But I do recognize that I may have gone too far in the multi-voice direction such that the interviews don't feel very serial anymore.

              In the future, I want to publish more articles each week. So that may help. I may also reduce the number of interviews I interleave. If I publish two interview installments a week, and have four interviews going, then each installment of each particular interviewee would come out every two weeks. That might be the best compromise. I'm open to suggestion.

              I'd also like to publish non-interview articles (tutorials, how-tos, etc.) by others, especially by all of you, so if you have ideas for Artima.com articles, please submit them. Info on how is here:

              http://www.artima.com/write.html

              > (Apart from that, Artima is still my favourite Java
              > oriented web site.)

              >
              > Vince.
    • Paul
       
      Posts: 3 / Nickname: foxed / Registered: October 15, 2003 0:17 PM
      integer *should* be part of a class hierarchy
      October 15, 2003 4:45 PM      
      > This is the kind of thinking that's reflected in a
      > language like Java for instance, but a lot of things
      > don't fit into class hierarchies. An integer shouldn't
      > be part of a class hierarchy. It doesn't need to. It
      > costs you to put it there. And it's very hard to do
      > elegantly.

      First of all, the Java int primitive isn't part of a class hierarchy.

      Arguably, it should be. There are several justifications for making everything an object:

      - you can store anything in a collection
      - you can define methods like toString and finalize and know everything will have them
      - you can define operations that all numbers have in common and build applications that work with a range of different numbers, including integers, bigints, floating point, decimal, etc.

      The .NET approach where everything, including integers, are objects seems more uniform and elegant than the Java primitives. Wrapper classes are an acknowledgement that integer-as-object is needed.

      I assume the "costs" Bjarne Stroustrup mentions are performance costs, which can be optimized away.

      I think integer-as-primitive is inelegant compared to integer-as-object.

      What am I missing?
      • Matt
         
        Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
        Re: integer *should* be part of a class hierarchy
        October 15, 2003 5:41 PM      
        I agree, Paul. Bill recently interviewed Matz, the creator of Ruby, who I'm sure doesn't agree with Bjarne on this! In Ruby (and Python and many others) integers are even more like objects than in .NET, where they look more like objects than they do in Java, but still need the boxing and unboxing.

        The only reason to have a special primitive data type is performance. On C++, since it is still C, with additions, that is important, because people expect to be able to get "close to the metal." Many other languages -- Java, Python, Ruby and so on -- have C extensions for that purpose (and for access to close-to-the-metal things). Most of the time, it is a premature optimization to be overly concerned about the speed of integer operations.

        Hardware has come a long way in the last fifteen or twenty years: in those days, luxuries like everything being an object were not as feasible. Around 1989 or 1990, I worked at a place that a product written in Smalltalk -- it was so slow that it was completely unusable on a Windows 3.1 desktop. They were pondering porting the whole thing to C++, just to boost the performance. I don't think that would happen these days.
        • Joe
           
          Posts: 15 / Nickname: jcheng / Registered: October 16, 2002 8:08 AM
          Re: integer *should* be part of a class hierarchy
          October 16, 2003 11:48 AM      
          >> I agree, Paul. Bill recently interviewed Matz, the creator of Ruby, who I'm sure doesn't agree with Bjarne on this! In Ruby (and Python and many others) integers are even more like objects than in .NET, where they look more like objects than they do in Java, but still need the boxing and unboxing. <<

          I like Ruby and I'm glad integers are objects in Ruby. However, Java is appropriate for many classes of applications that Ruby (and Python, et al) would not be at all suitable for, especially where performance is a concern. My understanding is that for number-intensive applications, Java and C# can be comparable to C/C++ in speed (once the IL has been jitted)... whereas Ruby and Python are easily an order of magnitude or two slower. See how big the difference is in matrix multiplication:
          http://www.bagley.org/~doug/shootout/bench/matrix/

          Heck, Ruby doesn't even use native threads and Python's interpreter requires instructions to be executed totally serially. These languages are clearly not designed for apps where high performance is a requirement, since (overgeneralizing here) they don't gain any speed from multiple processors.

          Just as people expect certain levels of performance from C, there are people out there who expect certain levels of performance from Java... Java is just at a different place on the performance/ease-of-development continuum from C/C++ or Ruby/Python/Smalltalk. It seems to be at least performant enough and easy-to-use enough for millions of developers to happily develop on it.
          • Isaac
             
            Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
            Re: integer *should* be part of a class hierarchy
            October 16, 2003 2:11 PM      
            > See how big the difference is in matrix multiplication:
            > http://www.bagley.org/~doug/shootout/bench/matrix/

            A more up-to-date version is available at:
            http://dada.perl.it/shootout/


            > Java is just at a different place
            > on the performance/ease-of-development continuum from
            > C/C++ or Ruby/Python/Smalltalk.

            Smalltalk performance is more like Java than Ruby/Python. Smalltalk implementations have long used what we now know as JIT compilation.

            As you said of Java, in general Smalltalks fast enough.
            http://www.lissett.com/ben/exp/bench1.htm
          • Matt
             
            Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
            Re: integer *should* be part of a class hierarchy
            October 16, 2003 0:42 PM      
            Ah, but you are missing the crucial point to languages like Ruby and Python: use the best tool for the job. You do most of the coding in a nice programmner-friendly and very productive language and use libraries (eg. NumPy http://www.python.org/topics/scicomp/numpy.html), or write C extensions for just those parts that need the blazing performance.

            That matrix multiplication comparison is entertaining, but not of any real value. I believe there are plenty scientists using Python for high-performance numerical tasks, but they would be silly to write it all in pure Python code; instead they use the NumPy module (and/or other other similar modules).
            • Joe
               
              Posts: 15 / Nickname: jcheng / Registered: October 16, 2002 8:08 AM
              Re: integer *should* be part of a class hierarchy
              October 19, 2003 7:59 AM      
              >> Ah, but you are missing the crucial point to languages like Ruby and Python: use the best tool for the job. You do most of the coding in a nice programmner-friendly and very productive language and use libraries (eg. NumPy http://www.python.org/topics/scicomp/numpy.html), or write C extensions for just those parts that need the blazing performance. <<

              I very much understand that... don't get me wrong, I use Ruby all the time. I am not trying to belittle the usefulness of those languages in the real world. All I am saying is that Gosling et al's decision not to make Java primitives objects is a reasonable tradeoff for some set of users/problems.

              For example, some programmers would rather implement a project in one "fast enough" language than in a combination of a really slow and really fast one--especially if binary cross-platform compatibility is a requirement.
      • Joe
         
        Posts: 15 / Nickname: jcheng / Registered: October 16, 2002 8:08 AM
        Re: integer *should* be part of a class hierarchy
        October 16, 2003 11:28 AM      
        Hi Paul,

        I mostly agree with you but just wanted to point out a couple of small things...

        > First of all, the Java int primitive isn't part of
        > a class hierarchy.
        >
        > Arguably, it should be. There are several justifications
        > for making everything an object:
        >
        > - you can store anything in a collection

        C++ doesn't need this, since it has generics--and soon Java and C# will too...

        > - you can define methods like toString and finalize and
        > know everything will have them
        > - you can define operations that all numbers have in
        > common and build applications that work with a range of
        > different numbers, including integers, bigints, floating
        > point, decimal, etc.
        >
        > The .NET approach where everything, including integers,
        > are objects seems more uniform and elegant than the Java
        > primitives. Wrapper classes are an acknowledgement that
        > integer-as-object is needed.

        I think it's a distinction worth noting that .NET integers aren't objects; they're primitives that masquerade as objects through automatic boxing and unboxing. The only difference between this and Java is who is doing the wrapping: the programmer or the compiler. (And with 1.5, Java gets autoboxing as well... I think?)

        > I assume the "costs" Bjarne Stroustrup mentions are
        > performance costs, which can be optimized away.

        The costs are quite high for many applications. I don't think you can so easily optimize them away. I wouldn't be surprised if the performance penalty for many numerical applications was 10X or greater. (Not that I have any data to back that up...)

        > I think integer-as-primitive is inelegant compared to
        > integer-as-object.

        How about integer-as-primitive-with-autoboxing?

        Personally I think Java and .NET strike a very practical balance by having all classes share a common ancestor, but having primitive data types. Stroustrup seems not to condone the former...?
        • Paul
           
          Posts: 3 / Nickname: foxed / Registered: October 15, 2003 0:17 PM
          Re: integer *should* be part of a class hierarchy
          October 16, 2003 4:57 PM      
          Joe says:

          > > - you can store anything in a collection
          >
          > C++ doesn't need this, since it has generics--and soon
          > Java and C# will too...

          Generics work for strongly-typed collections, not heterogeneous ones. I suppose in C++ you could always have a collection of void pointers, which amounts to the same thing but somehow seems uglier to me.

          > I think it's a distinction worth noting that .NET integers
          > aren't objects; they're primitives that masquerade as
          > objects through automatic boxing and unboxing. The only
          > difference between this and Java is who is doing the
          > wrapping: the programmer or the compiler. (And with 1.5,
          > Java gets autoboxing as well... I think?)

          Isn't the whole point of any high level language to get things automated for you?

          This automated treatment is crucial - it means the value types *are* objects in the sense that they have methods and can be stored in collections. It's not just a matter of housekeeping, it means you can treat everything uniformly when it makes sense.

          While boxing is of course necessary to use a value type in a collection, I doubt it's needed to simply call a method.
          I believe Java 1.5 will add boxing for collections, but you still won't be able to call methods through a primitive. Can anyone confirm that?

          I wouldn't use "primitive" to describe an integer in .NET, because it has connotations of a fixed set of special-case types. .NET uses the phrase "value type" which includes not just boolean, char and numbers, but enums and structs too.

          > The costs are quite high for many applications. I don't
          > think you can so easily optimize them away. I wouldn't be
          > surprised if the performance penalty for many numerical
          > applications was 10X or greater. (Not that I have any
          > data to back that up...)

          I don't have hard numbers either, but I doubt it. When you just do arithmetic operations with an integer, it should map straight to an integer in your processor. Is Bjarne performance concern about pure OO systems like Smalltalk where there are no value types? If so, it's curious that the language he mentioned several times to contrast with C++ was Java.
          • Joe
             
            Posts: 15 / Nickname: jcheng / Registered: October 16, 2002 8:08 AM
            Re: integer *should* be part of a class hierarchy
            October 19, 2003 8:18 AM      
            > Generics work for strongly-typed collections, not
            > heterogeneous ones. I suppose in C++ you could always have
            > a collection of void pointers, which amounts to the same
            > thing but somehow seems uglier to me.

            Absolutely. I didn't consider heterogeneous collections; usually when I hear this line of thinking it's referring to homogeneous collections.

            As for the rest of your post, I thought your original post was talking about integer-as-object in a much more full sense--as in, undistinguishable from other class-based objects in both appearance and implementation, in the way that say String is for example. If .NET's type system meets your definition of integer-as-object, then I completely agree with you... working with ints is much nicer in C# than Java, arguably as "elegant", and the performance is the same.
            • Isaac
               
              Posts: 51 / Nickname: igouy / Registered: July 10, 2003 7:42 AM
              Re: integer *should* be part of a class hierarchy
              October 19, 2003 2:19 PM      
              >Generics work for strongly-typed collections, not
              >heterogeneous ones. I suppose in C++ you could always have
              >a collection of void pointers, which amounts to the same
              >thing but somehow seems uglier to me.
              >
              > Absolutely. I didn't consider heterogeneous collections;
              > usually when I hear this line of thinking it's referring
              > to homogeneous collections.

              Any examples of the need to work with heterogeneous collections? I'm struggling to remember an example - even in Smalltalk the collection elements seemed tightly related.
          • Julian
             
            Posts: 1 / Nickname: julianr / Registered: October 21, 2003 1:04 AM
            Re: integer *should* be part of a class hierarchy
            October 21, 2003 5:47 AM      
            > Generics work for strongly-typed collections, not
            > heterogeneous ones. I suppose in C++ you could always have
            > a collection of void pointers, which amounts to the same
            > thing but somehow seems uglier to me.

            You can also use a collection of boost::any objects when the stored objects don't share the same base class. It's not perfect, but it's safe, and a lot cleaner than using void pointers (in fact, I use boost::any for almost everything that would otherwise have been a void*).

            If you would make everything polymorphic in C++, would you still keep value semantics? I think the clear value/pointer semantics of C++ are one of its strengths.
            • Bjarne
               
              Posts: 48 / Nickname: bjarne / Registered: October 17, 2003 3:32 AM
              Re: integer *should* be part of a class hierarchy
              October 21, 2003 10:00 AM      
              > > Generics work for strongly-typed collections, not
              > > heterogeneous ones. I suppose in C++ you could always
              > have
              > > a collection of void pointers, which amounts to the
              > same
              > > thing but somehow seems uglier to me.
              >
              > You can also use a collection of boost::any objects when
              > the stored objects don't share the same base class. It's
              > not perfect, but it's safe, and a lot cleaner than using
              > void pointers (in fact, I use boost::any for almost
              > everything that would otherwise have been a void*).

              For a slightly more general answer, se my FAQ: http://www.research.att.com/~bs/bs_faq2.html#containers

              A collection of void* is very rarely a good answer.
            • Paul
               
              Posts: 3 / Nickname: foxed / Registered: October 15, 2003 0:17 PM
              Re: integer *should* be part of a class hierarchy
              October 22, 2003 11:52 PM      
              > If you would make everything polymorphic in C++, would you
              > still keep value semantics? I think the clear
              > value/pointer semantics of C++ are one of its strengths.

              Thanks for the discussion of boost::any.

              Yes, I would keep value semantics, which of course makes integer a non-object, or at least a non-reference type, as Joe Cheng has been pointing out. The Java/.NET way is to tie value semantics fundamentally to a type, whereas of course in C++ you can treat any type both ways.

              I still like calling methods through anything at all and it seems to me more, not less, elegant to say that toString is available for everything.
      • Jon
         
        Posts: 6 / Nickname: talliesin / Registered: November 24, 2003 4:50 AM
        Re: integer *should* be part of a class hierarchy
        November 24, 2003 10:35 AM      
        > - you can define methods like toString and finalize and
        > know everything will have them

        The main reason I dislike the single hierarchy of Java is that you can call methods like toString and have them do something even if that's meaningless in a given case.

        FWIW though you can do something like the following in C++:

        template<typename T> string toString(const T& obj)
        {
        istringstream ss;
        ss << obj;
        return ss.str();
        }

        template<> inline string toString(const string& strObj)
        {
        return strObj;
        }


        The second of these two functions is a specialisation that means that if the object already defines a string() operator then that will be used, and in the most trivial case where the object actually is a string this should hopefully be optimised away to nothing.

        In the first case, which will be called in the more general case the standard mechanism for serialising an object to characters is used to construct the string. This will work for all the built in types, and for classes where the author could see a reason for doing so. If there is no reason to represent the class as a string then it won't compile - whereas with Java it will compile but then produce output of little value other than as debugging clues.

        If the class' author has genuinely been remiss in not providing a way to serialise the class to a character stream then it can be provided without altering the classes definition by defining the function ostream& operator<<(ostream&, const someObject&);. This also makes it easier to add support for different character types, rather than tying that choice into an entire object heirarchy that is inseperable from the language. (I'll admit though that I would often be happier if C++ had a character type with guaranteed UTF-16, UTF-32 or even UTF-8 semantics).

        So I'd go further than saying that integer shouldn't be part of a hierarchy and say that neither should string, vector<pair<int, void*> > or many other types, unless their use or implementation genuinely gains from it (and in the latter case the inheritance could be private or protected). I think that's what Bjarne Stroustrup meant too, though I won't assume he agrees with me.

        Further still, once we have classes free from any hierarchy and we have control over whether objects and primatives are created on the stack or the heap the distinction between integer and an integer-like class (like the wrapped classes of Java and .Net) becomes less striking - both to us and to the compiler (which may well optimise away all or most operations on such a class to the equivalent on an integer). Of course this means that such classes aren't of much use to us, and C++ doesn't have such wrappers (though classes that contains a single primative aren't unheard of).
    • gangadhar
       
      Posts: 2 / Nickname: gangadhar / Registered: September 30, 2003 2:25 AM
      Re: The C++ Style Sweet Spot
      October 14, 2003 1:31 AM      
      The interesting part of the interview was the necessity to keep the number of virtual functions / member functions to a minimum. I wonder if there is any numerical limit on the number of functions. Agreed it differs from each application, but in general what do you think is an optimal number of functions in a class ? Both in terms of performance and also in terms of maintainability.
      And the idea of the invariants is excellent !
      • Jared
         
        Posts: 1 / Nickname: juliana / Registered: October 14, 2003 0:28 AM
        Re: The C++ Style Sweet Spot
        October 14, 2003 4:33 AM      
        For Java, I tend to follow a "rule of ten". Each method has 10 lines, each class has 10 methods, and each package has 10 classes. Those are obviously rough guidelines, but larger ratios make the code difficult to read and maintain.
        • Matt
           
          Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
          Re: The C++ Style Sweet Spot
          October 14, 2003 8:09 AM      
          > For Java, I tend to follow a "rule of ten". Each method
          > has 10 lines, each class has 10 methods, and each package
          > has 10 classes. Those are obviously rough guidelines, but
          > larger ratios make the code difficult to read and
          > maintain.

          So, how would you refactor JFrame in Java, or CWnd in MFC, for example? Or at least, what general approach would you take?

          This is something that came up with Scott Meyer's interview and some others, if I remember. I've been trying to get Bill to follow up by asking about refactoring a specific example of a well-known class with a ton of methods, such as either of the two mentioned above.
          • Bill
             
            Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
            Re: The C++ Style Sweet Spot
            October 14, 2003 8:40 AM      
            > So, how would you refactor JFrame in Java, or
            > CWnd in MFC, for example? Or at least, what
            > general approach would you take?
            >
            > This is something that came up with Scott Meyer's
            > interview and some others, if I remember. I've been
            > trying to get Bill to follow up by asking about
            > refactoring a specific example of a well-known class with
            > a ton of methods, such as either of the two mentioned
            > above.

            Ken Arnold touched on this with his <code>getKnobs()</code> notion. Basically he suggested having the handful of methods that most people use most of the time in the interface, plus a <code>getKnobs()</code> method that allows people to tweak all the little details that sometimes some people will want to tweak. Kind of like flipping down that little hidden panel on your TV set to reveal little knobs that let you mess with the color, horizontal scan rate, and so on:

            http://www.artima.com/intv/taste4.html
          • Merriodoc
             
            Posts: 14 / Nickname: brandybuck / Registered: March 24, 2003 6:00 AM
            Re: The C++ Style Sweet Spot
            October 14, 2003 8:47 AM      
            > So, how would you refactor JFrame in Java, or
            > CWnd in MFC, for example? Or at least, what
            > general approach would you take?
            >
            > This is something that came up with Scott Meyer's
            > interview and some others, if I remember. I've been
            > trying to get Bill to follow up by asking about
            > refactoring a specific example of a well-known class with
            > a ton of methods, such as either of the two mentioned
            > above.

            That's one heck of a question! I don't even know where you would begin. Either of those classes do a lot of things and handle some pretty complex tasks.

            Seriously, how useful would a 10 method windowing class be? I think you have to defer to Einstein on this one and 'make everything as simple as possible, but not simpler'. To which one could always retort with 'Any fool can make things bigger, more complex, and more violent. It takes a touch of genius-and a lot of courage-to move in the opposite direction.' I think it would take more than a touch of genius to effectively refactor the aforementioned classes.

            Anyway, refactoring CWnd or JFrame is still one heck of a question. On the surface you're left with either get rid of a lot of functionality or reduce the number of methods and increase the number of classes that compose the main class.

            Ripping out functionality would limit what you can do in either case and probably isn't a realistic option. The other option, composing the main class of a bunch of smaller classes, would reduce the number of methods, but then anytime you needed to do anything interesting, you would have to get a reference to the particular piece of the window and work with that particular object. That has its own pitfalls. So instead of needing to know a bunch of method calls, you would need to know all of the classes that make up the main class and all of those contituent class' method calls.

            This would increase the number of things you would need to know and I think runs afoul a bit of the generally accepted principle of eliminating get/set methods as much as possible. I don't see much of a difference between get/set and needing to get a constituent object and calling a method or setting a property on it. You're still doing something that affects the state of the main class. It's not as bad as needing to poll the class for its state and then setting something, but it's certainly not clean. The main class would have to poll its contituent objects before doing anything. This would all be hidden from the end user, but it doesn't strike me as elegant or efficent.

            Does anybody else have any ideas on this one? It's a heck of a question (I'm guessing why it doesn't get asked, or gets dodged when it does), although I think I've mentioned that already...
            • Don
               
              Posts: 2 / Nickname: puffybsd / Registered: October 14, 2003 7:17 AM
              Re: The C++ Style Sweet Spot
              October 14, 2003 0:20 PM      
              > > So, how would you refactor JFrame in Java, or
              > > CWnd in MFC, for example? Or at least, what
              > > general approach would you take?

              Let's face it, CWnd wraps an awful API. Even the much cleaner WTL version, CWindow, has a bunch of gunk. (JFrame is much better, IMHO, but still has gunk).

              Where does the gunk come from? The gunk comes from trying to take on too much responsibility at once. These windowing classes are responsible for registering messages, handling timers, resizing themselves, attaining focus, changing style, interacting with peers, tracking their children, repainting, bitblting and self-disposal.

              The fix is to strip down the Window class to the bare minimum of what a Window is (rectangle) and
              let other classes (or libraries) handle the extraneous or unrelated. WindowStylist - in charge of decorating windows, WindowPlanner - handles windows events, WindowGrimReaper - in charge of managing the window life cycle*.

              Suddenly the CWnds of the world look a lot simpler. Other classes are shouldering some of the burden. But wait, this might seem ugly because it's kind of procedural.

              But there's more to the ugliness than that. Developers entertain mixed metaphors when it comes to windows. On one hand, a window is a rectangle. On the other hand, a window is a metaphor for the Application as a whole.

              So developers want to see the simple setTitle(), resize(), close() API that is Window As Rectangle, but also expect the kitchen sink interface that properly reflects Window As Whole Enchilada.

              In a way, the WAWE metaphor provides a nice Facade pattern implementation to everything. But it's unsettling when we look for the simplier interface. My answer to refactoring: change the name of the class from JFrame to JVisualKitchenSink and CWnd to CVisualWholeEnchiladaApplication

              *(I have a whole version with private delegates for defaults in my mind).
            • Chris
               
              Posts: 6 / Nickname: mouse / Registered: December 3, 2002 8:33 AM
              Re: The C++ Style Sweet Spot
              October 14, 2003 10:33 AM      
              This is nearly exactly my question.

              http://www.artima.com/forums/flat.jsp?forum=32&thread=10110

              I don't see anyone giving really good answers. Helpful suggestions, yes, but not full-blown answers. The question is inherently complex. You have to understand what all of the responsibilities/concerns are, and what the usage patterns are. This is not a trivial task for user interface development.

              Though it's significantly related to my interests in managing software complexity, I have too many other interests right now to tackle it with the amount of diligence that would be required to do a good job. Darn day job. :->
      • Walter
         
        Posts: 12 / Nickname: wkaras / Registered: December 22, 2003 2:53 PM
        Re: The C++ Style Sweet Spot
        December 22, 2003 8:38 PM      
        > The interesting part of the interview was the necessity to
        > keep the number of virtual functions / member functions
        > to a minimum.
        ...


        That wasn't what I understood him to be saying. I thought he was saying that a big part of designing a class is thinking about whether, how and why additional classes would be derived from it. Following some rule of thumb like "just make 'em all virtual" only helps you ignore an important part of the class design thought process.

        The only place I've seen good information re the performance of virtual functions/base classes is in the C++ Annotated Reference Manual. It dicusses possible implementations of these features, which are interesting in there own right because they're so ingenious. Unfortunately, the ARM is very out-of-date, so only old geezers like myself are likely to have a copy of it. It's too bad Dr. Stroustrup has not incorporated this material into C++PL.
    • Uwe
       
      Posts: 4 / Nickname: uwe / Registered: August 27, 2003 8:00 PM
      Re: The C++ Style Sweet Spot
      October 17, 2003 5:11 AM      
      One additional thought on the "too hot, too cold, just right" issue:

      Bjarne describes how using C++ in a low-level, C-style way is as suboptimal as using it in an über-OO, Java-style way. (BTW, I suppose they go very well together, often code that is designed Java-style needs to be implemented C-style.)

      It could be inferred that he considers well-used C++ to be superior to C as well as Java - and of course he'd be absolutely correct with that ;-) - but an important point is IMHO that each misuse C++ is a lot more cumbersome than using the respective style in the original language:

      Getting a low-level, C-style solution to work in C++ is far more difficult than creating a real C solution. E.g. a custom memory management system in C is not trivial, but quite straightforward. In C++ it is no longer so (you have to consider POD's, copying, destructors, stuff ...).

      A "pure-OO" language can also work very well. I won't comment on Java, but e.g. in Ruby the fact that every datatype is derived from a root class never gets in your way. In Ruby, this is just an implementation detail that never contorts your design - true multiparadigm programming is possible.

      In C++, trying to be "pure-OO" is really bad because it means working against the language. Wether it is a bad idea in general is a secondary, almost moot, consideration.

      "When in Rome, do as the Romans do."

      If you are lucky - like I am - you happen to find the true C++ way of multiparadigm design a natural - as good as or even better than "pure OO" - way to think about design and programming.
      • Merriodoc
         
        Posts: 14 / Nickname: brandybuck / Registered: March 24, 2003 6:00 AM
        Re: The C++ Style Sweet Spot
        October 17, 2003 5:49 AM      
        > "When in Rome, do as the Romans do."
        >
        > If you are lucky - like I am - you happen to find the true
        > C++ way of multiparadigm design a natural - as good as or
        > even better than "pure OO" - way to think about design and
        > programming.

        This is one of the reasons I like Python as well as C++. You can do either procedural or OO as needed, and they both look logical in the language.

        Most of the performance talk here has been about numeric types. I think where you really get the performance boost in C++ is in the ability to combine an OO design with the low-level memory access allowed in C. Recently somebody I work with was troubleshooting a performance problem with putting a large report together in XML. One of the issues is that the string manipulation was just too darn slow with all of the packaged classes (string and XML) in C++ and in various other languages (It was prototyped in VB and that required a lot of patience in large cases), so we put together a class specifically for concatenating and manipulating very large strings. When you got to really large strings (500MB+), the file I/O was taking longer than the creation of the string. Previously large reports were taking a horribly long time. The class cut a 20 minute operation (our main test cases were ~20 minutes and didn't remotely approach 500MB reports) down to well under 1 on average.

        I can't imagine a 1/2 GB string in Java, Python, <insert your favorite dynamic interpreted garbage collected language here>, etc. As for numerics, as many people have already pointed out, that is easy to get around in many languages. In Python you can extend the language with a module written in C/C++ for performance critical pieces. Java is pretty good in most cases with numerics. In the Microsoft world you can create a COM object that can be called for any critical tasks. And so on.

        I always get a little nervous when I hear about "the one true way" when it comes to programming. Some tools are better than others for some tasks and it helps to have some understanding of as many as reasonably possible. Having everything be an object may (I question this still from time to time, I don't buy it) be more elegant, but objects always carry baggage and sometimes that baggage needs to be dumped.

        I'm sure many people will disagree with this statement, but I feel that when elegance gets in the way of solving a real problem, elegance must go. At the end of the day your customer (client, manager, internal users of your app in a corporation, etc.) doesn't give a poop about whether your application has a great class structure, makes clever uses of collections/dictionaries/hash tables, uses Exceptions instead of return codes for error handling, is purely object oriented or not, follows some self imposed 'rule of X' where you don't ever have more than X methods in a class, etc. They care that the application gets their job done in a reasonable fashion. All of the above mentioned things more often than not help you get to your goal, but all they are is tools. Something to help you get where you're going. They are not an end in and of themselves.
      • Walter
         
        Posts: 12 / Nickname: wkaras / Registered: December 22, 2003 2:53 PM
        Re: The C++ Style Sweet Spot
        December 22, 2003 10:22 PM      
        I would be interested in an elaboration of why it's so meaningful or important whether or not there is a single common root class. Have you seen a langauge where the root class defines actual behaviors that are useful to all possible classes?

        In SmallTalk, it seems to me that the root class is a mechanism that allows you to encode algorithms that depend only on the interface to an object, and not on any of its behaviors. It's a nice trick, in that it re-uses semantics related to class hierarchies, thus keeping the language small. But it's a bit of a cheat, since class hierarchies in SmallTalk are supposed to be about shared behavior.

        C++ uses a different approach to allow for generic algorithms -- templates. Although templates add new syntax and semantics to the language, it's definitely the right choice given the performance-sensitive applications C++ (vs. SmallTalk) is targetted at.

        Java tries to follow in SmallTalk's footsteps, but it doesn't really work well. Lacking templates, a shared interface in Java can only be captured in a common base (interface). Interface inheritance in Java (and C++) doesn't work with primitive types and can't capture many aspects of an object interface, especially when you get into interfaces that defines "geometries" of multiple types rather than "algebras" of a single type. Java muddles through by defining a small common interface in the root class that allows a library of the most common generic containers to be provided. This leaves Java reciting the mantra of Pascal: the problem isn't that you can't do it, the problem is that you want to do it.
    • David W.
       
      Posts: 7 / Nickname: viewpoint / Registered: February 16, 2004 0:09 PM
      Re: The C++ Style Sweet Spot
      February 16, 2004 5:39 PM      
      > In this interview, C++ creator Bjarne Stroustrup suggests
      > C++ programmers can get the most from C++ by avoiding the
      > perils of staying too low level and venturing too
      > object-oriented in C++ programming style.
      >
      > http://www.artima.com/intv/goldilocks.html
      >
      > What do you think of Bjarne's comments?

      Dr.Stroustrup's conceptual view is useful and makes practical sense of Classes. Made things more clear .
      Thanks Dr.Stroustrup for a great language and the fact you still wear blue jeans.

      Sweetspot resolve:
      The Sweet spot is formed through the center and gathering or letting go as required from start to the end of the applications runtime but stays in the sweet spot all the while.

      The how's I figured. I hope reasonably correct :

      Validation:
      The sweet spot validation helps to clarify the significance of class construction. Defining the class with this in mind given use makes sense too. Moreso, as the constituients of the class/objects are accounted for, given the task.

      Defining class form:
      I gathered to define the class in terms of a work shop with a table in the center of it.

      Tools you are going to use most of the time and only those for the immediate task at hand at a given time are placed on the table.

      Tools which you may use but at different times are on the walls and can be retrieved anytime as required.

      Defining requirements of the class
      A class is formed where resolve to design is achieved given the requirements of the immediate problem domain.

      Other classes:
      All other classes can be developed and instanced as needed or as the domain morphs to demand it.

      Consider too high or too low level programming:
      Resolve undue problems which might otherwise be done
      well enough anyway with what the existing class can do already.

      Thanks again

      Viewpoint
    • David W.
       
      Posts: 7 / Nickname: viewpoint / Registered: February 16, 2004 0:09 PM
      Re: The C++ Style Sweet Spot
      February 17, 2004 10:15 PM      
      The Sweetspot of a C++ style. To find if this existed and for the benifet of Mr.Kite with thanks I developed the following Truth test.

      Purpose:
      To challenge or highlight the significance of class qualification through simplistic C++ techniques as a norm rather than sophisticated techniques as a norm.

      The following test of a practical class design was developed to establish the strength or weakness of the concept. Overview as follows.

      Classes developed
      Class shoe : for a shoe shop, shoe designer and shoe materials chemist lab.

      Results:
      I was surprised to see what happened. As it turns out Bjarne was righton in a most explicit, useful and practical sense.

      Resolve overview:
      Class definitions refined is very important. The result
      should be a succinct collective of definitions working in harmonic association for the domain written for whether one class or more. Each class can be defined naturally for use in full or in part depending on its purpose.


      Conclusion:
      Given the results I was very happy to have read and more importantly learned from this article.


      To clarify resolve:

      Classes are used for different purposes. With this in mind a class in an application should be thought out from the most simplest format first.

      Develop one class, another class if needed, and another class if needed.

      Call em as needed. If this dosn't work functionality wise then reconsider the use of other available C++ formatting techniques.

      The Truth test:

      To show the strength and truth of this approach.

      Here in this example I have developed 3 levels of class use. I could have used more and still can using the simplist technique noted above.

      Consider a class called Shoe within two different levels of possible use. After... watch where the class goes and ask too where else it can go. It is Sweet!

      A class shoe for a shoe store and a class shoe for a shoe designer.

      You would not write everything about the shoe store business in a shoe class. But you could. A shoe to a shoe store manager is stock and by way of object instantiation the description of any number of shoes ordered.


      However,it is just one class as part of the shoe store business.

      The shoe store business has other classes as well which define the domain.

      Hence, defining -- defining the integral associations as distinctive class entities is important for symetrical (and if the word elegant is functional and not just gloss), elegant functionality.

      Besides the above this shoe class may be borrowed from the shoe store and placed in a group or set of classes for a shoe designers shoes as well. That's neat!

      Once again the destinction of the class design is for a higher level purpose but is needed as an objective result for the description of the shoes which the shoe designer designs.

      Given this how does the shoe designer get this high level class result?

      Defines other classes. This is why distinctive class dev is important. Classes can work together.

      Class shoe for a shoe designer may be the result of details found in many classes which make up the shoe definition. In this case they are the materials classes of the shoe.

      Examples would be found by defining parts of the shoes to get a shoe result.

      Soooo- shoe soles, shoe sides, shoe tongue, shoe holes, shoe laces could each be a class. They would be put together later to arrive at the description for the shoe store or also as a reference for the shoe designer.

      To define the shoe with as many classes as "IS REQUIRED" to define the shoe "FOR THE SHOE DESIGNER" are the criteria for the classes. Why? The results of materials selection for each class would be a part of the finish design for a proposed shoe for the shoe designer. Wouldn't it? The results would then fit into one Class/ object which is found at the shoe store as well, the shoes description.

      Why not just put it all together in one class and hand the class to the shoe store and use the same class for the shoe designer? For the same reason the details of the chemists or physics labs information is not handed to the shoe store. The don't need it. A class like that WOULD be cluttering the mind and hard to manage.

      Wouldn't it be better to work on just one part of the shoe at a time ? One way to work with the group of classes using windows would be a group of functions in the application to call 2 or 3 other classes and assign to
      a form or dialogs class for informations display as required.

      Now extend it to a 3rd level of classes for shoes:
      All of the classes of the class designer define various materials found in different shoes.

      Each class too is different and can work on their own in a different class setting if there is a requirement. Another advantage of defining the class carefully. It fits in any setting a shoe fits.

      Now bring the materials classes of a proposed shoe down to different level. Another set of classes can be be developed in order for the chemist to resolve the quality of the shoe designers shoe design. How about for defining each class at the level of a chemist. This would be the chemical constituents of each material which goes into the shoe.Or physics lab the physical properties of the shoes in action.

      Here then the above classes though in different settings help to qualify or serve in each others domain.
      The chemist like the shoe designer uses the information of the level above and vice versa to get the the information needed to work with and understand the shoe to be sold.

      Interesting : Now you have lateral groups of classes created by a vertical process of a shoe class which started at the shoe store and can be traced all the way to the chemists and physics lab.

      A simple approach to resolve a complex domain. Ha. really wonderful.

      It looks like this on the map if you can C -|- -|-


      So simply put: These three businesses related to the shoe have been handled with distinct and different classes without other formats of class development techniques. Do you agree ?


      The point taken by this birdbrain given the format of Dr. Stroustrups is his elaboration towards simplicity in class development the abuse of class development techniques found within the C++ arsenal can muddle things up and offset the object from hitting the sweetspot of better functionality.

      Like hitting the tennis racket in other than the sweet spot make the object wobble off its most direct course.

      Of course the above approach could also be applied to the
      format of code which execute the classes as noted in the main article. I believe similar results would be the norm.

      Clearly Thanks again Dr. Bjarne Stroustrup, and C++.

      David W. Stubbs (Viewpoint)
      • David W.
         
        Posts: 7 / Nickname: viewpoint / Registered: February 16, 2004 0:09 PM
        Re: The C++ Style Sweet Spot
        February 19, 2004 0:59 PM      
        C++ Principle infraction !


        In this article it was stated that you do not like data only classes. A struct is better considered for data only requirements.

        With this in mind the above example could illustrate the misuse of the class shoe in the shoe store.

        Data classes seem a practical sollution and a good consideration in place of a struct though. Is the consideration only semantic as a principle or is there significant resource considerations to evaluate given general (but a specific set) of data requirements?

        Argument Statement:
        For the shoe store shoe class structs may be a better consideration. Why?

        Reasons:
        The Shoe store class is a data class which displays information about a shoe. The consideration of a class in this instance may better be handled with a struct.

        Functionality of the struct and class
        functionality associated with the struct could be better left in a file and called for the struct only as required. A leaner sollution.

        A class by definition usually holds functions as well which acts on the data it contains. The instancing of the object of the class would present additonal overhead which is not needed.


        Counter Questions to the why considerations?:
        B). Could a Data Class not be created in place of a struct. Objects created as required from the class and a function object(s) instanced to service the Data object?

        Resolve to question : Semantics and resources
        Is there much difference in overhead or other factor with the instancing process of a struct or Data class given this general requirement?

        Classes and object by conceptual design seem to work together naturally with more promise than structs. However,regardless of objects as a preference structs do have a good and valued purpose.


        Viewpoint
    • David W.
       
      Posts: 7 / Nickname: viewpoint / Registered: February 16, 2004 0:09 PM
      Re: The C++ Style Sweet Spot
      February 20, 2004 10:01 PM      
      > In this interview, C++ creator Bjarne Stroustrup suggests
      > C++ programmers can get the most from C++ by avoiding the
      > perils of staying too low level and venturing too
      > object-oriented in C++ programming style.
      >
      > http://www.artima.com/intv/goldilocks.html
      >
      > What do you think of Bjarne's comments?

      My question pertains to Object Oriented style in C++.

      I would like to ask Bjarne if an object - oriented resolve
      can be made correctly given change factors of his Date example. I include the Bjarnes comments from page 4 bottom paragraph for ease of reference to the problem domain.

      Bjarne's comments Start
      I've seen the Date problem solved by having a base class Date with some operations on it and the data protected, with utility functions provided by deriving a new class and adding the utility functions. You get really messy systems like that, and there's no reason for having the utility functions in derived classes. You want the utility functions to the side so you can combine them freely. How else do I get your utility functions and my utility functions also? The utility functions you wrote are independent from the ones I wrote, and so they should be independent in the code. If I derive from class Date, and you derive from class Date, a third person won't be able to easily use both of our utility functions, because we have built dependencies in that didn't need to be there.
      Bjarne's comments finish.

      Viewpoint change considerations:

      Question is : I wonder if you might evaluate the following consideration of outside function groupings for class use with inheritance or derived class formatting please.

      Date Class:
      Date class purpose : To evaluate/display current date of any TimeZone

      I Used the Invariant factor to create date class thus clearly defined.

      Exact change to consider for class correctness:

      If I have 60 functions which can be segregated to 6 groups. Each are premised in context as clearly defined. Is it ok to use these functions to create a class for the purpose of deriving a class with the Date class.

      The stipulation is that the 6 groups are clearly defined.

      Using the functions as classes derived from groups
      // group example is : finding times given ships compass
      // group example is : finding times given star positions
      // group example is : finding times given sun locations
      // extend hypothetical examples to 6 groups 10 functions each.

      // Windows application use
      Instance the derived classes as required through code in events or text based code processing .

      Is there anything wrong with doing this given resources are not a problem.

      Thankyou

      Viewpoint
    • David W.
       
      Posts: 7 / Nickname: viewpoint / Registered: February 16, 2004 0:09 PM
      Re: The C++ Style Sweet Spot
      February 22, 2004 10:11 AM      
      > Invariants
      > What do you think of Bjarne's comments?

      Viewpoint Topic:
      Invariants use and dangers to class development.

      The Invariant factor is a means of validating the contents of a class. With this factor there is a danger in creating classes which are too large or out of scope with the class definition and purpose.

      This is because validation in itself allows for the significance of member functions and variables in a class. With this you may validate that which may be better defined in another class as well as left outside the class as a function.

      Therefore the use of Invariant factoring is an integral part but not less important to creating a class than other considerations for defining and developing a class. Moreso, if the class is to achieve definition for use in a clear and correct perspective of the application domain.

      An example is : If you have a shoe class defined and it is provisional to an applications purpose it is always a shoe class. Even if other classes which define the shoe can be created they should never replace the class defined if it is has been defined correctly. Other classes which support the shoe in definition can only compliment and be complimented by its design and therefore included or excluded for development use given an applications purpose.


      Thankyou for your article.


      Viewpoint Stubbs