<div dir="ltr">On Mon, Dec 26, 2016 at 8:47 PM Daniel Leping &lt;<a href="mailto:daniel@crossroadlabs.xyz">daniel@crossroadlabs.xyz</a>&gt; 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&#39;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&#39;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 &quot;newbie&quot; 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&#39;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 &lt;<a href="mailto:tony.allevato@gmail.com" class="gmail_msg" target="_blank">tony.allevato@gmail.com</a>&gt; 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 &lt;<a href="mailto:daniel@crossroadlabs.xyz" class="gmail_msg" target="_blank">daniel@crossroadlabs.xyz</a>&gt; 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&#39;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&#39;ve written code that needed to generically serve instances of a type T, and in each of those cases—thanks to Swift&#39;s support for first-class functions and initializers-as-functions—I found it to be cleaner to have my factory take a () -&gt; 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&#39;t require imposing *any* additional constraints on T. Even though it&#39;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&#39;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 &quot;a thing that needs to call a specific initializer on a type&quot; is a discussion motivated by patterns in other languages that are more restrictive than Swift. If you think of a factory instead as &quot;something you can call that returns a T&quot;, 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 &lt;<a href="mailto:tony.allevato@gmail.com" class="gmail_msg" target="_blank">tony.allevato@gmail.com</a>&gt; 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 &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; 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&#39;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 &quot;compiler magic&quot; 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&#39;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 &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; 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&quot; 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>