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

肇鑫 owenzx at gmail.com
Sun Jan 17 08:57:48 CST 2016


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160117/079366e0/attachment.html>


More information about the swift-evolution mailing list