[Discussion] Type for matching a closure


(Charlie Monroe) #1

AFAIK there isn't currently a way of matching if an Any instance is a closure:

func something<T>(x: T) -> String {
    /// is x a function? We want to support Any (Int, Int32, Float, Double,
    /// AnyObject, ...), but disallow functions.
    ...
}

let myClosure = { print("Hello") }
something(myClosure) // Don't allow this.

I propose adding a protocol Function - all closures would conform to it. See the code on

https://gist.github.com/charlieMonroe/655f2b5e25cc0b4ba06c0ddafa41c73b

which outlines the API and possible usage of it:

- Allowing to match a function from an Any instance.
- Inspect the function object - arguments, captured values, return type. This may help debugging retain cycles by printing the catputred variables - you will be able to see `self` within these.
- Invocation - creating something as NSInvocation, since you'd be able to call the function with a list of arguments.
- This could also become a basis for some RPC in Swift.

I know this is partially something for the Reflection discussion going on here as well as something for the existentials, but since it kind of overlapses both discussions, I thought creating a new thread would perhaps be beneficial.

Charlie


(Haravikk) #2

I’m a +1 for being able to detect them, a protocol would also be useful for defining methods and such on them in future.

I’m curious why you’re hoping to deny functions in your example though; there’s nothing you can really do with T without testing/casting it, in which case a default case or branch will allow functions to either fall through or throw some kind of unknown type error, e.g-

func something<T>(x:T) -> String {
    switch (x) {
        case is Int32:
            return "Int32"
        case is AnyObject:
            return "AnyObject"
        default:
            fatalError("Unexpected type")
    }
}

But yeah, either way, being able to specifically detect or require functions/closures would be nice.

···

On 31 May 2016, at 11:12, Charlie Monroe via swift-evolution <swift-evolution@swift.org> wrote:

AFAIK there isn't currently a way of matching if an Any instance is a closure:

func something<T>(x: T) -> String {
    /// is x a function? We want to support Any (Int, Int32, Float, Double,
    /// AnyObject, ...), but disallow functions.
    ...
}

let myClosure = { print("Hello") }
something(myClosure) // Don't allow this.

I propose adding a protocol Function - all closures would conform to it. See the code on

https://gist.github.com/charlieMonroe/655f2b5e25cc0b4ba06c0ddafa41c73b

which outlines the API and possible usage of it:

- Allowing to match a function from an Any instance.
- Inspect the function object - arguments, captured values, return type. This may help debugging retain cycles by printing the catputred variables - you will be able to see `self` within these.
- Invocation - creating something as NSInvocation, since you'd be able to call the function with a list of arguments.
- This could also become a basis for some RPC in Swift.

I know this is partially something for the Reflection discussion going on here as well as something for the existentials, but since it kind of overlapses both discussions, I thought creating a new thread would perhaps be beneficial.

Charlie

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Vladimir) #3

+1, I also think we need a special protocol for function/closure.

···

On 31.05.2016 13:12, Charlie Monroe via swift-evolution wrote:

AFAIK there isn't currently a way of matching if an Any instance is a closure:

funcsomething<T>(x: T) -> String{
    /// is x a function? We want to support Any (Int, Int32, Float, Double,
    /// AnyObject, ...), but disallow functions.
    ...
}

letmyClosure = { print("Hello") }
something(myClosure) // Don't allow this.

I propose adding a protocol Function - all closures would conform to it.
See the code on

https://gist.github.com/charlieMonroe/655f2b5e25cc0b4ba06c0ddafa41c73b

which outlines the API and possible usage of it:

- Allowing to match a function from an Any instance.
- Inspect the function object - arguments, captured values, return type.
This may help debugging retain cycles by printing the catputred variables -
you will be able to see `self` within these.
- Invocation - creating something as NSInvocation, since you'd be able to
call the function with a list of arguments.
- This could also become a basis for some RPC in Swift.

I know this is partially something for the Reflection discussion going on
here as well as something for the existentials, but since it kind of
overlapses both discussions, I thought creating a new thread would perhaps
be beneficial.

Charlie

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(L Mihalkovic) #4

This looks more like a reflection api than like strictly speaking conformance.

But following along, by analogy, to the executeWithArgs, there should be a way to discover the structure of types on AnyClass.

At this point, it is not the road swift has travelled. Right now they opted for Mirrors to expose the structure of subjects.. all except the functions&closures. At this point Mirrors miss this discoverability, but doing what you propose would make things even more lobsided by having 2 unfinished parts of the language. So I think they don't quite belong today. But runtime reflection goes quite deep in the runtime.

···

On May 31, 2016, at 2:07 PM, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

I’m a +1 for being able to detect them, a protocol would also be useful for defining methods and such on them in future.

I’m curious why you’re hoping to deny functions in your example though; there’s nothing you can really do with T without testing/casting it, in which case a default case or branch will allow functions to either fall through or throw some kind of unknown type error, e.g-

func something<T>(x:T) -> String {
    switch (x) {
        case is Int32:
            return "Int32"
        case is AnyObject:
            return "AnyObject"
        default:
            fatalError("Unexpected type")
    }
}

But yeah, either way, being able to specifically detect or require functions/closures would be nice.

On 31 May 2016, at 11:12, Charlie Monroe via swift-evolution <swift-evolution@swift.org> wrote:

AFAIK there isn't currently a way of matching if an Any instance is a closure:

func something<T>(x: T) -> String {
    /// is x a function? We want to support Any (Int, Int32, Float, Double,
    /// AnyObject, ...), but disallow functions.
    ...
}

let myClosure = { print("Hello") }
something(myClosure) // Don't allow this.

I propose adding a protocol Function - all closures would conform to it. See the code on

https://gist.github.com/charlieMonroe/655f2b5e25cc0b4ba06c0ddafa41c73b

which outlines the API and possible usage of it:

- Allowing to match a function from an Any instance.
- Inspect the function object - arguments, captured values, return type. This may help debugging retain cycles by printing the catputred variables - you will be able to see `self` within these.
- Invocation - creating something as NSInvocation, since you'd be able to call the function with a list of arguments.
- This could also become a basis for some RPC in Swift.

I know this is partially something for the Reflection discussion going on here as well as something for the existentials, but since it kind of overlapses both discussions, I thought creating a new thread would perhaps be beneficial.

Charlie

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution