[swift-evolution] Proposal: extend Optional-specific syntax to arbitrary types with CustomOptionalConvertible

Kevin Ballard kevin at sb.org
Mon Dec 7 15:47:16 CST 2015


I agree. The motivation of this proposal is laudable, but I'm not sure it actually gains anything over just defining a property of optional type on the type in question. For example, with your Either enum, you might have:

var left: ErrorType?    var right: Value?

This requires no language changes and allows the use of if-let and
optional chaining. It also allows you to expose your different variants
as optional, instead of assuming that only one variant is special.

-Kevin Ballard

On Mon, Dec 7, 2015, at 01:38 PM, Paul Cantrell via swift-evolution wrote:
> I like the sentiment of this proposal, but I’m not sure it provides
> clear value. We already have a generalized version of “if let” in the
> form of “if case”:
>
> func foo(either: Either<String>) -> String { if case .Right(let
> string) = either { return string        } else { return "No
> value"        }    }
>
> This works with cascades just fine:
>
> if case .Right(let string0) = either0,            .Right(let string1)
> = either1,            .Right(let string2) = either2 {
>
> Leaving aside that Swift’s “if case” syntax is a bit clumsy and hard
> to remember at first, does a CustomOptionalConvertible really grant
> additional benefit in terms of either safety or readability?
>
> Cheers,
>
> Paul
>
>
>> On Dec 7, 2015, at 2:58 PM, krzysztof at siejkowski.net via swift-
>> evolution <swift-evolution at swift.org> wrote:
>>
>> Hi,
>>
>>
>> # Introduction
>>
>> I'd like to propose a non-invasive way of extending the funtionality
>> of `if let` conditional binding (and potencially other Optional-
>> related language constructs) by introducing
>> `CustomOptionalConvertible` protocol. The idea is basically the same
>> as with `CustomStringConvertible` protocol used to provide string
>> interpolation or with `~=` operator used in `switch` statement
>> pattern matching.  I believe it's going to simplity and unify the
>> use of the Optional-related family of Swift syntax constructs for
>> custom types.
>>
>> The proposal is in a draft stage right now, I'll clear it up if it
>> proves worth to be pull-requested.
>>
>>
>> # Motivation
>>
>> One of the Swift features that are core to it's safety and
>> readability are Optionals. They're important enough to be given
>> special place in the language syntax. Special operators like `?`, `!`
>> or `??`, special casting keywords like `as?`, special conditional
>> binding `if let`. The Optionals, however, might be also seen as a
>> member of larger family of constructs: call them monads, boxes, value
>> containers, computational context bearers. One example of those would
>> be a very similar type going by the name of  Either, Try or Result.
>> It can be seen as an Optional that carries some additional
>> information about the reason why the value is absent. That
>> information is not always of our interest and in those cases
>> conditional binding  for Either type makes a lot of sense. However,
>> the `if let` syntax is currently exclusively working only for
>> optionals.
>>
>>
>> # Proposed solution
>>
>> While I'd love to see Swift introducing a powerful construct similar
>> to Haskell's `do-notation` or Scala's `for-comprehension`, I believe
>> it'd require a significant invasive change in the language
>> implementation (and, possibly, vision). Therefore the proposed
>> solutions is much more humble. Let's introduce the
>> `CustomOptionalConvertible` protocol with signature:
>>
>> ``` protocol CustomOptionalConvertible { typealias Wrapped public var
>> optional: Optional<Wrapped> { get } } ```
>>
>> Such a protocol will provide a way for an arbitrary type to convert
>> to the Optional. All the types implementing this protocol could then
>> be used in conditional binding syntax without explicit declaration of
>> conversion. I do not propose the introduction of general implicit
>> conversion construct, just a special case. The same as
>> `CustomStringConvertible` is a special case of allowing the value to
>> express itself in the string
>> interpolation.`CustomOptionalConvertible` will allow the author of an
>> arbitratry type to integrate with Swift syntax:
>>
>> ``` enum Either<Value> { case Left(ErrorType) case Right(Value) }
>>
>> extension Either : CustomOptionalConvertible { typealias Wrapped =
>> Value public var optional: Optional<Value> { get { switch (self) {
>> case .Left(_): return .None case .Right(let value): return
>> .Some(value) } } } }
>>
>> func foo(either: Either<String>) -> String { if let string = either {
>> return string } else { return "No value" } } ```
>>
>> There is already a similar mechanism available in the context of
>> pattern matching: `~=` operator.
>>
>>
>> # Impact on the language
>>
>> While I cannot say much about the impact on the compiler, I believe
>> the introduction will bring no breaking change to the Swift language
>> itself. All the places that are currently requiring Optionals will
>> still require Optionals.
>>
>> For the language users it'll make it easier to integrate the
>> constructs used in the program with the native syntax, making them
>> easier to use and read. Current solution, namely: ``` func
>> foo(either: Either<String>) -> String { if let string =
>> either.optional { return string } else { return "No value" } } ``` is
>> introducing unnecessary noise in the otherwise neat syntax. The
>> problem escalates when `if let` cascade is used: ``` if let string =
>> eitherString.optional           int = eitherInt.optional
>> array = eitherArray.optional // ... ```
>>
>>
>> # Alternatives considered
>>
>> The equivalent of Haskell’s `do-notation`. It’s a powerful construct
>> (some say even too powerful, see
>> https://wiki.haskell.org/Do_notation_considered_harmful). However, I
>> can’t imagine it without significant changes to the language syntax
>> (`if let` should return value) and vision (I believe that Optional
>> are syntactic unicorns by design).
>>
>>
>> All the best, Krzysztof
>>  _______________________________________________
>> swift-evolution mailing list swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _________________________________________________
> 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/20151207/1388daba/attachment.html>


More information about the swift-evolution mailing list