2

I'm curious, is there a pre-existing protocol whose only requirement is that there be an init with no arguments? I'm creating a generic that needs to be able to initialize an associated type without worrying about any arguments. This seems to call for a protocol like this:

protocol HasEmptyInitializer {
    init()
}

It seems like a pretty basic protocol that might be needed in many contexts. Before I go polluting my protocol space with the above, I was wondering if there is anything like that already in Foundation or other 1st party library. Does anyone know of such a thing?

Curious Jorge
  • 354
  • 1
  • 9
  • Hmm… it seems odd that this would be a requirement of a protocol. What would you want it for? Like… what is the context in which you would be using it? – Fogmeister Feb 05 '23 at 23:39
  • Sure you can do this is if it makes sense for your use case. I don't think there's any built-in protocol for that, as such `init` is quite rare as a protocol requirement – timbre timbre Feb 05 '23 at 23:51
  • 5
    This is a very famous non-protocol because it lacks semantics. For the background on why this is intentionally not a protocol in Swift, see https://oleb.net/blog/2016/12/protocols-have-semantics/ If you have a semantically meaningful protocol that only has this requirement, then there is no problem creating it, but it is quite rare. – Rob Napier Feb 06 '23 at 00:47
  • 2
    For the problem you describe, it usually makes more sense to pass an constructor (a function that returns a new instance) rather than use a protocol. That's much more powerful, since you can then pass an arbitrary closure and support types regardless of their `init` requirements. – Rob Napier Feb 06 '23 at 00:53
  • 1
    Thanks @RobNapier, that's a great link. I'll re-architect things to use an optional, though there are different issues to solve there. Question (no ingratitude implied): why do stackoverflowers prefer to use comments instead of the answer mechanism? I would like Future Me to be able to find a ranked answer to this question. Would you consider reposting as an answer? – Curious Jorge Feb 06 '23 at 01:30
  • 2
    @CuriousJorge There could be different reasons, but personally, I comment a lot of maybe-answers because I'm not yet sure if it solves OP's problem. Lots of new users get a really negative impression when their "How do I do this?" questions (particularly [XY problems](https://en.wikipedia.org/wiki/XY_problem)) get met with "you shouldn't, and here's why ...". It's actually the best thing to do, but it helps if you first check in with OP that they understand why you're suggesting an alternative approach, and make sure it actually works for their case – Alexander Feb 06 '23 at 02:15
  • 1
    Same. I'm always uncomfortable giving a "definitive answer" (which is what SO wants answers to be) when the answer is "you probably shouldn't do that." It's not the answer the asker was really looking for. I don't know if this is true on all tags, but conversations among the regulars in comments is really common in the Apple tags. It does break the site a little bit, and I've tried to more often just add it as an answer (often deleting comments and making them answers), but I hesitate even more when others have already weighed in. – Rob Napier Feb 06 '23 at 02:43
  • (Also, link-only answers are frowned on, so it's more work to write a real answer, and sometimes I'm in a hurry :D. In this case it really feels like this must be a duplicate, but I can't find it, and it's bad form to answer questions that are duplicates rather than duping them, so I really should search more but I'm going to bed now. There are a lot of rules about what you're supposed to do that I get to ignore if I just make a quick comment that answers the question.... I'm not always a good SO'er.) – Rob Napier Feb 06 '23 at 02:48
  • Thanks to both of you for your responses! I would say, why worry about definitive correctness of answer or comprehension of asker situation? :-) Let the system take care of that. If you're mistaken, it will be ignored, unless it's terrible. And even if it's the definitive right answer today, that's not something to be too focused on, as something tomorrow may make a new answer more correct, and the SO voting system should, in theory, take care of that. – Curious Jorge Feb 06 '23 at 02:53
  • @Alexander that was my thinking behind asking for more context hopefully it's resolved now. – Fogmeister Feb 06 '23 at 12:02
  • You clearly get it @CuriousJorge, but a lot of new comers don’t. They’ll ask about why their force unwrapping crashes or why you can’t escape a value out of an asynchronous callback closure for the 90th time that day, and get upset when you deduplicate their question against an exact match which just uses a different example – Alexander Feb 06 '23 at 13:05

1 Answers1

1

This is a very famous non-protocol because it lacks semantics. For the background on why this is intentionally not a protocol in Swift, see Ole Begemann's writeup Protocols are more than Bags of Syntax. If you have a semantically meaningful protocol that only has this requirement, then there is no problem creating it, but it is quite rare.

The fundamental point of Ole's writeup (which gathers together many other conversations) is that a protocol is more than just "it has this method" (i.e. syntax). It's about what kinds of algorithms it facilitates. "Plusable" wouldn't be a good protocol to cover "things you can apply + to." What + means for Ints is not really the same as what + means for Collections (the latter isn't even commutative). Similarly, "makable by calling init()" tells you nothing about what the resulting object means. Is is "empty?" Some unspecified "default" value? Invalid? The semantics of protocols matter more than the syntax.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thanks very much! After reading the blog post, I see that a) there probably isn't a 1st party protocol (eg `DefaultConstructible` in the post) like the one I'm searching for; and b) in my situation, optionals are a better solution to by needs. – Curious Jorge Feb 06 '23 at 02:59
  • slight aside: I wonder how many of us violate "This means that if you write a Person struct with firstName and lastName properties and in your implementation of == you only use firstName to determine equality, you’re violating the contract laid down by the protocol’s semantics" for the convenience of being able to use `==`. I know I do. Will I make different choices in the future? hmmm.... – flanker Feb 06 '23 at 10:16
  • 1
    Exactly! FWIW, it has all worked out in this case. I had been struggling to use optionals with some SwiftUI structures and so I took the easy/pragmatic way out and initialized some data in a StateObject with unused default values, just so I could avoid the optionals. That led me to my question above, which brought me back to "I should really use optionals". So I persevered with solving the problems around that and thanks to the kind people at Stack Overflow, I learned some [new things](https://stackoverflow.com/q/75356738/14840926) and it's all right as rain! – Curious Jorge Feb 06 '23 at 21:39