3

I want to use them as a parameter to a method of my Region struct:

private func combineWith(region: RegionProtocol, combine: (Bool, Bool) -> Bool) -> Region {
    return Region() {point in
        combine(self.contains(point), region.contains(point))
    }
}

But apparently, (Bool, Bool) -> Bool) is not what && or || are. If you know, please let me know how you found out.

1 Answers1

2

If you "cmd-click" on the word "Swift" in the statement

import Swift

in Xcode and search for || then you'll find that it is declared as

func ||<T : BooleanType>(lhs: T, rhs: @autoclosure () -> Bool) -> Bool

The reason is the "short-circuiting" behaviour of the || operator: If the first operand is true, then the second operand must not be evaluated at all.

So you have to declare the parameter as

combine: (Bool, @autoclosure () -> Bool) -> Bool

Example:

func combineWith(a : Bool, b : Bool, combine: (Bool, @autoclosure () -> Bool) -> Bool) -> Bool {
    return combine(a, b)
}

let result = combineWith(false, true, ||)
println(result)

Note: I tested this with Xcode 6.1.1. The syntax for autoclosure parameters changed in Swift 1.2 (Xcode 6.3) and I haven't been able yet to translate the above code for Swift 1.2 (see also Rob's comments below).

The only thing that I can offer at the moment are extremely ugly workarounds. You could wrap || into a closure that does not have autoclosure parameters:

func combineWith(a : Bool, b : Bool, combine: (Bool, () -> Bool) -> Bool) -> Bool {
    return combine(a, { b })
}

let result = combineWith(false, true, { $0 || $1() } )

Or you go without the short-circuiting behaviour:

func combineWith(a : Bool, b : Bool, combine: (Bool, Bool) -> Bool) -> Bool {
    return combine(a, b)
}

let result = combineWith(false, true, { $0 || $1 } )
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • This really does seem obviously the answer (except that you can't put `@autoclosure` in the type like that). But it doesn't seem to actually work. Try it: `func f(b: (Bool, () -> Bool) -> Bool) {}; f(&&)`. Not sure why yet. – Rob Napier Feb 21 '15 at 17:01
  • @RobNapier: I tried it with Xcode 6.1.1 and it worked. I think that syntax of autoclosure parameters changed with Xcode 6.3, which version did you use? – Martin R Feb 21 '15 at 17:04
  • I'm running 6.3; if I put @autoclosure in, it complains that it can only be used with declarations, not types. If I leave it out, it complains that the types don't match. (It's possible this is a bug in 6.3.) – Rob Napier Feb 21 '15 at 17:05
  • 3
    I am thinking this is a bug; posted to devforums. https://devforums.apple.com/message/1105641#1105641 – Rob Napier Feb 21 '15 at 17:15