[swift-evolution] [Idea] Use optionals for non-optional parameters
Justin Jia
justin.jia.developer at gmail.com
Sun Sep 4 00:15:33 CDT 2016
> On Sep 4, 2016, at 1:35 AM, Thorsten Seitz <tseitz42 at icloud.com> wrote:
>
>
>
>> Am 03.09.2016 um 18:45 schrieb Justin Jia <justin.jia.developer at gmail.com>:
>>
>>
>>> On Sep 4, 2016, at 12:19 AM, Thorsten Seitz <tseitz42 at icloud.com> wrote:
>>>
>>>
>>>
>>> Am 15.08.2016 um 19:05 schrieb Justin Jia via swift-evolution <swift-evolution at swift.org>:
>>>
>>>> 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
I was thinking about a precondition syntax. But I think it's too complicated. I agree. Maybe do this explicitly is better.
Justin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160904/80b73958/attachment.html>
More information about the swift-evolution
mailing list