> Am 03.09.2016 um 18:45 schrieb Justin Jia <[email protected]>:
> 
> 
>> On Sep 4, 2016, at 12:19 AM, Thorsten Seitz <[email protected]> wrote:
>> 
>> 
>> 
>> Am 15.08.2016 um 19:05 schrieb Justin Jia via swift-evolution 
>> <[email protected]>:
>> 
>>> I agree that being explicit is nice and I also like to use `guard`.
>>> 
>>> But according to my observation, usually it is easier to make mistakes if 
>>> we choose to use `guard`.
>>> 
>>> Let me give you a fake real world example.
>>> 
>>> With `guard`, you need to be really careful when you want to add new 
>>> expression (people usually will add to the end of the function).
>>> 
>>> ```
>>> func updateCell(cell: Cell, data: CellData) {
>>>   cell.label.text = data.title
>>>   guard let imageName = data.imageName else { return }
>>>   cell.sublabel.text = cell.humanize(imageName)
>>>   guard let image = UIImage(named: imageName) else { return }
>>>   cell.addBackgroundImage(image)
>>>   // Let's say we changed the design and added a new heading that depends 
>>> on image name
>>>   cell.heading = String(imageName.characters.first) // This won't be called 
>>> if image is nil!
>>> }
>>> ```
>>> 
>>> With `if let`, it is really hard to read. This will become more complicated 
>>> if we add more attributes to cell.
>>> 
>>> ```
>>> func updateCell(cell: Cell, data: CellData) {
>>>   cell.label.text = data.title
>>>   if let imageName = data.imageName {
>>>     cell.sublabel.text = cell.humanize(imageName)
>>>     if let image = UIImage(name: imageName) {
>>>       cell.addBackgroundImage(image)
>>>     }
>>>     cell.heading = String(imageName.characters.first)
>>>   }
>>> }
>>> ```
>>> 
>>> With the proposed syntax:
>>> 
>>> ```
>>> func updateCell(cell: Cell, data: CellData) {
>>>   cell.label.text = data.title
>>>   let imageName = data.imageName // imageName is optional
>>>   cell.sublabel.text = cell.humanize(imageName?)
>>>   let image = UIImage(named: imageName?) // image is optional
>>>   cell.addBackgroundImage(image?)
>>>   cell.heading = String(imageName.characters.first?)
>>> }
>>> ```
>>> 
>>> This is really easy to read. And everything works correctly.
>> 
>> It is even easier if you define the methods on Cell to take optional 
>> arguments. 
>> Then you can write the code like in your last example and don't even need 
>> the proposed syntax:
>> 
>> class Cell {
>>     let label = UILabel()
>>     let sublabel = UILabel()
>>     var heading: String?
>>     func humanize(_ string: String?) -> String {...}    // optional argument
>>     func addBackgroundImage(_ image: UIImage?)    // optional argument
>> }
>> 
>> extension UIImage {
>>     init?(named imageName: String?) {...}
>> }
>> 
>> extension String {
>>     init?(named imageName: Character?) {...}
>> }
>> 
>> func updateCell(cell: Cell, data: CellData) {
>>   cell.label.text = data.title
>>   let imageName = data.imageName
>>   cell.sublabel.text = cell.humanize(imageName)
>>   let image = UIImage(named: imageName)
>>   cell.addBackgroundImage(image)
>>   cell.heading = String(imageName?.characters?.first)
>> }
>> 
>> -Thorsten 
> 
> 
> Quoting another email:
> 
>> Actually there is an easy fix: make all functions accept optionals. I think 
>> this is a really bad idea because sometimes functions are designed to accept 
>> non-optionals.
>> 
>> e.g.
>> 
>> ```
>> func addSubview(_ view: UIView) { }
>> ```
>> 
>> It doesn’t make sense if we want to add nil as the subview, so we choose to 
>> write code like this:
>> 
>> ```
>> if let view = view {
>>     addSubview(view)
>> }
>> ```
> 

I agree. The proposal effectively does just that, though: turn every function 
into a function accepting optionals (returning nil if any argument is nil). I 
would prefer to do this explicitly in cases where it makes sense and use map or 
let-bindings elsewhere.

-Thorsten 
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to