<div dir="ltr">On Mon, Dec 26, 2016 at 8:47 PM Daniel Leping <<a href="mailto:daniel@crossroadlabs.xyz">daniel@crossroadlabs.xyz</a>> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_msg">Tony,</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">totally agree. The functional approach is great and it definitely is worth being a default way of thinking in Swift.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">From the API perspectives, though, it would still be good to have an overload that accepts a type. Consider it library's syntactic sugar, but still.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Moreover, functional approach is usually quite some complicated for newbies which is not good for the library to be widely used.</div></blockquote><div><br></div><div>Is asking a user to pass an initializer as an argument really more complicated for a newcomer than requiring them to write an empty extension to retroactively conform types they want to use with the factory to a new protocol, though? I'd argue the opposite. Passing the initializer to the factory makes the relationship between the two things very clear; relying on a protocol constraint means that the conformance is applied far away from the factory that requires it. In any case, neither retroactive modeling nor initializers-as-functions is probably a "newbie" concept in Swift so I would find it difficult to imagine that adoption of an API would be harmed by choosing the latter.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">In general I don't think we should be limited in Swift to be _functional only_.</div><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">On Tue, 27 Dec 2016 at 10:09 Tony Allevato <<a href="mailto:tony.allevato@gmail.com" class="gmail_msg" target="_blank">tony.allevato@gmail.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_msg">On Mon, Dec 26, 2016 at 8:35 PM Daniel Leping <<a href="mailto:daniel@crossroadlabs.xyz" class="gmail_msg" target="_blank">daniel@crossroadlabs.xyz</a>> wrote:<br class="gmail_msg"></div><div class="gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_msg">Tony, could you, please, share your approaches? Maybe it will open the door to finding an easy solution to the issue.</div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">...and I'll tell you what it is since I fat-fingered the send button too soon. :)</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">There have been a couple times where I've written code that needed to generically serve instances of a type T, and in each of those cases—thanks to Swift's support for first-class functions and initializers-as-functions—I found it to be cleaner to have my factory take a () -> T as a parameter and I pass T.init into that, rather than place constraints on T itself.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">This approach doesn't require imposing *any* additional constraints on T. Even though it's trivial to use an extension to add conformance like DefaultConstructible to many existing types, the latter approach excludes any type that does not make sense to have a default initializer, or where the default initializer isn't what you want to use. Maybe you want to have your factory use a static method to create the objects of a certain type instead: passing the function reference lets you do that. The function can even be a closure that captures outer context, letting your factory work for types that need additional parameters passed to the creation method.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">In general, I think talking about factories as "a thing that needs to call a specific initializer on a type" is a discussion motivated by patterns in other languages that are more restrictive than Swift. If you think of a factory instead as "something you can call that returns a T", the functional approach is *much* more powerful and general.</div></div></div><div class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">On Tue, 27 Dec 2016 at 10:02 Tony Allevato <<a href="mailto:tony.allevato@gmail.com" class="gmail_msg" target="_blank">tony.allevato@gmail.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">On Mon, Dec 26, 2016 at 8:31 PM Daniel Leping via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_msg">Braeden, a good point as for inheritance. Totally agree here.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Though the generic factory problem remains. Maybe it could be solved differently? Any ideas?</div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">As a matter of fact, I've used a different approach in some of my own projects that has ended up working out well.</div></div></div><div class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">The only thing that pops up in mind right now is to have some "compiler magic" that deals with the constraints. Maybe a concrete class can fall into the category (be DefaultConstructable).</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Anyways, my point is that compile time constraints for a type that can be created with a default constructor are important for certain patterns. I'm not saying the protocol is the right or the only way, but I want to find a solution.</div><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">On Tue, 27 Dec 2016 at 5:22 Braeden Profile via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">I’m gonna do my best to explain my thoughts on this, as I just spent an hour reading the whole thread…………<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I’m -1 on adding the protocol DefaultConstructible to the standard library (especially under that name). It doesn’t explain its semantics effectively. I agree that a protocol should have definite semantics that are hopefully explained by the name. This protocol fails that test—a default instance of value types is completely context-specific, and default class instances are just iffy to me.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I’m firmly in the camp that you could create a protocol like this for your own project and apply it to the types you think semantically fit the purpose…</div><div class="gmail_msg"><span class="m_6760345133789631045m_-5120392299815025053m_-3768429038021220633m_2401379044161755966m_4771876137164557897m_-4371823811555265644Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>protocol ZeroConstructible { init() }</div><div class="gmail_msg"><span class="m_6760345133789631045m_-5120392299815025053m_-3768429038021220633m_2401379044161755966m_4771876137164557897m_-4371823811555265644Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>extension Int: ZeroConstructible { }</div><div class="gmail_msg">…but I wouldn’t do this myself, as there are too many use-cases with too many definitions of “default”. What if I wanted Int to conform to multiple? It only can have one init(). I’d do something like this…</div><div class="gmail_msg"><span class="m_6760345133789631045m_-5120392299815025053m_-3768429038021220633m_2401379044161755966m_4771876137164557897m_-4371823811555265644Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>protocol ZeroConstructible { static func constructZero() }</div><div class="gmail_msg"><span class="m_6760345133789631045m_-5120392299815025053m_-3768429038021220633m_2401379044161755966m_4771876137164557897m_-4371823811555265644Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>protocol UnsafeConstructible { static func constructUnsafe() }</div><div class="gmail_msg"><span class="m_6760345133789631045m_-5120392299815025053m_-3768429038021220633m_2401379044161755966m_4771876137164557897m_-4371823811555265644Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>protocol FactoryConstructible { static func constructDefault() } // I’ve never needed to use a factory, myself...</div><div class="gmail_msg">…and create those new functions when I conform my types to it. It’s cumbersome, but correct. As of yet, I’ve never needed to do such a thing, and nearly all the use-cases brought up in the thread can be solved with something of the like.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Every “default" is context-dependant.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Addressing other parts of the thread:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><ul class="m_6760345133789631045m_-5120392299815025053m_-3768429038021220633m_2401379044161755966m_4771876137164557897m_-4371823811555265644MailOutline gmail_msg"><li class="gmail_msg">I read a new name suggested for the protocol: “Identity”. Unfortunately, I associate that with the proposed protocol HasIdentity { func === }, not a mathematical identity.</li><li class="gmail_msg">DefaultConstructible could never be a normal protocol that magically gets applied where init() exists. protocol required inits are just that—`required`. If a superclass conforms to DefaultConstructible, every subclass must, too! This would give most every class tree the infinite chain of `init()` that NSObject suffers from.</li><li class="gmail_msg">AnyObject was used to justify compiler magic that could be applied for DefaultConstructible. I disagree that this is appropriate, as AnyObject most certainly implies semantics. Every AnyObject is a class, with reference semantics, unsafe-weak-strong references, and more. I could not see definite semantics evolve for DefaultConstructible throughout the whole discussion.</li></ul><div class="gmail_msg"><br class="gmail_msg"></div></div><div class="gmail_msg">That’s my two cents. Granted, no one would be hurt by its addition except those who try to understand this protocol, but I want to avoid that chaos.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div></div>_______________________________________________<br class="gmail_msg"><br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"><br class="gmail_msg"></blockquote></div></div><br class="gmail_msg"><br class="gmail_msg">_______________________________________________<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"></blockquote></div></div></blockquote></div></div><br class="gmail_msg"><br class="gmail_msg"></blockquote></div></div></blockquote></div></div>
</blockquote></div></div>