user1040049 user1040049 - 1 month ago 16
Swift Question

Further details between closure properties and functions

This question acknowledges other seemingly similar questions... but is asking for further details.

Fact: Functions are closures: (sources: Swift: Difference between closure, completion handler and function? and What is the difference between functions and closures?).

Belief: The nuances lie mainly in: 1) having a name; 2) having captured variables;

struct Sample1 {
static func even(_ x: Int) -> Bool {
return x % 2 == 0
}
}
struct Sample2 {
static let even: (Int) -> Bool = { (x: Int) in
return x % 2 == 0
}
}
Sample1.even(42) // true
Sample2.even(42) // true



  • Fact: A
    protocol
    could describe either a
    struct
    and/or
    class
    even though they are quite different (i.e. memory semantic) source

  • Conjecture: Since functions and closures are the same, there should be a way to express the similarity between
    Sample1
    and
    Sample2
    (listed above) via a
    protocol
    .

  • Observation: The following code fails:

    protocol Attempt1 { static var even: (Int) -> Bool { get } }
    protocol Attempt2 { static func even(_ x: Int) -> Bool }

  • QUESTION: Is there a way to write a
    protocol
    which describes both
    Sample1
    and
    Sample2
    ?

  • Conjecture:
    Sample2
    's closure does not capture any variable (
    x
    is locally defined), and so is essentially a
    func
    (because it can be referred to by the property's name).

  • QUESTION: For the above scenario, barring any human expressiveness, is one option technically better (once compiled)?






Edit for clarity:

code 1:

protocol Foo {
static func even(_ x: Int) -> Bool
}
struct Sample1: Foo {
static func even(_ x: Int) -> Bool {
return x % 2 == 0
}
}
struct Sample2: Foo {
static let even: (Int) -> Bool = { (x: Int) in
return x % 2 == 0
}
}
// Sample2 doesn't conform to Foo


code 2:

protocol Foo {
static let even: (Int) -> Bool { get }
}
struct Sample1: Foo {
static func even(_ x: Int) -> Bool {
return x % 2 == 0
}
}
struct Sample2: Foo {
static let even: (Int) -> Bool = { (x: Int) in
return x % 2 == 0
}
}
// Sample1 doesn't conform to Foo


Q: Since functions are closures.. why can't I have single protocol refer to both of them?!

Answer

I'm unable to understand your question because I don't see the sense in which "the following code fails". You seem merely not to know the syntax for writing a protocol. This is legal:

protocol Attempt1 { static var even: (Int) -> Bool { get } }
protocol Attempt2 { static func even (_:Int) -> Bool }

And none of that has anything to do with closures or all the rest of the stuff you said, which seems to me just a jumble of unrelated terms.

Q: Since functions are closures.. why can't I have single protocol refer to both of them?!

Again, this has nothing to do with a function vs. a closure. It has to do with the fact that variables are not functions. This protocol:

protocol Foo {
    static func even(_ x: Int) -> Bool
}

...requires that its adopter declare a static (or class) function. This protocol:

protocol Foo {
    static let even: (Int) -> Bool { get }
}

...requires that its adopter declare a static variable. It's as simple as that. The type of the variable / function is not in question — by which I mean, the mere fact that the type of the variable is the same as the signature of the function does not in some mysterious way turn a variable into a function.