We need a rethink; stop the @pseudoProtocol madness

Is it just me, or between property wrappers, static callability, and dynamic callability, do we have a lot of things that are like protocols, but can't be implemented as such due to custom naming requirements or something else? Maybe this screams for us adding a meta-protocol concept to Swift and implementing all these near-protocol things in terms of that. Would something like Rust's hygienic macros count?


Can you elaborate why do you see property wrappers as pseudo protocols? Wrappers are concrete types with stored properties. I‘m having hard times making a connection between wrappers and protocols.

I'm not saying that the property wrapper is a protocol relative to type containing the enhanced property, it's the "@propertyWrapper" and other preparations that are like a protocol relative to the wrapper type. You do something similar to types that want to be dynamically callable.

1 Like

Hmm I see, but we use attributes because protocols cannot describe specific semantics that we want.

That's exactly the point of CTMacUser. Maybe instead of using attributes and custom compiler logic each time a protocol can't fit, we may think about a generalised way to do it. (I'm just rephrasing it, I don't know if this is a good or bad idea).


There is no can’t. The design reflects the core team’s decision not to spell these as protocols.

You're sure? The property wrapper author has a note on the limitations of using protocols for his design.

1 Like

Yes, the core team may have choose to keep the protocol syntax, but even using a protocol, you would still have to add special cases in the compiler to handle these protocols in a different way for each of these feature.

I think one of the reasons is that we still cannot write any useful algorithms on this protocol type, if it exists.


A hygienic macro system has been discussed in the past, and I think the idea is still a possibility. However, I'd like to point out that two of the current marking annotations have been called out for deprecation and removal. Someone just needs to move forward with a new proposal to remove them.

1 Like

I love these new features but I think it is an extremely unfortunate development to start introducing a multitude of magic function signatures, like callAsFunction, subscript[keyPath:], all the function builder stuff etc. And removing the attributes makes it downright bewildering..

It makes it much less clear why someone else's code that you are looking at works the way it does, and it makes it less discoverable for you when you make your own types, how would you ever guess that naming your function differently will produce a completely different effect?

I can only hope that the reason that the core team is moving away from the attributes is that they have some some longer term plan in mind that sorts all this out, like a macro system, better xcode integration or something else.

Barring that, I think a nicer approach than magic function names like callAsFunction would be to ADD an attribute at the relevant function definition, and then let you name it however you want:

func arbitrarilyNamedFunction(arg: String) -> Int { ... }

Another disadvantage with unattributed pseudo-protocols is that it's hard to find out more about them, even if a reader of the code suspects that there is something special going on. With normal protocols you can always click on the protocol name and read the documentation or at least the definition, but if there is no attribute there is nothing to click.

In short, there is a reason we don't have this syntax for init's and subscripts:

func init(value: T, otherValue: U) { ... }
func getAsSubscript(arg: T) -> U { ... }

They are functions calls that behave in very special ways, so they have a special syntax and even get different syntax highlighting. This makes it clearer that something special is going on. I haven't seen a compelling reason why this shouldn't apply to the newer features we're discussing here. Has one been given somewhere?


The strengths and weaknesses of the design for the static callable feature was discussed at length during review. It’s not necessary to rehash that here.


Of course it is, that is what this thread is about - the problems with pseudo protocols with magic function names. of which callAsFunction is a recent example.


It's fine to bring-in new argument for/against the design post-review should it weight heavily enough.

It's not exactly beneficial to anyone to just repeat the discussion near-verbatim.

If you think this thread is irrelevant you can flag it, but discussing the precise topic of the thread seems fairly unobjectionable. And when the topic is a trend in the evolution of swift, it is pretty relevant to bring up examples of that trend, and the problems with it.