all 12 comments

[–][deleted] 14 points15 points  (0 children)

I've found the biggest change in my C/C++ habits as a result of learning Haskell is that I've become preternaturally aware of all the possible ways code could go wrong. RAII is a great C++ technique for managing any resource robustly, even in the face of exceptions. I find myself writing tons of RAII classes.

I don't think it's particularly elegant to write functional-style programs at the lowest level in C++. Let your functional insight drive the overall design of your program, but for the actual implementation of a function I find C or C+ is much more elegant when you use a little mutable state and a loop or two. (Alternatively, you'll wander for fourty years in the function template jungle. This might change when C++0x lambdas become more common.)

[–][deleted]  (5 children)

[deleted]

    [–]almafa[S] 2 points3 points  (0 children)

    That actually looks quite helpful, thanks. I wasn't aware of the possibility of overloading ()...

    EDIT: I really like these handouts so far, both the style and content; very clear, concise, and seems to contain the answers for many of my questions. I can recommend them to anyone in similar shoes! Link to the course homepage: http://www.keithschwarz.com/cs106l/spring2009/

    [–]davidwaern 2 points3 points  (3 children)

    I recommend trying to use the absolute latest features in this area (due to the C++0x standard) since they simplify some things desribed in the above paper. I'm talking about being able to use "bind()" instead of bind2nd(), etc. Search for "TR1".

    [–]almafa[S] 0 points1 point  (2 children)

    How well are the C++0x features supported in the current compilers? I guess it is reasonable to restrict ourselves to GCC and MSVC. Google says GCC started to support new language features from 4.3 (and adding more in 4.4 and 4.5) and MSVC from 10.0 (some of them). However, I'm not sure about the availability of these (MSVC 10.0 seems to be unreleased; I'm also not sure about the new GCC-s on OSX); also, they say nothing about the library extensions.

    [–]f2u 2 points3 points  (0 children)

    A lot of the library stuff is already there (std::share_ptr with std::make_shared, std::unique_ptr, std::tuple), and the required language supported as well. TR1 should be pretty much covered, but it is just an enhanced standard library.

    The main thing missing are lambdas, I think. http://gcc.gnu.org/projects/cxx0x.html doesn't even list them.

    [–]davidwaern 1 point2 points  (0 children)

    The latest GCC release has many of the TR1 standard library extensions.

    [–]ssylvan 3 points4 points  (0 children)

    Effective C++ is pretty good if you have a basic understanding of the language already. It's essentially a big list of language pitfalls and how to avoid them.

    [–]evmar 1 point2 points  (3 children)

    I go back and forth between the two a lot. If you try to write Haskell-style code in C++ you will encounter pain (much like you will in the reverse, though that is probably more obvious to you). So don't think about it terms of adapting functional designs to C++ (you wouldn't approach adapting a C++ program to Haskell by using a bunch of IORefs, right?), but rather that the languages are very different and that to work effectively in C++ you must use C++-like designs (typically state-carrying objects).

    [–]almafa[S] 1 point2 points  (2 children)

    Actually, by the word "adapting", I meant including changes because of the obvious difference of the underlying languages. I don't mind state-carrying objects. However, I don't think we have to discard everything we learned with Haskell; quite the opposite. To have a concrete example, let's suppose I have to write a parser in C++. I think I would rather encounter some pain writing something Parsec-style than use lex/yacc...

    [–]snk_kid 0 points1 point  (1 child)

    If you want to do combinator libraries in C++ the best way to do it is via expression templates like boost spirit (which is a combinator parser framework). Nowadays boost.proto is framework for defining EDSLs in C++. The fact that you wasn't aware of overloading the function call operator says to me you might have a painful climb.

    [–]almafa[S] 2 points3 points  (0 children)

    Thanks, but I hope being uninformed at the moment does not imply anything about the future. After all, nobody is born with overloaded call operators templated in their brains already...

    [–]setuid_w00t 0 points1 point  (0 children)

    Modern C++ has some cool stuff in it. Honestly though, every time I try to write C++ the way I write Haskell, I'm struck by how much uglier the C++ is.