Earlier quoted context omitted.
The thing is that the tone of the article seems to suggest taking such an extreme: I mean, an "anti-if " campaign? There's like, only one sentence of concession near the end towards those unconvinced by the argument.
FWIW, I'm pretty unimpressed by the anti-if campaign's website. They've clearly put style over substance. It's a beautiful website, but I spent some time poking through it and I can still only guess at what exactly they're on about. It seems to be something about if-statements being bad, but beyond that it's rather a muddle. I'm trying to be charitable, though, so let's assume that the core of their idea is something…
Destroy All Ifs – A Perspective from Functional Programming
171–180 of 226 posts
Re: Destroy All Ifs – A Perspective from Functional Programming
#172Earlier quoted context omitted.
What distinction are you drawing between "first-class functions" and "function pointers"?
About the same distinction as I'd draw between an integer and a pointer to an integer.
In its treatment of expressions, C doesn't draw the distinction between function and pointer to function. When you call printf("foo\n"), the printf part is a primary expression which designates a function, and evaluates to a function pointer. That pointer is then dereferenced by the postfix ().
The main difference between a "first class" function and a function pointer is that a first class function carries an environment, which allows the body of the function to make references to lexically scoped names outside of the function. A function pointer carries a reference to the code only.
Re: Destroy All Ifs – A Perspective from Functional Programming
#173This is the starter code: publish :: Bool -> IO () publish isDryRun = if isDryRun then do _ This would be nicer if you could do multiple functions with pattern matching. In Elixir this would be: @spec publish(boolean) :: any def publish(true = _isDryRun) do _ = unsafePreparePackage dryRunOptions IO.puts "Dry run completed, no errors." end def publish(false = _isDryRun) do pkg = unsafePreparePackage defaultPublishOpti…
Pattern matching is just as explicit as an if loop. In languages that implement it for null values, it is just as explicit as typing "if (foo == null)" in an imperative language. You have to think about it, and type just as much code to deal with it, as you would in a language without pattern matching. The only upside to pattern matching that I can see is that you are forced by the compiler to match all possible inpu…
Re: Destroy All Ifs – A Perspective from Functional Programming
#174Earlier quoted context omitted.
Why create a lambda just to execute it and then discard it?
The problem with the Boolean is rather that people mix up the two values all the time. The lambda also has more type safety. A Boolean is always a Boolean, but the compiler (and in a dynamic language the runtime) can tell you when you are calling your passed functions with the wrong arguments, because you mixed them up.
Re: Destroy All Ifs – A Perspective from Functional Programming
#175Earlier quoted context omitted.
It does. This could have been written .map_err(ToString::to_string) as well. Works just fine with methods.
Why can't it be written as: .map_err(to_string) When using the lambda the type is inferred, so why should there be a need for the ToString?
Re: Destroy All Ifs – A Perspective from Functional Programming
#176I read everything I could find on the Anti-IF site and didn't understand what the mission is exactly. They qualify and mention they want to remove the bad and dangerous IFs, but I couldn't find examples that differentiate between bad ones and good ones -- are there good ones according to this campaign? I like using functional as much as anyone, and removing branching often does make the code clearer and remove the po…
I read everything I could find on the Anti-IF site and didn't understand what the mission is exactly. I have a similar problem, in that every time I try to understand the perspective of functional-programming advocates, I find that the authors always seem to illustrate their points with examples like this: match :: String -> Boolean -> Boolean -> String -> Bool match pattern ignoreCase globalMatch target = ... If I'm…
How many layers above that you want to hide that fact is entirely dependant on you and the requirements of solving there problem.
I have a problem with people assuming 'their' way is there only way, and generally being oblivious about the vast variety of problems the rest of us encounter.
Re: Destroy All Ifs – A Perspective from Functional Programming
#177I'm surprised that the article and none of the comments so far mentioned the "Expression Problem": http://c2.com/cgi/wiki?ExpressionProblem Basically, if you structure the control flow in object oriented style (or church encoding...) then its easy to extend your program with new "classes" but if you want to add a new methods then you must go back and rewrite all your classes. On the other hand, if you use if-statemen…
> I think its because until recently pattern matching and > algebraic data types (a more robust alternative to > switch statements) [...] Could you elaborate a bit on what this accomplishes, eg. pattern matching vs a "case" statement? As I've programmed in Haskell for the past year or two, I've observed exactly this change in my style of writing - that I've started to get rid of "case" statements inside function defi…
* [at least some] compilers will check for exhaustiveness
* "Pattern matching isn't just conditional matching. It's also binding, and even some common operations. "
Re: Destroy All Ifs – A Perspective from Functional Programming
#178Re: Destroy All Ifs – A Perspective from Functional Programming
#179Earlier quoted context omitted.
Scala allows underscores, and sequential underscores refer to the next element, so you can do e.g. list(1, 2, 3, 4).reduce(_ + _) == 10
Doesn't that make the parameter anonymous, though? Can you println that _ and see the value of the current element?
Re: Destroy All Ifs – A Perspective from Functional Programming
#180Earlier quoted context omitted.
The annoying part there is the repeated "|x| x.". Rust should have syntax to reference a method of an object, instead of having to write a wrapper. So it'd look like .map_err(???.to_string()).
It does. This could have been written .map_err(ToString::to_string) as well. Works just fine with methods.