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
([email protected]) 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution