Live data from Hacker News

Haskell's effect on my C++ : exploit the type system

vallettaventures.com

21–30 of 57 posts

Re: Haskell's effect on my C++ : exploit the type system

#21

  int a = f();
  if (a 
I believe the latter will generally result in 2 calls to f() (unless it returns less than zero), which could cause undesired behavior or just be inefficient. Of course, it depends on what f() does.

Assuming MAX(0,f()) expands to something like this:

  if( f() 

Re: Haskell's effect on my C++ : exploit the type system

#22
post #21

int a = f(); if (a I believe the latter will generally result in 2 calls to f() (unless it returns less than zero), which could cause undesired behavior or just be inefficient. Of course, it depends on what f() does. Assuming MAX(0,f()) expands to something like this: if( f()

If MAX evaluates f() twice, then it is broken. It's trivial to write a version that only evaluates its arguments once in C++ using templates, and in C using common extensions that allow for macros with multiple statements that act as an expression.

Re: Haskell's effect on my C++ : exploit the type system

#24
post #21

int a = f(); if (a I believe the latter will generally result in 2 calls to f() (unless it returns less than zero), which could cause undesired behavior or just be inefficient. Of course, it depends on what f() does. Assuming MAX(0,f()) expands to something like this: if( f()

It was a poor choice on the part of the author to use the macro-looking MAX() in his example. There is in fact a standard max() function in the header that does not suffer from silly macro-expansion problems:

    template
    const T& max(const T& a, const T& b) {
        return a 
    const T& max(const T& a, const T& b, Predicate p) {
        return p(a, b) ? b : a;
    }
And your definition of MAX() is wrong, not just because of multiple evaluation of the arguments. The “conventionally wrong” MAX() would be this:

    #define MAX(a, b) ((a) 

Re: Haskell's effect on my C++ : exploit the type system

#25
post #23

> int a = f(); > if (a > has been replaced with > const int a = MAX(0,f()); Going by MAX capitalization, it must be a macro, in which case the code is wrong. I am guessing this is a synthetic example, but still - try and get the basics right.

Technically, the code is wrong only if f() is not pure.

Re: Haskell's effect on my C++ : exploit the type system

#26

map and fold are available in C++, though they're called std::transform (in ) and std::accumulate (in ). Totally agree with the author's point, the C++ I write nowadays is heavily influenced by my Scala/Haskell/Lisp exposure and is much better for it.

Yep. , , , and are all incredibly useful, yet so underused.

Re: Haskell's effect on my C++ : exploit the type system

#27
post #23

> int a = f(); > if (a > has been replaced with > const int a = MAX(0,f()); Going by MAX capitalization, it must be a macro, in which case the code is wrong. I am guessing this is a synthetic example, but still - try and get the basics right.

Technically, the code is wrong only if f() is not pure.

Yes, I know, but there is no way to enforce it. This a classic "noob" mistake with macros - using a macro argument more than once.

Re: Haskell's effect on my C++ : exploit the type system

#28
My somewhat biased stance: functional programming languages make you progress as a programmer quickly. Becoming great requires deliberate practice and intrinsically hard problems. So you learn programming and CS about 5-10 times as fast in a functional language. This is part of why enterprise Java/C++ devs plateau at a skill level of 1.2 (even into their gray-haired years) while ML and Haskell programmers can reach 1.5 in a few years and generally cross 2.0 if they make a career out of software. (For reference, here's where I explain that scale: http://michaelochurch.wordpress.com/2012/01/26/the-trajector... ; it's a 0.0-to-3.0 scale and 1.5 is what most of us would consider a seriously good programmer.)

So if you want to grow as an engineer and computer scientist, learn these languages. You'll learn a lot fast, and not just about one programming paradigm (FP) but about complexity and how to manage it. You'll just learn a lot more about software because the way to learn software is to write it and one person can actually accomplish significant things in these languages. Java and C++ demote the individual contributor: "commodity" developers crank out classes and a more senior "architect" figures out how to bolt them together.

That said, these languages won't improve your performance in typical Java and C++ jobs. Six months of practice for exposure might give you some new ideas and make your code and performance better. Beyond that, they might diminish it. Why? Because you start hating these languages (Java and C++) and the accidental complexity they throw at you, which starts to look foreign and unnecessary. You get to a point where your own code (if you use the idioms of these languages, and you probably should, because it's not just about you) starts to look like someone else's. When you start hating your own code, disengagement sets in and it gets ugly fast. I can "hack" Java and C++ but I certainly wouldn't do a major project in them at this point.

My Java and C++ are uninspired now that I know better languages. Often, the only way I can write decent Java is to write it first in Scala (which I like, a lot) and transliterate the solution. Whether this produces "good" Java I don't even know.

Also, I really believe that C++ is the 21st-century COBOL. Java was gunning for that distinction, but Scala and Clojure gave it an assembly-like status, as the lowest-level language on the JVM (which will remain important for at least 15 years because of Scala and Clojure).

Re: Haskell's effect on my C++ : exploit the type system

#29
post #21

int a = f(); if (a I believe the latter will generally result in 2 calls to f() (unless it returns less than zero), which could cause undesired behavior or just be inefficient. Of course, it depends on what f() does. Assuming MAX(0,f()) expands to something like this: if( f()

It was a poor choice on the part of the author to use the macro-looking MAX() in his example. There is in fact a standard max() function in the header that does not suffer from silly macro-expansion problems: template const T& max(const T& a, const T& b) { return a const T& max(const T& a, const T& b, Predicate p) { return p(a, b) ? b : a; } And your definition of MAX() is wrong, not just because of multiple evaluati…

The problem is a loss of verbosity. The next person looking at the code isn't necessarily going to know how MAX is defined, and saving 1 line of code isn't worth making it less clear.

That said, for me, your code would be clear, as not being in all caps, I would assume it's a function and therefore doesn't have the same weakness.

As someone else pointed out, there's no way you can look at MAX(0,f()) and know that it's enforced that f() is only used once within the macro.

Re: Haskell's effect on my C++ : exploit the type system

#30
post #27

Earlier quoted context omitted.

Technically, the code is wrong only if f() is not pure.

Yes, I know, but there is no way to enforce it. This a classic "noob" mistake with macros - using a macro argument more than once.

That's why in C++ people seem to generally recommend inline functions instead. Not only do the arguments only get evaluated once, but the whole thing is type safe too.

Of course, people still misuse macros.

Post reply on HN