1. 38
  1.  

  2. 9

    The author handwaves a little that Python and Haskell have the tools to do this task easily, so I thought I’d add those as examples. First, Python:

    from itertools import count, islice
    triples = (
        (x, y, z)
        for z in count()
        for x in range(1, z)
        for y in range(x, z)
        if x * x + y * y == z * z
    )
    for t in islice(triples, 100):
        print(t)
    

    and in Haskell:

    module Main where
    
    triples :: [(Integer, Integer, Integer)]
    triples = [(x, y, z) | z <- [1..], x <- [1..z], y <- [x..z], x*x + y*y == z*z]
    
    main :: IO ()
    main = putStrLn . unlines . map show $ take 100 triples
    
    1. 6

      People often gripe about the STL but what Alex Stepanov created is truly a thing of beauty. It was truly radical at the time. It’s even radical now considering that generic programming is still not mainstream.

      However, it isn’t what most people are used to. Most people still don’t understand what iterators are. For those that do not know, iterators are a generalization of a pointer. Pointers are a subset of iterators.

      People don’t get the STL because people can’t math.

      1. 5

        The STL is amazing (see Sean Parent’s talk on generic programming for some background).

        But along with all the benefits it has brought to C++, it has also been a factor in some of the issues the author touches on (and which are well-known), like long compile times, slow debug performance, hard to understand error messages. Whether it is math that makes the C++ ranges implementation shown hard to read, or the sheer volume of packaging of that math – compare it to the python and haskell implementation above.

        What I find a more interesting question raised by this discussion is whether the prevalence of certain industries in the C++ committees has steered the language in a direction where things like compile times are neglected because they can just throw more hardware at such problems. But of course this corporate interest is also part of the reason C++ had a revival in the first place.

        1. 2

          indeed ! STL starts from algorithms and not objects, and algorithms are defined on algebraic structures. imho, extending these structures with complexity requirements is the crux, and iterators are the key :)

          1. 1

            For (advanced) generic programming to become mainstream, someone’s got to work on the compile times.

            Maybe we need a -fno-monomorphization flag to get super fast debug builds at least?..

            1. 1

              I’m wondering if concepts can help speed up compile times. I know they are meant to improve error messages and readability, but certainly, they can be used to short-circuit parts of the compilation process… I haven’t really explored that idea much though.

          2. 3

            Manager Conan in response to “what is best in life”:

            “To conquer your projects, too see the bugs driven down before you, and to hear the lamentations of the developers.”

            1. 1

              A bit off-topic, but here’s a lazy but in my opinion simple C implementation:

              struct triple {
                  int x;
                  int y;
                  int z;
              };
              
              struct triple triples_generator(bool new) {
                  static __thread int z = 1;
                  z = new ? 1 : z;
                  for (;; z++)
                      for (int x = 1; x <= z; ++x) {
                          for (int y = x; y <= z; ++y) {
                              if (x * x + y * y == z * z)
                                  return (struct triple){x, y, z++};
                          }
                      }
              }
              

              it can then be used as follows:

              for (int i = 0; i < 10; i++) {
                      struct triple t = triples_generator(!i);
                      printf("Triple (%d, %d, %d).\n", t.x, t.y, t.z);
              }
              

              __thread can be replaced by thread_local if the compiler provides threads.h from C11.

              1. 1

                This skips over some triples. EDIT: But with some small modifications, yes it’s more elegant. The Pythagorean triples example wasn’t the best way to showcase ranges.

                1. 1

                  I agree that it wasn’t the best way to showcase ranges, that’s why I considered the C example off-topic:)

              2. 1

                Using precompiled headers will shave a bit of the compilation time, but the compiler will still have to do the template instantiations every time. Has the author tried explicitly instantiating the templates in a different translation unit?