[swift-evolution] Compiler should generate code base on the functions that have default values

肇鑫 owenzx at gmail.com
Sun Jan 17 21:18:43 CST 2016


Hi David,

You understanding is correct.

There is only one thing I have to mention. Unless the other c style
languages which you can call default values in the middle, Swift only
allows you to call default values in the last. That makes you example:

func print(message: String = default, path: String = default, line: Int =
default)

can only wrapped to 4 functions instead of 8.

func print(message: String, path: String, line: Int)
func print()
func print(message: String)
func print(message: String, path: String)

You can't call func print(path: String) by calling func print(message:
String = default, path: String = default, line: Int = default). print(_,
path: "path"t, line: _) is not a valid calling in Swift.

zhaoxin

On Mon, Jan 18, 2016 at 2:19 AM, David Hart <david at hartbit.com> wrote:

> Hi Dave,
>
> I agree with 肇鑫. Your issue and his seem like two separate issues, and I’d
> also like to see his issue implemented. For example, imagine I wanted to
> define this protocol:
>
> protocol Logger {
>     func print()
>     func print(message: String)
>     func print(path: String)
>     func print(line: Int)
>     func print(message: String, path: String)
>     func print(message: String, line: Int)
>     func print(path: String, line: Int)
>     func print(message: String, path: String, line: Int)
> }
>
> It would be much simpler if I could more simply write:
>
> protocol Logger {
>     func print(message: String = default, path: String = default, line:
> Int = default)
> }
>
> Which is a separate issue then what you propose which would allow the same
> as the following for *init* as well:
>
> protocol Logger {
>     func print(message: String)
> }
>
> class NSLogger {
>     func print(message: String, path: String, line: Int) {
>         // ...
>     }
> }
>
> extension NSLogger: Logger {
>     conformance {
>         print(message)
>     }
> }
>
> On 17 Jan 2016, at 18:09, 肇鑫 via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> It is not to *conform to the same function name but with  different
> signatures*. It is the protocol limits in current Swift. You can
> implement a protocol function with default values. But the protocol can't
> call the function with the default value. So you have to add another
> function that has no argument in the protocol and change the implementation.
>
> current code:
>
> protocol A {
>     func printSomething(something:String)
> }
>
> struct Foo:A {
>     func printSomething(something:String = "some thing") {
>         print(something)
>     }
> }
>
> Foo().printSomething() // some thing
> (Foo() as A).printSomething() // Missing argument for parameter #1 in call
>
> default value part is widely discussed in this thread
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160111/006798.html>,
> including other approaches like protocol extension.
>
> zhaoxin
>
> On Mon, Jan 18, 2016 at 12:52 AM, J. Cheyo Jimenez <cheyo at masters3d.com>
> wrote:
>
>> This is very interesting. The first case seems like a bug because the
>> compiler should not let you define that function().
>>
>> Do you have any actual examples when you would need to conform to the
>> same function name but with different signatures?
>>
>>
>> On Sunday, January 17, 2016, 肇鑫 via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>> This proposal is the summary of the previous protocol function default
>>> value proposal and some of my new thinkings all together.
>>>
>>> Currently the compiler doesn't stop you defining two functions like:
>>>
>>> func printSomething(something:String = "some thing") {
>>>     print(something)
>>> }
>>>
>>> func printSomething() {
>>>     print("some thing!")
>>> }
>>>
>>> However, when you call it, an error arises.
>>>
>>> printSomething() // Ambiguous use of 'printSomething'
>>>
>>> You may say just remove the function that has no argument. But protocol
>>> needs it.
>>>
>>> protocol A {
>>>     func printSomething(something:String)
>>>     func printSomething()
>>> }
>>>
>>> struct Foo:A {
>>>     func printSomething(something:String) {
>>>         print(something)
>>>     }
>>>
>>>
>>>     func printSomething() {
>>>         self.printSomething("some thing")
>>>     }
>>>
>>> }
>>>
>>> If you do't define the no-argument function in protocol A. You can not
>>> use the function by (Foo() as A).printSomething().
>>>
>>>
>>> As we all know, a function with default values, can rewrite to two or
>>> more equivalent functions. For example,
>>>
>>> struct Bar {
>>>     func add(int1:Int = 1, int2:Int = 2, int3:Int = 3) {
>>>         print(int1 + int2 + int3)
>>>     }
>>>
>>> }
>>>
>>> is equivalent to
>>>
>>> struct Bar {
>>>     func add(int1:Int, int2:Int, int3:Int) {
>>>         print(int1 + int2 + int3)
>>>     }
>>>
>>>
>>>     func add() {
>>>         self.add(1, int2: 2, int3: 3)
>>>     }
>>>
>>>
>>>     func add(int1:Int) {
>>>         self.add(int1, int2: 2, int3: 3)
>>>     }
>>>
>>>
>>>     func add(int1:Int, int2:Int) {
>>>         self.add(int1, int2: int2, int3: 3)
>>>     }
>>>
>>> }
>>>
>>> So my proposal is let compiler or pre-compiler to generate the code
>>> internally, without changing the original code,  base on the functions that
>>> have default values.
>>>
>>> Then we need not to define multiple functions in a protocol when we need
>>> function with default values.
>>>
>>> new code:
>>>
>>> protocol A {
>>>     func printSomething(something:String)
>>> }
>>>
>>> struct Foo:A {
>>>     func printSomething(something:String = "some thing") {
>>>         print(something)
>>>     }
>>>
>>> }
>>>
>>>
>>> If we don't want to change our previous code, we may also need to
>>> introduce another keyword defaultValue. This keyword is used only in a
>>> protocol to restrict if a function's argument can have a default value. If
>>> a function use it, but the implementation doesn't give a default value, or
>>> vice versa, an error arises.
>>>
>>> new code:
>>>
>>> protocol A {
>>>     func printSomething(something:String = defaultValue)
>>> }
>>>
>>> struct Foo:A {
>>>     func printSomething(something:String = "some thing") {
>>>         print(something)
>>>     }
>>>
>>> }
>>>
>>> This keyword is useful. With it, you can still use Swift in old way.
>>> Which means you need not to change code like below if you don't want to.
>>>
>>> old code:
>>>
>>> protocol A {
>>>     func printSomething(something:String)
>>>     func printSomething()
>>> }
>>>
>>> struct Foo:A {
>>>     func printSomething(something:String) {
>>>         print(something)
>>>     }
>>>
>>>
>>>     func printSomething() {
>>>         self.printSomething("some thing")
>>>     }
>>>
>>> }
>>>
>>> But if you want to write new code. You can just write it in the new
>>> way, enjoining the simpler and clearer.
>>>
>>> zhaoxin
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160118/cf93bf26/attachment.html>


More information about the swift-evolution mailing list