Feature request: Add ability to mark closures as "Functional"

I filed this as rdar://21468140 but I would like to open this up for discussion. I'm probably not the first person to think of this too.


[Swift] Add ability to mark closures as "Functional"


Summary:

It would be nice to be able to mark functions (and generally any closure) as functional. That is having no side effects outside of their scope. I believe Haskell has a similar language feature.


Here's a first stab at how this feature would work:


class foo {
    var bar = "Hello"

    @functional
    func baz() -> Int {
        bar = "world"
        return 42
    }
}


Trying to compile the above code would result in a compile time error along the lines of "baz() is a functional closure and cannot have side effects" on the line where bar is reassigned to "world"

So what usage would this bring? Sorry I never dived into the functional programming fad so I may be hard on uptake, but I fail to see any improvement this would be.

There are times where you may want to make sure that a function has no side effects. For me currently I'm writing threadsafe code and it would be great if the compiler could verify for me that the code I'm writing doesn't mutate any shared state.

Just to know: You need use a class? Because Strucs are threadsafe and has compiler checks to mutability.


Sometimes value types programing is the answer.

Hmm looks like i need to watch the "Building Better Apps with Value Types in Swift" WWDC session... Thanks!


That being said, a class may still be needed for Obj-C interop... not sure.

Is the existing noescape attribute related to what you're asking for?

@noescape specifies a lifetime for the closure itself but it doesn't prevent the closure from mutating the state of its parameters or any global state.

If you used a struct, the compiler would warn you about mutating the struct itself, but if the closure had side effects outside of that, you wouldn't be warned.


struct Mutant {
  let mutate: () -> ()                  
}
var i = 0
let mutClos = { print(++i) }
let wolverine = Mutant(mutate: mutClos) 
print(i)            // 0 
wolverine.mutate()
print(i)            // 1

+1 for interesting topic. I'm generally for making things more explicit, at the cost of some extra typing. Seems swift is going in this general direction already.


Probably something other than `functional` though, even do I appreciate the continued inception 🙂

Yeah, I like this idea too. It seems like a suitably Swift safety feature, to be able to prefix a function with something that tells the compiler to check whether anything in the function - or any of the functions called in the function, and so on recurseively(do I understand this right?) - does anything to change a state.


The trick is... suppose we have a "functional" function A which accesses a property B of an object of class C but doesn't change it. All well and good. But then suppose we create D, a subclass of C, which differs only in that it counts how often property B is accessed. Now A isn't "functional", because there's a side-effect. Where would you put the error message?

There are actually two related concepts. One is what you describe, that the function doesn't affect the state of the program. The other is that the function isn't affected by the state of the program. The latter concept is important when automatically caching results, and in general when reasoning about the program.

I agree with this, but believe it would be even better to be hopeful for the future: I dream of a day when @functional is the norm, and therefore what should require marking is functions which _do_ have side effects outside of their scope, not functions which do not have such side effects.


@sideeffects - looks a little weird, though

@nonfunctional - probably could be misinterpreted to mean the function doesn't do anything, or does it incorrectly

**** no, there is nothing more annoying as a pure functional language. Side effects are important in many cases. After all, we live in a statefull world.

DressTheMonkey didn't suggest that side-effects should be disallowed, only that they should be explicitly marked. There are definitely advantages with languages like Erlang or Clojure where state is explicitly handled, using inter-process communication in Erlang and transactions in Clojure.

It is? Then why are both languages unused outside of academica? What good would it bring to make the standard case an exception. Our world and needed programming is heavyly statefull. Who says the functional paradigma would be better is living in a ivory tower.

I think this is a great idea. Its not going to prevent anyone from writing whatever they want in a function, including side-effects, but what it would do is clarify to a caller that the function does or does not cause side-effects. This can only be a good thing!


Personally I would prefer a clause on the definition, instead of an attribute,


eg. func f() -> x no side-effects {}


rdar://21477374

Feature request: Add ability to mark closures as "Functional"
 
 
Q