> On 20 Feb 2017, at 00:15, Brent Royal-Gordon via swift-evolution > <swift-evolution@swift.org> wrote: > >> On Feb 18, 2017, at 10:58 PM, David Waite via swift-evolution >> <swift-evolution@swift.org> wrote: >> >> 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? > > Strong coupling is sometimes inevitable. > > In a previous thread, I brought up an example of a place I would use this > feature: Wrapping the SQLite APIs. For instance: > > public protocol SQLiteValue { > init(statement: SQLiteStatement, columnAt index: Int) throws > func bind(to statement: SQLiteStatement, at index: Int) throws > } > extension Int: SQLiteValue { > public init(statement: SQLiteStatement, columnAt index: Int) > throws { > self = sqlite3_column_int(statement.stmt, index) > } > public func bind(to statement: SQLiteStatement, at index: Int) > throws { > try throwIfNotOK( > sqlite3_bind_int64(statement.stmt, index, self) > ) > } > } > extension Double: SQLiteValue {…} > extension Data: SQLiteValue {…} > extension String: SQLiteValue {…} > extension Optional: SQLiteValue where Wrapped: SQLiteValue {…}
That problem is that I don’t think the API should be written this way. This cries for the use of enums instead: enum SQLiteValue { case int(Int) case double(Double) case data(Data) case string(String) } protocol SQLiteValueConvertible { var sqliteValue: SQLiteValue { get } } extension Int : SQLiteValueConvertible { var sqliteValue: SQLiteValue { return .int(self) } } And that API actually allows interesting extension points. For example, how about automatic binding of dates: extension Date : SQLiteValueConvertible { var sqliteValue: SQLiteValue { return .double(timeIntervalSince1970) } } I keep getting the impression that the uses for the proposals are actually cases where an enum is required. > This is a case of your hated "strong implementation coupling". But the > coupling is to a library that ultimately writes data to disk in a portable > format. Strong coupling here is inevitable. > > What is the purpose of permitting outside conformances to `SQLiteValue`? > There is no useful way to conform to `SQLiteValue`; the underlying library > supports certain types, and I'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't > exposed. > > 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'm stuck. *For an API I > don't intend anyone to conform to publicly in the first place.* That kind of > sucks, doesn't it? > > -- > Brent Royal-Gordon > Architechies > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution