Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I am still scratching my head why the 'some' keyword is needed/required for opaque types.

Eg. SquareButton and RoundButton are implementations of the Button (protocol).

You want to create a function that returns the button, but you don't want to specify to the user exactly what type of button is it (as it doesn't matter). Your function could just declare the top level protocol as the return type without needed to specify the word "some"

createPlayButton -> Button

instead of createPlayButton -> some Button

Am I missing something? It feels like the 'some' keyword is just there to help the compiler and not the users necessary

it seems like the equivalent of id <MyProtocol> in Objective-C. Basically just a surface re-arranging of names, but keeping the same concepts as in Objective-C

I feel Golang did better in this regards... (eg. not necessary distinguishing between protocols and super class-es, it is quacks like a duck, it is a duck)



The difference is subtle but it's there.

The "some" keyword indicates that the function returns a specific type, even if that type isn't known to the caller.

One place where this is meaningful is if you have to use the result of that function in a generic function. For instance if my functions are defined like this:

    func createPlayButton() -> Button { ... }

    func doSomething<T: Button>(_ button: T) { ... }
And I try to call this:

    doSomething(createPlayButton())
I will get an error, because the protocol Button does not conform to itself. However If I use opaque types:

    func createPlayButton() -> some Button { ... }
this works just fine because the compiler is able to determine the concrete type returned by `createPlayButton`


Why doesn't a protocol conform to itself?


In many cases it doesn't make sense. For instance, what if your protocol contains a static member?

    protocol P {
        static var x: Int { get }
    }
Here `let x = P.x` doesn't make any sense, because it's only the type implementing the protocol which has that member. However this would be possible:

    func f() -> some P { ... }
    let p = f()
    let x = type(of:p).x
because in this case p has a concrete type, we just don't know what it is.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: