Live data from Hacker News

Destroy All Ifs – A Perspective from Functional Programming

degoes.net

11–20 of 226 posts

Re: Destroy All Ifs – A Perspective from Functional Programming

#11
post #6

The idea that each type has its own control flow primitives is bothersome. It's taken over Rust: argv.nth(1) .ok_or("Please give at least one argument".to_owned()) .and_then(|arg| arg.parse:: ().map_err(|err| err.to_string())) .map(|n| 2 * n) I'm waiting for date.if_weekday(|arg| ...) Reading this kind of thing is hard. All those subexpressions are nameless, and usually comment-less. This isn't pure functional progra…

Most of this should be obviated when the ? operator is ready. But until then, there is no primitive for 'work on the type you wrapped in Option, short-circuiting and returning None at the first sign of failure', so it has to be done in the library.

If this is an accepted idiom, people will be using it for years to come. Sometimes only to be cool.

With "?" and "try!()", Rust is sort of emulating exceptions in a weird way.

Re: Destroy All Ifs – A Perspective from Functional Programming

#13
post #5

Define true as a lambda taking two lazy values that returns the first, and false as one that returns the second, and you can turn all booleans into lambdas with no increase in code clarity. The straw man in the post - talking about a case-sensitive matcher that selectively called one of two different functions based on a boolean - is indeed trivially converted into calling a single function passed as an argument, but…

>> you want to change the mechanism of comparison (perhaps introduce locale sensitive comparison)

I couldn't agree more, and this is why I think most FP programs are about as intellectual stimulating as `std::min_element`

Re: Destroy All Ifs – A Perspective from Functional Programming

#14
I 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 potential for mistakes.

But I admit I have a hard time with suggesting people prefer a lambda to an IF, or to not ever use an IF. A lambda is, both complexity wise, and performance wise, much heavier than an IF. And isn't is just as bad to abstract conditionals before any abstractions are actually called for?

Re: Destroy All Ifs – A Perspective from Functional Programming

#15

This just seems to obscure the logic. Not unlike how polymorphism can make code flow harder to read, though feel more clever. There is a place for it - like when you're trying to express a set of logic that will be guarded by the same condition, but always at the cost of some complexity. A set of conditionals is probably the most obvious way to express branching.

> A set of conditionals is probably the most obvious way to express branching.

Besides object polymorphism and sets of conditionals, there's also generalized predicate dispatch, but that's probably an overkill for many things.

Re: Destroy All Ifs – A Perspective from Functional Programming

#16
post #5

Define true as a lambda taking two lazy values that returns the first, and false as one that returns the second, and you can turn all booleans into lambdas with no increase in code clarity. The straw man in the post - talking about a case-sensitive matcher that selectively called one of two different functions based on a boolean - is indeed trivially converted into calling a single function passed as an argument, but…

A library can very easily provide, along with the kit components, convenience functions that perform common tasks - like matchCaseInsensitive or whatever. The point I took from the post is that, regardless of how the final public API is presented (and indeed, hopefully it doesn't involve piecing together umpteen bits), the code implementing it can be written by composing simple components rather than unwieldy conditionals.

Re: Destroy All Ifs – A Perspective from Functional Programming

#17
post #5

Define true as a lambda taking two lazy values that returns the first, and false as one that returns the second, and you can turn all booleans into lambdas with no increase in code clarity. The straw man in the post - talking about a case-sensitive matcher that selectively called one of two different functions based on a boolean - is indeed trivially converted into calling a single function passed as an argument, but…

> Define true as a lambda taking two lazy values that returns the first, and false as one that returns the second, and you can turn all booleans into lambdas with no increase in code clarity.

This is trivially true, any datatype can be encoded as a function. The post is not saying that we can pass any type of lambda whatsoever, but that we should pass lambdas that implement the required functionality.

> The straw man in the post - talking about a case-sensitive matcher that selectively called one of two different functions based on a boolean - is indeed trivially converted into calling a single function passed as an argument, but it's hard to say that it's an improvement. Now the knowledge of how the comparison is done is inlined at every call point

If call sites shouldn't choose wich lambda (or boolean) to pass, simply define a new function that always passes the same lambda to the original function, and use it everywhere. (This could also be a good case for partial application.)

Re: Destroy All Ifs – A Perspective from Functional Programming

#18
I recommend Bob Harper's essay on "boolean blindness": https://existentialtype.wordpress.com/2011/03/15/boolean-bli...

An excerpt:

> The problem is computing the bit in the first place. Having done so, you have blinded yourself by reducing the information you have at hand to a bit, and then trying to recover that information later by remembering the provenance of that bit.

Re: Destroy All Ifs – A Perspective from Functional Programming

#19
This whole campaigned is misguided.

"Bad IFs" are a code smell, and they're being scapegoated when the real problems are management demanding that simple hackish prototypes & tests be deployed into production, management that doesn't allow time for refactoring, and poor programmers who think that "bad IFs" are good code.

But the main site also doesn't do any reasonable job of defining what a "Bad IF" even is.

The crux of the matter is that programmers need time to craft the details of a project to avoid or correct technical debt. These sort of reactions just point out one tiny portion of technical debt itself and doesn't solve any fundamental problems at all.

(and yeah, I known I'm ranting against the Anti-IF campaign, not the particular take on the linked site. But this article just seems to parameterize the exact same parameters that are branched on anyway.)

Re: Destroy All Ifs – A Perspective from Functional Programming

#20
This 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 defaultPublishOptions
          IO.puts (A.encode pkg)
    end

Pattern matching is pretty powerful, even going as far to give a dynamic, non-statically types language like Elixir the ability to 'destroy all iffs' too.
Post reply on HN