Paranoid about style/elegance and function size, please quell

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • E. Robert Tisdale

    #16
    Re: Paranoid about style/elegance and function size, please quell

    John Potter wrote:
    [color=blue]
    > Sean Fraley wrote:
    >[color=green]
    >> std::cout << "this program has run for " << std::clock()
    >> << " clock ticks.\n";[/color]
    >[color=green]
    >>is actually a better choice than[/color]
    >
    >[color=green]
    >> std::cout << "this program has run for "
    >> << foo(std::cout)
    >> << "clock ticks.\n";[/color]
    >[color=green]
    >>for the following reasons:[/color]
    >[color=green]
    >>1) it works like you think it should. Try writing, compiling,
    >>and then running some code with your implementation of foo.
    >>It does some weird stuff.[/color]
    >
    > Be nice. Do not misuse it. Use it properly and complain about that.
    >
    > foo(std::cout << "this program has run for ")
    > << "clock ticks." << std::endl;[/color]

    I hope everyone remembers that Sean is complaining about
    Francis Glassborow's function and not mine.
    I felt that I was obliged to do the best I could
    with the function that Francis gave us.



    Comment

    • E. Robert Tisdale

      #17
      Re: Paranoid about style/elegance and function size, please quell

      Francis Glassborow wrote:
      [color=blue]
      > Let me reinsert the context:
      >
      > 1) Functions that are designed for doing (e.g. display a graphic) should
      > return void or, if member functions possibly *this.
      >
      > Which was one of my guidelines wrt to writing code. Now go and examine
      > the writings of any of the above list of authors and you will find that
      > they implicitly apply that guideline in their published code (i.e. you
      > will find them using a void return type whenever there is no sensible
      > value to return.
      >
      > Bjarne Stroustrup was/is following a policy of as close to C... so he
      > had very little choice about operators including the assignment ones in
      >
      > C++ yielding values. I suspect that Ritchie may have been heavily
      > influenced by the precursors to C (such as B and BCPL). In practice
      > there are numerous bugs in code that are a result of the C and C++
      > assignment operators returning values.
      > And where did I mention a pure procedural style? I would like some
      > support for a pure functions but that is a different issue.
      >
      > It is also interesting to note that relatively late on C++ increased its
      >
      > support for 'procedure' type functions by allowing return of the call of
      >
      > a void function to a function with a void return.
      >[/color]

      According to Brian W. Kernighan and Dennis M. Ritchie,
      "The C Programming Language", Copyright 1978,
      Chapter 6 Structures, Section 2 Structures and Functions, page 121:

      "There are a number of restrictions on C structures.
      The essential rules are that the only operations
      that you can perform on a structure are take its address with &,
      and access on of its members. This implies that
      structures may not be assigned to or copied as a unit,
      and that they can not be passed to or returned from functions.
      (These restrictions will be removed in forth-coming versions.)"

      Appendix A C Reference Manual, Section 14 Types revisited,
      Subsection 1 Structures and unions, page 209:

      "There are only two things that can be done with structures and unions:
      name one of its members (by means of the . operator);
      or take its address (by unary &). Other operations, such as assigning
      from or to it or passing it as a parameter, draw an error message."

      These restrictions on passing and returning struct's
      have long since been removed from the C computer programming language
      but old habits die hard -- especially bad habits.
      There is no longer any reason to pass a pointer to the return value
      explicitly in the function argument list.
      Your compiler will do that for you.
      It is still a good idea to pass a const pointer
      if you need to reference large objects from the function.

      Comment

      • Albrecht Fritzsche

        #18
        Re: Paranoid about style/elegance and function size, please quell

        Ed Avis wrote:[color=blue][color=green]
        >>You are entitled to an opinion but it is not widely shared by expert
        >>C++ programmers (such as Bjarne Stroustrup, Nico Josuttis, Scott
        >>Meyers, Rob Murray, Steve Dewhurst, Herb Sutter, Andrei Alexandrescu
        >>...).[/color]
        >
        >
        > You can't just drop a long list of names without giving some
        > references to where we can find their opinions to back you up.[/color]

        It is really not that hard to find some articles by those mentioned
        above. Google sometimes does wonders, but

        Emergency loans from £100-£2,500 with 15-minute funding. Soft credit check won't affect your score. No fees from Sunny. Apply 24/7 for same-day approval.


        might be a sufficient starting point if you haven't have any books
        by those authors handy or not read yet.
        [color=blue]
        > What exactly is this concept? If you say that 'a procedure does not
        > return a value' then ... it doesn't give
        > any reason to write programs in this style.[/color]

        Of course not, but if you head for a clear and concise(?) style than
        you might find procedures sometimes the most valuable tool. Just
        have a look at the STL - there those procedures are called algorithms
        and more often than not having a void return.

        Until now noone has complained, though.
        Ali


        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
        [ comp.lang.c++.m oderated. First time posters: Do this! ]

        Comment

        • John Potter

          #19
          Re: Paranoid about style/elegance and function size, please quell

          On 1 Jul 2003 15:34:11 -0400, Francis Glassborow
          <francis.glassb orow@ntlworld.c om> wrote:
          [color=blue]
          > 1) Functions that are designed for doing (e.g. display a graphic) should
          > return void or, if member functions possibly *this.[/color]

          ostream& operator<< (ostream&, string const&);
          iterator vector<T>::inse rt(iterator, T const&);
          [color=blue]
          > Which was one of my guidelines wrt to writing code. Now go and examine
          > the writings of any of the above list of authors and you will find that
          > they implicitly apply that guideline in their published code (i.e. you
          > will find them using a void return type whenever there is no sensible
          > value to return.[/color]

          Your statement is acceptable, but not your intent. Whenever there is
          any way to use the imagination to create a sensible return, the function
          is not void. Void is a last resort used in inverse proportion to the
          sensibleness of the user. :)

          John

          [ See http://www.gotw.ca/resources/clcm.htm for info about ]
          [ comp.lang.c++.m oderated. First time posters: Do this! ]

          Comment

          • Francis Glassborow

            #20
            Re: Paranoid about style/elegance and function size, please quell

            In message <3F00980D.80709 09@jpl.nasa.gov >, E. Robert Tisdale
            <E.Robert.Tisda le@jpl.nasa.gov > writes[color=blue][color=green]
            > > You are entitled to an opinion
            > > but it is not widely shared by expert C++ programmers
            > > (such as Bjarne Stroustrup, Nico Josuttis, Scott Meyers, Rob Murray,
            > > Steve Dewhurst, Herb Sutter, Andrei Alexandrescu ...).[/color]
            >
            >Please cite the references and quote the relevant passages.[/color]

            Please read clause 25, Algorithms library of the C++ standard. It is too
            long to quote here but you should find a copy in JPL's reference
            library.
            Those wishing to avoid using procedures (functions returning nothing)
            must, effectively, avoid the C++ library and any third party library
            that does not guarantee to avoid all standard functions that return
            void.
            [color=blue]
            >[color=green]
            > > The significance of a function returning void in C++ is that
            > > it is really a procedure
            > > which is a well understood concept in computer science.[/color]
            >
            >It is well understood that procedural programs
            >are difficult read, understand and maintain.[/color]

            I was not writing about procedural programs but that certain actions are
            inherently procedures (i.e. are used for their side effects). Even
            functional programming languages such as Haskell accept that some
            procedural type actions are unavoidable though they try to minimise
            them.
            [color=blue]
            >Each procedure call changes the state of the program.[/color]

            But that is just a subset, each call of a function that has side effects
            potentially changes the state of the program. A function in C++ can only
            return one thing, which means that any function that is (in)directly
            responsible for changing two or more non-local objects has to choose
            which to return if either.
            [color=blue]
            >The state affects the flow control
            >which can change the thread of execution.
            >The thread of execution determines the sequence of procedure calls, etc.
            >What you end up with is spaghetti.[/color]

            If we try to use uncontrolled procedural programming, but that is very
            different from using procedures to carry out actions and functions to
            evaluate and return values. Unfortunately (in the opinion of purists)
            C++ supports everything from pure procedures to pure functions with
            every conceivable mixture in between. At least I can call out my
            procedures by giving them a void return type. I wish I had a similar
            mechanism to identify pure functions.
            [color=blue]
            >
            >Procedural programs are difficult to analyze
            >and practically impossible to prove correct.[/color]

            I never advocated writing pure procedural programs.
            [color=blue]
            >You should avoid procedure calls (and assignment statements)
            >whenever possible.[/color]

            Then C++ is a bad language to use, Haskell would be a much better
            choice.
            [color=blue]
            >[color=green]
            > > And destructors simply do not have return values of any kind
            > > so they are not exceptions to a guideline,
            > > the programmer is never given the choice.[/color]
            >[color=green]
            > > What should be the return type of:
            > >
            > > std::ostream& foo(std::ostrea m& os){
            > > std::os << std::clock();
            > > return os;
            > > }[/color][/color]

            That is not what I wrote, please be more careful about attributions. Had
            I wanted such a function I would have written:

            std::ostream& foo(std::ostrea m & out){
            return out<< std::clock();
            }

            or even:

            bool foo(std::ostrea m & out)
            return not (out << std::clock()).f ail();
            }

            Please note that your code includes a non-existent object (std::os) and
            so should fail to compile.


            --
            ACCU Spring Conference 2003 April 2-5
            The Conference you should not have missed
            ACCU Spring Conference 2004 Late April
            Francis Glassborow ACCU


            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
            [ comp.lang.c++.m oderated. First time posters: Do this! ]

            Comment

            • Tony

              #21
              Re: Paranoid about style/elegance and function size, please quell

              I am not C++ expert in any way.
              I like the combination of procedural style and oo style in C++. There
              are many things which best be treated in oo style. There are just a
              few things which bested be treated in procedual style.
              Take y = sin(x). This calculation in my view best be treated as is
              like in math, in procedural style. C++ gives us both styles, I think
              it is a good thing.
              In Java, y = sin(x) is a member of Math class. I found Java way is not
              natural.
              Tony

              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
              [ comp.lang.c++.m oderated. First time posters: Do this! ]

              Comment

              • kanze@gabi-soft.fr

                #22
                Re: Paranoid about style/elegance and function size, please quell

                John Potter <jpotter@falcon .lhup.edu> wrote in message
                news:<qf24gv8vd gfbdastvkck6f4e k64ai9n1f0@4ax. com>...[color=blue]
                > On 1 Jul 2003 15:34:11 -0400, Francis Glassborow
                > <francis.glassb orow@ntlworld.c om> wrote:[/color]
                [color=blue][color=green]
                > > 1) Functions that are designed for doing (e.g. display a graphic)
                > > should return void or, if member functions possibly *this.[/color][/color]
                [color=blue]
                > ostream& operator<< (ostream&, string const&);
                > iterator vector<T>::inse rt(iterator, T const&);[/color]

                void vector<T>::inse rt(iterator, size_type, T const&);

                I don't think you can quote the C++ library for examples of good design.
                There are a few: separating the formatting from the sinking/sourcing in
                iostream, for example. But on the whole... Even within a single class,
                it can't be consistent.
                [color=blue][color=green]
                > > Which was one of my guidelines wrt to writing code. Now go and
                > > examine the writings of any of the above list of authors and you
                > > will find that they implicitly apply that guideline in their
                > > published code (i.e. you will find them using a void return type
                > > whenever there is no sensible value to return.[/color][/color]
                [color=blue]
                > Your statement is acceptable, but not your intent. Whenever there is
                > any way to use the imagination to create a sensible return, the
                > function is not void. Void is a last resort used in inverse
                > proportion to the sensibleness of the user. :)[/color]

                If you have to use your imagination or your creativeness to invent a
                return value, you probably would be better off with void. What should a
                function like EventGenerate:: enrolForEvent( EventHandler& ) return, for
                example? Or the callback EventHandler::o perator()( Event const& ) ?

                Generally speaking, if the purpose of a function is to obtain a value,
                then that value should be returned by means of the return of the
                function. Otherwise, if the function can fail in an unexceptional way,
                the return value should be the error code. Otherwise, in general, the
                return value should be void -- there are a few cases where supporting
                chaining imposes some other return value, but they aren't that often.

                --
                James Kanze GABI Software mailto:kanze@ga bi-soft.fr
                Conseils en informatique orientée objet/ http://www.gabi-soft.fr
                Beratung in objektorientier ter Datenverarbeitu ng
                11 rue de Rambouillet, 78460 Chevreuse, France, Tél. : +33 (0)1 30 23 45 16

                [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                [ comp.lang.c++.m oderated. First time posters: Do this! ]

                Comment

                • kanze@gabi-soft.fr

                  #23
                  Re: Paranoid about style/elegance and function size, please quell

                  Sean Fraley <sfraley@rhiann onweb.com> wrote in message
                  news:<LKfMa.313 042$VP.53361032 @twister.neo.rr .com>...[color=blue]
                  > E. Robert Tisdale wrote:[/color]
                  [color=blue][color=green][color=darkred]
                  > > > What should be the return type of:[/color][/color][/color]
                  [color=blue][color=green][color=darkred]
                  > > > std::ostream& foo(std::ostrea m& os){
                  > > > std::os << std::clock();
                  > > > return os;
                  > > > }[/color][/color][/color]
                  [color=blue][color=green]
                  > > At the very least, a function should return a reference to the
                  > > object that was modified so that the function can be used in
                  > > expressions.[/color][/color]
                  [color=blue]
                  > Once again, why?[/color]

                  In that case, one could just as easily ask: why not? The fact that some
                  forms of std::vector::er ase return iterator, and others return void, is
                  obviously poor design.

                  But that begs the point. The fact that there are times when some
                  "procedures " should logically return a value (and thus become functions)
                  doesn't mean that all should. The initial argument was that using
                  "procedures " makes reasoning about the program impossible, and results
                  in spaghetti code. Just returning some random value, which might
                  eventually permit chaining, won't make the program easier to
                  understand. In fact, I'd argue just the opposite -- if the statement
                  contains just one procedure invocation, and nothing else, I know that it
                  does exactly what that procedure does. Once you start chaining
                  functions with side effects (i.e. procedures with return values), you're
                  making things even more complex and difficult to understand. This
                  argument actually weighs in in favor of what Francis originally stated:
                  if the function isn't really a function, then don't fool the reader by
                  making it look like one. (The words are mine, but I think they more or
                  less correspond with what Francis meant.) I would qualify it somewhat:
                  there are procedures which can "fail" in expected (non-exceptional)
                  ways, for which using a return value to indicate error state would be
                  appropriate.

                  And in real life, we do need procedures. If I call a procedure to write
                  something to a file, or to display something on the screen, it had
                  better have some side effects.

                  --
                  James Kanze GABI Software mailto:kanze@ga bi-soft.fr
                  Conseils en informatique orientée objet/ http://www.gabi-soft.fr
                  Beratung in objektorientier ter Datenverarbeitu ng
                  11 rue de Rambouillet, 78460 Chevreuse, France, Tél. : +33 (0)1 30 23 45 16

                  [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                  [ comp.lang.c++.m oderated. First time posters: Do this! ]

                  Comment

                  • John Potter

                    #24
                    Re: Paranoid about style/elegance and function size, please quell

                    On 1 Jul 2003 22:48:02 -0400, Albrecht Fritzsche
                    <albrecht.fritz sche@tiscali-dsl.de> wrote:
                    [color=blue]
                    > Of course not, but if you head for a clear and concise(?) style than
                    > you might find procedures sometimes the most valuable tool. Just
                    > have a look at the STL - there those procedures are called algorithms
                    > and more often than not having a void return.[/color]

                    You seem to count funny. I get void returns on 30 of 102 algorithms.
                    Existence: yes, majority: no. Sorting accounts for 18 of the 30.

                    John

                    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                    [ comp.lang.c++.m oderated. First time posters: Do this! ]

                    Comment

                    • E. Robert Tisdale

                      #25
                      Re: Paranoid about style/elegance and function size, please quell

                      Ed Avis wrote:
                      [color=blue]
                      > Displaying a graphic doesn't really 'modify' that graphic,
                      > so I agree, it should return void.[/color]

                      It modifies the display.


                      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                      [ comp.lang.c++.m oderated. First time posters: Do this! ]

                      Comment

                      • Francis Glassborow

                        #26
                        Re: Paranoid about style/elegance and function size, please quell

                        In message <d6652001.03070 20553.1ac25d2@p osting.google.c om>,
                        kanze@gabi-soft.fr writes[color=blue]
                        >This
                        >argument actually weighs in in favor of what Francis originally stated:
                        >if the function isn't really a function, then don't fool the reader by
                        >making it look like one. (The words are mine, but I think they more or
                        >less correspond with what Francis meant.) I would qualify it somewhat:
                        >there are procedures which can "fail" in expected (non-exceptional)
                        >ways, for which using a return value to indicate error state would be
                        >appropriate.[/color]

                        Yes that is much my view. If a procedure can fail in ways that influence
                        the rest of the program I normally give it a return type of bool. Note
                        that that has nothing to do with whatever the procedure was doing, it is
                        just an effective way of reporting failure.

                        Indeed only yesterday I wrote some code that went like this:

                        bool dosomething(myt ype & mt){
                        try {
                        // do various things that modify mt
                        // but always leave mt stable
                        return true;
                        }
                        catch(...) {return false;}
                        }

                        In the circumstances I did not care what had gone wrong, just that it
                        had not worked as intended. Of course this function is also terrible
                        because it uses SEME :-)


                        --
                        ACCU Spring Conference 2003 April 2-5
                        The Conference you should not have missed
                        ACCU Spring Conference 2004 Late April
                        Francis Glassborow ACCU


                        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                        [ comp.lang.c++.m oderated. First time posters: Do this! ]

                        Comment

                        • Francis Glassborow

                          #27
                          Re: Paranoid about style/elegance and function size, please quell

                          In message <3F03A082.30304 05@jpl.nasa.gov >, E. Robert Tisdale
                          <E.Robert.Tisda le@jpl.nasa.gov > writes[color=blue]
                          >Ed Avis wrote:
                          >[color=green]
                          > > Displaying a graphic doesn't really 'modify' that graphic,
                          > > so I agree, it should return void.[/color]
                          >
                          >It modifies the display.
                          >[/color]
                          And if that is done by a system call? What should I then return?

                          --
                          ACCU Spring Conference 2003 April 2-5
                          The Conference you should not have missed
                          ACCU Spring Conference 2004 Late April
                          Francis Glassborow ACCU


                          [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                          [ comp.lang.c++.m oderated. First time posters: Do this! ]

                          Comment

                          • Ed Avis

                            #28
                            Re: Paranoid about style/elegance and function size, please quell

                            brangdon@cix.co .uk (Dave Harris) writes:
                            [color=blue]
                            >And you should make sure no-one confuses a procedure with
                            >a function. One way to achieve that is to make sure functions never
                            >have side effects and procedures never return results.[/color]

                            I fear this may turn into another SESE-ish discussion. While such a
                            style is often useful, I wouldn't like to mandate it for all code, all
                            of the time. Inherently stateful things like an I/O library don't
                            really need to follow the rule, since it is obvious that
                            print_string() has a side effect, whether or not it returns void.

                            It would help if compilers had some way for the programmer to assert
                            that a function has no side effects, and have this statically
                            checked. I think gcc has some weird attribute you can set on a
                            function to say it is pure and so calls to it may be optimized away,
                            but it's the programmer's responsibility to make sure the annotation
                            is sound.

                            --
                            Ed Avis <ed@membled.com >

                            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                            [ comp.lang.c++.m oderated. First time posters: Do this! ]

                            Comment

                            • E. Robert Tisdale

                              #29
                              Re: Paranoid about style/elegance and function size, please quell

                              Francis Glassborow wrote:
                              [color=blue]
                              > And you were responding to Mr. Tisdale's rewriting of what I had written.[/color]

                              Your function

                              void foo(void){
                              std::cout << std::clock();
                              }

                              modifies a global variable -- cout.


                              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                              [ comp.lang.c++.m oderated. First time posters: Do this! ]

                              Comment

                              • Rob

                                #30
                                Re: Paranoid about style/elegance and function size, please quell

                                "Francis Glassborow" <francis.glassb orow@ntlworld.c om> wrote in message
                                news:y6ZZKEEH7$ A$EwRu@robinton .demon.co.uk...[color=blue]
                                > In message <3F03A082.30304 05@jpl.nasa.gov >, E. Robert Tisdale
                                > <E.Robert.Tisda le@jpl.nasa.gov > writes[color=green]
                                > >Ed Avis wrote:
                                > >[color=darkred]
                                > > > Displaying a graphic doesn't really 'modify' that graphic,
                                > > > so I agree, it should return void.[/color]
                                > >
                                > >It modifies the display.
                                > >[/color]
                                > And if that is done by a system call? What should I then return?
                                >[/color]

                                There are only three possibilities.

                                1) The system call can never fail, so there is no point in returning
                                anything.

                                2) The system call can fail, and no recovery is possible in the function
                                making the call. In this case the error needs to be reported.
                                That may be done by returning an error code or (if an error should
                                never be ignored) throwing an exception.

                                3) If the system call can fail, but recovery is possible by the function
                                making the call, then the appropriate action needs to be determined
                                by what the caller needs to be told about. [This is a mix of 1 and
                                2].

                                In the end it comes down to what the caller needs to know about and what
                                it can reasonably be expected to cope with.




                                [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                                [ comp.lang.c++.m oderated. First time posters: Do this! ]

                                Comment

                                Working...