On Sun, Jan 17, 2016 at 3:32 AM, Dave via swift-evolution < swift-evolution@swift.org> wrote:
Instead of adding stuff to the protocol declaration, can we add it to the
object definition?
Right now, IMHO, there’s a bug in the way protocols and functions w/
default parameters interact (or rather, don’t)…
Say I have this protocol (which, BTW, I end up adding to a lot of my
projects for providing default values):
protocol Initable {
init()
}
// Along with most other builtin types I use
extension Int : Initable {}
and this class:
class Variable <T: Initable> {
var value: T
let name: String
init(path: String = __FILE__, line: Int = __LINE__) {
self.value = T()
self.name = getDeclNameFromSource(path: path, line: line)
}
init(_ value: T, path: String = __FILE__, line: Int = __LINE__) {
self.value = value
self.name = getDeclNameFromSource(path: path, line: line)
}
init(name: String, value: T) {
self.value = value
self.name = name
}
}
Now, `Initable` says* that
var x = T() // where T: Initable, of course
is valid code. Do you know what else is valid?
var x = Variable<Int>() // Hooray! Default values!
Yet, despite the fact that, from the API user’s point of view, `Variable`
already has everything it needs to conform to `Initable`, you can’t write
“extension Variable : Initable” without either getting a non-conformance
error or, if you then add init() { fatalError() }, getting an “ambiguous
expression” error wherever you actually try to call Variable(). And this is
the bug: If your protocol `Foo` has a function `foo(X)`, and your type has
a function `foo(Y)` *where Y can be turned into X through the use of
default parameters*, then it’s impossible for your type to conform to
`Foo`, even though you could use it as a `Foo` in your code. In practice, I
think this only matters if you’re using “macros” like __LINE__ or something
as your default parameter, but it’s still annoying (to me, anyway).
I think we might be able to kill two birds with one stone here… What if
protocol conformance had to be declared *and* it was done implicitly for
anything for which there was already a perfect match?
extension Int : Initable {
// Implicitly generated because Int.init() (with no default
parameters) already exists
conformance {
//(protocol_identifier).(requirement_indentifer) = (expression)
Initable.init() = init() // or really any expression that
evaluates to an Int
}
}
Then we could get both your default parameter support (I think) *and* fix
this “bug of non-intuitivity” (which people keep telling me isn’t really a
bug because of what protocols *actually* mean*) simply by being able to
explicitly write it out:
class Variable <T: Initable> : Initable {
// Must be explicitly written, since in this case there’s no literal
match
conformance {
Initable.init() = init(_ value: T, path: String = __FILE__, line:
Int = __LINE__)
}
…
}
In theory, we could also use this for optimizations:
private let _default_int_: Int = 0
extension Int : Initable {
conformance {
Initable.init() = _default_int_ //why bother with a function call
when you could substitute a constant?
}
}
I don’t know how deep into the compiler this “conformance” clause would
have to be carried… The generic specializer would certainly need it, but I
don’t know enough about how that works to say how much this would actually
change anything…
- Dave Sweeris
* Yes, I know that protocol conformance is about the *actual* function
signatures and not just what the compiler can deduce… My point is that,
IMHO, it’s counter-intuitive to be able to get the same “user-level”
signature, but not be able to semantically express that to the compiler.
On Jan 16, 2016, at 03:35, Goffredo Marocchi via swift-evolution < > swift-evolution@swift.org> wrote:
I still think that, except in certain very generic cases, default methods
are something I would be wary of being easily abused.
Protocols, Java style interfaces, they allow users to focus only on a
generic behaviour/contract without having to rely or being able to rely
and/or make bonding assumptions on any implementation details of the type
conforming to the protocol. Default methods in a protocol still seem to go
in the opposite direction although they do offer a lot of convenience and
open up new styles.
Sent from my iPhone
On 16 Jan 2016, at 11:04, Haravikk via swift-evolution < > swift-evolution@swift.org> wrote:
I think that the point of allowing defaults in protocols is so that you
can assume a default for all types conforming to that protocol. To use your
example, if you receive an instance of Name, you can only call
printSomething() without arguments if you test that it is an instance of
type Name. If instead you test its conformance to the Good protocol (which
you might do if there are a lot of different types conforming to Good) then
you have to provide a value, because you can’t infer that every possible
implementation will have a default.
Regarding this proposal however I think it might be useful to have a
distinction between a protocol function that specifies a default value for
all implementations (that they must all conform to) versus one that
specifies that implementations must have a default value, but not what that
value must be.
For example, to have a fixed and altered default we currently we have to
do things like this:
protocol Protocol {
func functionWithSpecificDefault(argument:String)
func functionWithAnyDefault(argument:String)
}
extension Protocol {
func functionWithSpecificDefault() {
self.functionWithSpecificDefault(“Foo”) }
func functionWithAnyDefault() { self.functionWithAnyDefault(“Foo”) }
}
class MyClass : Protocol {
func functionWithSpecificDefault(argument:String) { /* Implementation here
*/ }
func functionWithAnyDefault(argument:String) { /* Implementation here */ }
func functionWithAnyDefault() { self.functionWithAnyDefault(“Bar”) } //
Override default
}
Which could be replaced by:
protocol Protocol {
func functionWithSpecificDefault(argument:String = “Foo")
func functionWithAnyDefault(argument:String = default)
}
class MyClass : Protocol {
func functionWithSpecificDefault(argument:String = “Foo") { /*
Implementation here */ }
func functionWithAnyDefault(argument:String = “Bar") { /* Implementation
here */ }
}
However, this has the added advantage that implementing
functionWithSpecificDefault with a default other than “Foo” would cause a
compiler error, while doing so for functionWithAnyDefault would not (but
specifying no default at all would, as one is required).
On 16 Jan 2016, at 10:15, 肇鑫 via swift-evolution < > swift-evolution@swift.org> wrote:
No. Although you protocol's function doesn't has a default parameter
value. Your implementation does. So you don't need to define another func
function() in your protocol.
protocol Good {
func printSomething(something:String)
}
struct Name:Good {
func printSomething(something: String = "John") {
print(something)
}
}
Name().printSomething()
above code works.
zhaoxin
On Sat, Jan 16, 2016 at 6:05 PM, Vatsal Manot <vatsal.manot@yahoo.com> > wrote:
It serves as a better (if not simpler) substitute for the following
pattern:
protocol Protocol
{
typealias Argument
func function()
func function(_: Argument)
}
On 16-Jan-2016, at 3:29 PM, 肇鑫 <owenzx@gmail.com> wrote:
I wonder where is the good for a protocol designer on this?
zhaoxin
On Sat, Jan 16, 2016 at 5:23 PM, Vatsal Manot via swift-evolution < >> swift-evolution@swift.org> wrote:
Currently, the following the code fails with multiple errors:
protocol Protocol
{
typealias Argument
func function(argument: Argument = default)
}
I propose that we allow protocols to require functions with default
parameter values. I can’t see any disadvantages to this, and the change
would only be additive.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Owen Zhao
--
Owen Zhao
_______________________________________________
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
_______________________________________________
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