<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Feb 19, 2017 at 5:15 PM, Brent Royal-Gordon via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">&gt; On Feb 18, 2017, at 10:58 PM, David Waite via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt; I am unsure if this feature is a good idea. Does someone have a real-world use for this which isn’t just hiding strong implementation coupling behind a protocol?<br>
<br>
</span>Strong coupling is sometimes inevitable.<br>
<br>
In a previous thread, I brought up an example of a place I would use this feature: Wrapping the SQLite APIs. For instance:<br>
<br>
        public protocol SQLiteValue {<br>
                init(statement: SQLiteStatement, columnAt index: Int) throws<br>
                func bind(to statement: SQLiteStatement, at index: Int) throws<br>
        }<br>
        extension Int: SQLiteValue {<br>
                public init(statement: SQLiteStatement, columnAt index: Int) throws {<br>
                        self = sqlite3_column_int(statement.<wbr>stmt, index)<br>
                }<br>
                public func bind(to statement: SQLiteStatement, at index: Int) throws {<br>
                        try throwIfNotOK(<br>
                                sqlite3_bind_int64(statement.<wbr>stmt, index, self)<br>
                        )<br>
                }<br>
        }<br>
        extension Double: SQLiteValue {…}<br>
        extension Data: SQLiteValue {…}<br>
        extension String: SQLiteValue {…}<br>
        extension Optional: SQLiteValue where Wrapped: SQLiteValue {…}<br>
<br>
This is a case of your hated &quot;strong implementation coupling&quot;. But the coupling is to a library that ultimately writes data to disk in a portable format. Strong coupling here is inevitable.<br>
<br>
What is the purpose of permitting outside conformances to `SQLiteValue`?</blockquote><div><br></div><div>Suppose you released this library and I used it for my SQLite needs. But my application uses Float behind the scenes, which can be losslessly promoted (as you must know) as Double. For convenience of interfacing with your library, I conform Float to SQLiteValue. Likewise, let&#39;s say I implement a new Rational type (not actually hypothetical, hehe), and I decide that I want to store that as Double (it&#39;d be precise enough once all the calculations are done). For convenience, I conform Rational&lt;Int&gt; to SQLiteValue. I could make good on these conformances by having `init()` and `bind(to:at:)` do a numeric cast and then forward to the relevant methods on Double. Now, I understand why your library wouldn&#39;t do this, since willy-nilly conversions between types are worth at least careful thought, but as a non-library client that uses Float pervasively, I&#39;d have good justification for that extension.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">There is no useful way to conform to `SQLiteValue`; the underlying library supports certain types, and I&#39;ve implemented support for those types. Allowing outside conformances can only mislead people into fruitlessly trying to conform their types, not realizing that the calls they need simply aren&#39;t exposed.<br></blockquote><div><br></div><div>What is the harm of permitting an outside conformance to `SQLiteValue`?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Moreover, exposing these details unnecessarily freezes the design of `SQLiteValue`. If I want to change the design of this parameter handling in a future version, well, too bad, the API is public, I&#39;m stuck. *For an API I don&#39;t intend anyone to conform to publicly in the first place.* That kind of sucks, doesn&#39;t it?<br></blockquote><div><br></div><div>But with `public` vs `open`, your API is still frozen whichever you choose. Even if you can&#39;t conform to `SQLiteValue`, there is no guarantee that your clients won&#39;t _invoke_ `SQLiteValue.bind(to:at:)`, so you can&#39;t redesign the protocol anyway. What other flexibility are you looking for?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Brent Royal-Gordon<br>
Architechies<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</div></div></blockquote></div><br></div></div>