[swift-evolution] [Pitch] Nil struct
Adrian Zubarev
adrian.zubarev at devandartist.com
Tue Nov 8 14:44:53 CST 2016
At first glance this doesn’t make any sense to me:
public protocol ExpressibleByNilLiteral {
associatedtype NilLiteralType = Nil
init(nilLiteral: NilLiteralType)
}
What’s the need for associatedtype there?
Shouldn’t it be just like this:
public protocol ExpressibleByNilLiteral {
init(nilLiteral: Nil)
}
I actually would appreciate this change, because of one thing I run into a few days ago.
I’m building a library for BSON (Binary JSON) where I have a struct Document which conforms to ExpressibleByDictionaryLiteral. Than I have a protocol which can convert any type to a value type my document can store.
Now I would have to choose how to implement ExpressibleByDictionaryLiteral:
public init(dictionaryLiteral elements: (String, Element.Value)...)
public init(dictionaryLiteral elements: (String, ElementValueConvertible)…)
If I would go for the second version, I’d lose the ExpressibleByNilLiteral from my value type but I could use every other type naturally.
With the proposed change I could extend Nil with my protocol and make the conversion naturally again.
That is the only advantage I would gain from such a change in the language.
--
Adrian Zubarev
Sent with Airmail
Am 8. November 2016 um 21:30:26, Anton Zhilin via swift-evolution (swift-evolution at swift.org) schrieb:
Gist link
Introduction
Change
nil literal type from
() to
Nil.
Before:
public protocol ExpressibleByNilLiteral {
init(nilLiteral: ())
}
After:
public struct Nil {
init()
}
public protocol ExpressibleByNilLiteral {
associatedtype NilLiteralType = Nil
init(nilLiteral: NilLiteralType)
}
Motivation
Currently,
nil differs from other literals: it doesn’t have its own type.
But in some cases we want to deal directly with it, without creating any instances.
The most important use case is comparison of an
Optional to
nil.
Currently, this operation is implemented using a hidden struct
_OptionalNilComparisonType,
which is needed precisely because because
nil does not have its own type.
Removal of such underscored types is one of the goals stated in Generics manifesto.
Additionally, declaration of
ExpressibleByNilLiteral differs from all other
Expressibles,
because it doesn’t have a
Literal type. It is generally beneficial to eliminate special cases.
Proposed solution
Introduce a struct
Nil, which becomes the default type for
nil literals:
public struct Nil : ExpressibleByNilLiteral {
init()
init(nilLiteral: NilLiteralType)
}
let a = nil
print(type(of: a)) //=> Nil
Rewrite
ExpressibleByNilLiteral:
public protocol ExpressibleByNilLiteral {
associatedtype NilLiteralType = Nil
init(nilLiteral: NilLiteralType)
}
Make use of
Nil in the standard library:
public func == <T>(left: T?, right: Nil)
public func == <T>(left: Nil, right: T?)
public func != <T>(left: T?, right: Nil)
public func != <T>(left: Nil, right: T?)
public func ~= <T>(left: Nil, right: T?)
Source compatibility
Nil identifier is taken, therefore applications that already use it will stop compiling.
Automatic migration is somewhat possible by renaming of the old entity; manual migration is recommended.
Applications that use declare
ExpressibleByNilLiteral conformances will stop compiling.
Automatic migration is possible.
Effect on ABI stability
Applications that use
Nil identifier will have to make ABI-breaking changes.
Otherwise, the change can mostly be applied in an ABI-compatible manner.
_______________________________________________
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/20161108/5b7ea081/attachment.html>
More information about the swift-evolution
mailing list