HN user

ajax77

30 karma

github.com/jdduke

Posts0
Comments14
View on HN
No posts found.

This simply isn't true. A number of years ago with the introduction of DirectX 10, Autodesk began transitioning several mainstay products to exclusive DirectX use under Windows (see http://archicad-talk.graphisoft.com/files/autodesk_inventor_...) Morevoer, Autodesk has moved to using a modern, unified renderer for a large number of their products. There may be other CAD companies "holding up" the "monstrosity" of dated OpenGL versions, but Autodesk is not that company. In all likelihood, the issues lies not with the CAD companies, but with their clients that refuse to upgrade their legacy applications of 10-15+ years age.

Pedantry isn't so bad, if it's correct... As was stated, the term "source codes" is very common in many communities, particularly scientific computing and associated academic circles. The only credibility lost here is... well let's just move on here, shall we?

That's simply not the case.. In general, the "no penalty" holds true for primitive data types, and when passing an r-value instance of a class that has a move copy constructor defined. In the case where your object is an expensively constructed l-value, it is preferable to pass by const reference rather than value (assuming you plan to use the object later... otherwise you could indeed pass using std::move semantics).

With the niceties of C++11, it's certainly become a lot less painful; lambdas, auto (both variable and return type), variadic templates and r-value references give the language just enough flexibility to allow functional style with far more natural syntax. To be sure, it's not a perfect setup; type traits (e.g., enable_if) in function signatures are ugly and hardly a replacement for concepts.

I've been dabbling in the creation of a functional library that provides a modest subset of Prelude-inspired features from Haskell. https://github.com/jdduke/fpcpp Many of the algorithms are simply wrappers around stl algorithms, hiding some of the syntactic awkwardness attendant with the heavy use of iterators. Some day I'll get around to playing with monadic devices, and integrating the list comprehension work that I've done recently.

A slight variation with neither error codes nor exceptions.

  template< typename T >
  auto findRoots(T a, T b, T c) -> pair<maybe<complex<T>>, maybe<complex<T>>> {
    typedef complex<T>       C;
    typedef maybe<C>         Root;
    typedef pair<Root, Root> Roots;

    if (a == 0) {
      if (b == 0) 
        return Roots(nothing,      nothing);
      else
        return Roots(Root(-c / b), nothing);
    } else {
      auto d     = C(b*b - a*c*4);
      auto two_a = a*2;
      return Roots(Root((-b + sqrt(d)) / two_a), 
                   Root((-b - sqrt(d)) / two_a));
    }
  }
  
maybe is simply a templatized std::pair wrapper that lets you check if the returned value is valid (either via maybe.valid() or if(maybe)). All imaginary results are handled automatically via std::complex. nothing decomposes into an invalid maybe value of the appropriate type.

Thankfully you're right; compilers have come a long way and Clang in particular has done a lot for easing the pains of template programming in a number of ways.

I'm knee deep in the development of several header-based, fully templated libraries, so I still certainly feel the pains of compilation times. And while the tests/samples I deal with tend to be somewhat extreme in their (ab)use of templates, I think you'll still find that the average Boost user would give a lot for yet speedier compilation.

It should be noted, it's very clear his executable sizes are for a Debug compilation. I tossed the same code for the final example into VC10, and sure enough in release mode the compiled size is 10KB, and in debug it's just less than the size he stated. This is for 64-bit.

I'm not sure what point it serves to compare debug mode executable sizes, but that should be clearly stated in the article. As other people stated, the final example really ought to lose the wrapping class in the spirit of C++11 brevity and functional decomposition.

Whether or not you are a C++ fan, templatized algorithms ARE often faster than their C-based, generic counterparts. Any decent C++ compiler should be able to inline generic code while C often relies on function pointers. I'm not saying this is always the case, but often. std::sort beating qsort is a typical argument, though I'm not sure the two algorithms are equivalent excepting language-specific constructs (http://stackoverflow.com/questions/4708105/performance-of-qs...)

As for size, you're absolutely right, though for many scenarios that appears to be less and less a pressing concern. Perhaps the biggest drawback is compilation time.

I can sympathize; I too use C++ by day, and have become increasingly bitter/jealous/frustrated as I've spent more time with Haskell by night.

To the point that, I've started writing several libraries that enable in C++ several of the features I miss most in Haskell. In particular, I've missed the natural syntax of higher order functions, e.g., currying and functional composition, as well as the pithy expressiveness of Prelude vs the STL. With C++11, we can have these things, and while Boost gives us a wealth of functionality, it's hardly the most natural (and lightweight) library.

fc (functional composition) (https://github.com/jdduke/fc) and fpcpp (functional programming with C++)(https://github.com/jdduke/fpcpp) are my recent (very much work-in-progress) efforts towards this end.

With fc, one can naturally compose functions, lambdas and function objects, e.g., given composable functions f, g, h, write auto fgh = f + g + h; or, auto fgh = compose(f, compose (h,g));, and then call it as fgh(a,b,c);

fpcpp enables syntax like

  let pi = [](unsigned samples) -> double {
      typedef std::pair<double,double> point;
      let dxs = map([](const point& p) { return p.first*p.first + p.second*p.second; },
                    zip(take(samples, rand_range(-1.0,1.0)),
                        take(samples, rand_range(-1.0,1.0))));
      return 4.0 * filter([](double d) { return d <= 1.0; }, dxs).size() / dxs.size();
  }
  EXPECT_NEAR(pi(10000), 3.14);
In writing fc and fpcpp, I've actually become less and less concerned for the future of C++; having used a good number of the C++11 features available, I've regained a good deal of my passion for C++ programming. Really, C++ needs a more expansive and natural standard library, iterators are powerful but are NOT the answer.

I looked for the "sign that the quote is bogus" but missed it. Maybe results that have 5 million hits are bogus? Maybe results that have relevant links are bogus? I can enter all sorts of valid quotes from both current and historic figures into Google, and obtain very similar results. ("Ask Not What Your Country Can Do For You", "A man should look for what is, and not for what he thinks should be", "A man who dares to waste one hour of time has not discovered the value of life.") I fail to see how that adds anything to the discussion. Neither do I see how the fact that Newton restated, rather than originated, a particular idea, helps your argument.

Also, please inform me as to how this statement relates to Lord Byron. Nothing I've read of Byron would favor him as the statement's originator over Newton. I can't help but think of this scene from Good Will Hunting when I read your replies http://www.youtube.com/watch?v=ymsHLkB8u3s&t=1m56s

Hard work as a means to success is hardly a post-romantic invention. Newton was very much a student of Aristotle, the teachings of whom we can see very much aligned with the statement in question.

In that light, would you also doubt these verified Newtonian quotes that suggest similar thinking? "If I have seen further it is only by standing on the shoulders of giants." "Truth is ever to be found in simplicity, and not in the multiplicity and confusion of things." "If I am anything, which I highly doubt, I have made myself so by hard work."

You highly doubt a revolutionary figure said a radical thing because it would have been considered impolite/revolutionary/radical?

Newton was in a world of his own; he, along with a few select others (Lock, Descartes and others), are in large part responsible for the Enlightenment. The very Enlightenment this statement characterizes so well. Even if he didn't say it (I cannot find the source, but I have read this quote a number of times in various papers), it is very much the kind of statement he would make.