It’s funny. My favourites SQLite library actually does it as I suggested :)
https://github.com/groue/GRDB.swift/blob/master/GRDB/Core/DatabaseValue.swift > On 20 Feb 2017, at 00:34, David Hart <da...@hartbit.com> wrote: > >> >> 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