Yes, it will — if a type does not conform to `CustomPlaygroundRepresentable`, PlaygroundLogger will continue to log it structurally.
Connor > On Jan 9, 2018, at 3:56 PM, Saagar Jha <saa...@saagarjha.com> wrote: > > I’ve just glanced through this, so I apologize if this was already addressed, > but will the default behavior (i.e. that of something that doesn’t conform to > CustomPlaygroundRepresentable) remain the same? > > Saagar Jha > >> On Jan 9, 2018, at 15:19, Connor Wakamo via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> Good afternoon, >> >> In preparation for ABI stability, I’ve reviewed the API exposed by the >> standard library for providing customized “quick looks” in playgrounds. This >> is exposed as the PlaygroundQuickLook enum and the >> CustomPlaygroundQuickLookable protocol. The PlaygroundQuickLook has a >> handful of issues: >> >> - It hard-codes the list of supported types in the standard library, >> meaning that PlaygroundLogger/IDEs cannot gain support for new types without >> standard library changes (including swift-evolution review) >> - The cases of the enum are poorly typed: there are cases like `.view` >> and `.color` which take NS/UIView or NS/UIColor instances, respectively, but >> since they’re in the standard library, they have to be typed as taking `Any` >> instead >> - The names of some of these enum cases do not seem to match Swift >> naming conventions) >> >> To that end, I am proposing the following: >> >> - Deprecate PlaygroundQuickLook and CustomPlaygroundQuickLookable in >> Swift 4.1 (including in the Swift 3 compatibility mode) >> - Remove PlaygroundQuickLook and CustomPlaygroundQuickLookable in Swift >> 5 to avoid including them in the stable ABI (this affects the compatibility >> modes, too) >> - Introduce a new protocol, CustomPlaygroundRepresentable, in the >> PlaygroundSupport library in Swift 4.1: >> >> protocol CustomPlaygroundRepresentable { >> /// Returns an alternate object or value which should >> stand in for the receiver in playground logging, or nil if the receiver’s >> default representation is preferred. >> var playgroundRepresentation: Any? { get } >> } >> >> - Update the PlaygroundLogger library in Swift 4.1 to support both >> CustomPlaygroundRepresentable and >> PlaygroundQuickLook/CustomPlaygroundQuickLookable >> - Provide a compatibility shim library which preserves >> PlaygroundQuickLook and CustomPlaygroundQuickLookable as deprecated in Swift >> 3/4 and unavailable in Swift 5, but only in playgrounds (including in the >> auxiliary source files stored inside a playground) >> >> I’ve put a full proposal below. Please let me know what you think of this >> proposal; I’d like to get some feedback before taking this through the >> review process, but I’ll need to get that quickly so I can get it under >> review soon as this is targeted at Swift 4.1. >> >> Thanks, >> Connor >> >> — >> >> Playground QuickLook API Revamp >> >> Proposal: SE-NNNN >> <https://github.com/cwakamo/swift-evolution/blob/playground-quicklook-api-revamp/proposals/NNNN-playground-quicklook-api-revamp.md> >> Authors: Connor Wakamo <https://github.com/cwakamo> >> Review Manager: TBD >> Status: Awaiting implementation >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#introduction>Introduction >> >> The standard library currently includes API which allows a type to customize >> its representation in Xcode playgrounds and Swift Playgrounds. This API >> takes the form of the PlaygroundQuickLook enum which enumerates types which >> are supported for quick looks, and the CustomPlaygroundQuickLookable >> protocol which allows a type to return a custom PlaygroundQuickLook value >> for an instance. >> >> This is brittle, and to avoid dependency inversions, many of the cases are >> typed as taking Any instead of a more appropriate type. This proposal >> suggests that we deprecate PlaygroundQuickLook and >> CustomPlaygroundQuickLookable in Swift 4.1 so they can be removed entirely >> in Swift 5, preventing them from being included in the standard library's >> stable ABI. To maintain compatibility with older playgrounds, the deprecated >> symbols will be present in a temporary compatibility shim library which will >> be automatically imported in playground contexts. (This will represent an >> intentional source break for projects, packages, and other non-playground >> Swift code which use PlaygroundQuickLook or CustomPlaygroundQuickLookable >> when they switch to the Swift 5.0 compiler, even in the compatibility modes.) >> >> Since it is still useful to allow types to provide alternate representations >> for playgrounds, we propose to add a new protocol to the PlaygroundSupport >> framework which allows types to do just that. (PlaygroundSupport is a >> framework delivered by the swift-xcode-playground-support project >> <https://github.com/apple/swift-xcode-playground-support> which provides API >> specific to working in the playgrounds environment). The new >> CustomPlaygroundRepresentable protocol would allow instances to return an >> alternate object or value (as an Any) which would serve as their >> representation. The PlaygroundLogger framework, also part of >> swift-xcode-playground-support, will be updated to understand this protocol. >> >> Swift-evolution thread: Discussion thread topic for that proposal >> <https://lists.swift.org/pipermail/swift-evolution/> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#motivation>Motivation >> >> The PlaygroundQuickLook enum which currently exists in the standard library >> is substandard: >> >> public enum PlaygroundQuickLook { >> case text(String) >> case int(Int64) >> case uInt(UInt64) >> case float(Float32) >> case double(Float64) >> case image(Any) >> case sound(Any) >> case color(Any) >> case bezierPath(Any) >> case attributedString(Any) >> case rectangle(Float64, Float64, Float64, Float64) >> case point(Float64, Float64) >> case size(Float64, Float64) >> case bool(Bool) >> case range(Int64, Int64) >> case view(Any) >> case sprite(Any) >> case url(String) >> case _raw([UInt8], String) >> } >> The names of these enum cases do not necessarily match current Swift naming >> conventions (e.g. uInt), and many cases are typed as Any to avoid dependency >> inversions between the standard library and higher-level frameworks like >> Foundation and AppKit or UIKit. It also contains cases which the >> PlaygroundLogger framework does not understand (e.g. sound), and this >> listing of cases introduces revlock between PlaygroundLogger and the >> standard library that makes it challenging to introduce support for new >> types of quick looks. >> >> Values of this enum are provided to the PlaygroundLogger framework by types >> via conformances to the CustomPlaygroundQuickLookable protocol: >> >> public protocol CustomPlaygroundQuickLookable { >> var customPlaygroundQuickLook: PlaygroundQuickLook { get } >> } >> This protocol itself is not problematic, but if PlaygroundQuickLook is being >> removed, then it needs to be removed as well. Additionally, there is a >> companion underscored protocol which should be removed as well: >> >> public protocol _DefaultCustomPlaygroundQuickLookable { >> var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook { get } >> } >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#proposed-solution>Proposed >> solution >> >> To solve this issue, we propose the following changes: >> >> Introduce a new CustomPlaygroundRepresentable protocol in PlaygroundSupport >> in Swift 4.1 to allow types to provide an alternate representation for >> playground logging >> Deprecate PlaygroundQuickLook and CustomPlaygroundQuickLookable in Swift >> 4.1, suggesting users use CustomPlaygroundRepresentable instead >> Remove PlaygroundQuickLook and CustomPlaygroundQuickLookable from the >> standard library in Swift 5.0 >> Provide an automatically-imported shim library for the playgrounds context >> to provide the deprecated instances of PlaygroundQuickLook and >> CustomPlaygroundQuickLookable for pre-Swift 5 playgrounds >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#detailed-design>Detailed >> design >> >> To provide a more flexible API, we propose deprecating and ultimately >> removing the PlaygroundQuickLook enum and CustomPlaygroundQuickLookable >> protocol in favor of a simpler design. Instead, we propose introducing a >> protocol which just provides the ability to return an Any (or nil) that >> serves as a stand-in for the instance being logged: >> >> /// A type that supplies a custom representation for playground logging. >> /// >> /// All types have a default representation for playgrounds. This protocol >> /// allows types to provide custom representations which are then logged in >> /// place of the original instance. Alternatively, implementors may choose to >> /// return `nil` in instances where the default representation is preferable. >> /// >> /// Playground logging can generate, at a minimum, a structured >> representation >> /// of any type. Playground logging is also capable of generating a richer, >> /// more specialized representation of core types -- for instance, the >> contents >> /// of a `String` are logged, as are the components of an `NSColor` or >> /// `UIColor`. >> /// >> /// The current playground logging implementation logs specialized >> /// representations of at least the following types: >> /// >> /// - `String` and `NSString` >> /// - `Int` and `UInt` (including the sized variants) >> /// - `Float` and `Double` >> /// - `Bool` >> /// - `Date` and `NSDate` >> /// - `NSAttributedString` >> /// - `NSNumber` >> /// - `NSRange` >> /// - `URL` and `NSURL` >> /// - `CGPoint`, `CGSize`, and `CGRect` >> /// - `NSColor`, `UIColor`, `CGColor`, and `CIColor` >> /// - `NSImage`, `UIImage`, `CGImage`, and `CIImage` >> /// - `NSBezierPath` and `UIBezierPath` >> /// - `NSView` and `UIView` >> /// >> /// Playground logging may also be able to support specialized >> representations >> /// of other types. >> /// >> /// Implementors of `CustomPlaygroundRepresentable` may return a value of >> one of >> /// the above types to also receive a specialized log representation. >> /// Implementors may also return any other type, and playground logging will >> /// generated structured logging for the returned value. >> public protocol CustomPlaygroundRepresentable { >> /// Returns the custom playground representation for this instance, or nil >> if >> /// the default representation should be used. >> /// >> /// If this type has value semantics, the instance returned should be >> /// unaffected by subsequent mutations if possible. >> var playgroundRepresentation: Any? { get } >> } >> Additionally, instead of placing this protocol in the standard library, we >> propose placing this protocol in the PlaygroundSupport framework, as it is >> only of interest in the playgrounds environment. Should demand warrant it, a >> future proposal could suggest lowering this protocol into the standard >> library. >> >> If this proposal is accepted, then code like the following: >> >> extension MyStruct: CustomPlaygroundQuickLookable { >> var customPlaygroundQuickLook: PlaygroundQuickLook { >> return .text("A description of this MyStruct instance") >> } >> } >> would be replaced with something like the following: >> >> extension MyStruct: CustomPlaygroundRepresentable { >> var playgroundRepresentation: Any? { >> return "A description of this MyStruct instance" >> } >> } >> This proposal also allows types which wish to be represented structurally >> (like an array or dictionary) to return a type which is logged structurally >> instead of requiring an implementation of the CustomReflectable protocol: >> >> extension MyStruct: CustomPlaygroundRepresentable { >> var playgroundRepresentation: Any? { >> return [1, 2, 3] >> } >> } >> This is an enhancement over the existing CustomPlaygroundQuickLookable >> protocol, which only supported returning opaque, quick lookable values for >> playground logging. (By returning an Any?, it also allows instances to >> opt-in to their standard playground representation if that is preferable >> some cases.) >> >> Implementations of CustomPlaygroundRepresentable may potentially chain from >> one to another. For instance, with: >> >> extension MyStruct: CustomPlaygroundRepresentable { >> var playgroundRepresentation: Any? { >> return "MyStruct representation" >> } >> } >> >> extension MyOtherStruct: CustomPlaygroundRepresentable { >> var playgroundRepresentation: Any? { >> return MyStruct() >> } >> } >> Playground logging for MyOtherStruct would generate the string "MyStruct >> representation" rather than the structural view of MyStruct. It is legal, >> however, for playground logging implementations to cap chaining to a >> reasonable limit to guard against infinite recursion. >> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#source-compatibility>Source >> compatibility >> >> This proposal is explicitly suggesting that we make a source-breaking change >> in Swift 5 to remove PlaygroundQuickLook, CustomPlaygroundQuickLookable, and >> _DefaultCustomPlaygroundQuickLookable. Looking at a GitHub search, there are >> fewer than 900 references to CustomPlaygroundQuickLookable in Swift source >> code; from a cursory glance, many of these are duplicates, from forks of the >> Swift repo itself (i.e. the definition of CustomPlaygroundQuickLookable in >> the standard library), or are clearly implemented using pre-Swift 3 names of >> the enum cases in PlaygroundQuickLook. (As a point of comparison, there are >> over 185,000 references to CustomStringConvertible in Swift code on GitHub, >> and over 145,000 references to CustomDebugStringConvertible, so >> CustomPlaygroundQuickLookable is clearly used many orders of magnitude less >> than those protocols.) Furthermore, it does not appear that any projects >> currently in the source compatibility suite use these types. >> >> However, to mitigate the impact of this change, we propose to provide a >> limited source compatibility shim for the playgrounds context. This will be >> delivered as part of the swift-xcode-playground-support project as a library >> containing the deprecated PlaygroundQuickLook and >> CustomPlaygroundQuickLookable protocols. This library would be imported >> automatically in playgrounds. This source compatibility shim would not be >> available outside of playgrounds, so any projects, packages, or other Swift >> code would be intentionally broken by this change when upgrading to the >> Swift 5.0 compiler, even when compiling in a compatibility mode. >> >> Due to the limited usage of these protocols, and the potential challenge in >> migration, this proposal does not include any proposed migrator changes to >> support the replacement of CustomPlaygroundQuickLookable >> withCustomPlaygroundRepresentable. Instead, we intend for Swift 4.1 to be a >> deprecation period for these APIs, allowing any code bases which implement >> CustomPlaygroundQuickLookable to manually switch to the new protocol. While >> this migration may not be trivial programatically, it should -- in most >> cases -- be fairly trivial for someone to hand-migrate >> toCustomPlaygroundRepresentable. During the deprecation period, the >> PlaygroundLogger framework will continue to honor implementations of >> CustomPlaygroundQuickLookable, though it will prefer implementations >> ofCustomPlaygroundRepresentable if both are present on a given type. >> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#effect-on-abi-stability>Effect >> on ABI stability >> >> This proposal affects ABI stability as it removes an enum and a pair of >> protocols from the standard library. Since this proposal proposes adding >> CustomPlaygroundRepresentable to PlaygroundSupport instead of the standard >> library, there is no impact of ABI stability from the new protocol, as >> PlaygroundSupport does not need to maintain a stable ABI, as its clients -- >> playgrounds -- are always recompiled from source. >> >> Since playgrounds are always compiled from source, the temporary shim >> library does not represent a new ABI guarantee, and it may be removed if the >> compiler drops support for the Swift 3 and 4 compatibility modes in a future >> Swift release. >> >> Removing PlaygroundQuickLook from the standard library also potentially >> allows us to remove a handful of runtime entry points which were included to >> support the PlaygroundQuickLook(reflecting:) API. >> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#effect-on-api-resilience>Effect >> on API resilience >> >> This proposal does not impact API resilience. >> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#alternatives-considered>Alternatives >> considered >> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#do-nothing>Do >> nothing >> >> One valid alternative to this proposal is to do nothing: we could continue >> to live with the existing enum and protocol. As noted above, these are >> fairly poor, and do not serve the needs of playgrounds particularly well. >> Since this is our last chance to remove them prior to ABI stability, we >> believe that doing nothing is not an acceptable alternative. >> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#provide-type-specific-protocols>Provide >> type-specific protocols >> >> Another alternative we considered was to provide type-specific protocols for >> providing playground representations. We would introduce new protocols like >> CustomNSColorConvertible, CustomNSAttributedStringConvertible, etc. which >> would allow types to provide representations as each of the >> opaquely-loggable types supported by PlaygroundLogger. >> >> This alternative was rejected as it would balloon the API surface for >> playgrounds, and it also would not provide a good way to select a preferred >> representation. (That is, what would PlaygroundLogger select as the >> representation of an instance if it implemented both >> CustomNSColorConvertible and CustomNSAttributedStringConvertible?) >> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#implement-customplaygroundrepresentable-in-the-standard-library>Implement >> CustomPlaygroundRepresentable in the standard library >> >> As an alternative to implementing CustomPlaygroundRepresentable in >> PlaygroundSupport, we could implement it in the standard library. This would >> make it available in all contexts (i.e. in projects and packages, not just >> in playgrounds), but this protocol is not particularly useful outside of the >> playground context, so this proposal elects not to >> placeCustomPlaygroundRepresentable in the standard library. >> >> Additionally, it should be a source-compatible change to move this protocol >> to the standard library in a future Swift version should that be desirable. >> Since playgrounds are always compiled from source, the fact that this would >> be an ABI change for PlaygroundSupport does not matter, and a compatibility >> typealias could be provided in PlaygroundSupport to maintain compatibility >> with code which explicitly qualified the name of the >> CustomPlaygroundRepresentable protocol. >> >> >> <https://github.com/cwakamo/swift-evolution/tree/playground-quicklook-api-revamp#have-customplaygroundrepresentable-return-something-other-than-any>Have >> CustomPlaygroundRepresentable return something other than Any? >> >> One minor alternative considered was to have CustomPlaygroundRepresentable >> return a value with a more specific type than Any?. For example: >> >> protocol CustomPlaygroundRepresentable { >> var playgroundRepresentation: CustomPlaygroundRepresentable? { get } >> } >> or: >> >> protocol PlaygroundRepresentation {} >> >> protocol CustomPlaygroundRepresentable { >> var playgroundRepresentation: PlaygroundRepresentation? { get } >> } >> In both cases, core types which the playground logger supports would conform >> to the appropriate protocol such that they could be returned from >> implementations of playgroundRepresentation. >> >> The benefit to this approach is that it is more self-documenting than the >> approach proposed in this document, as a user can look up all of the types >> which conform to a particular protocol to know what the playground logger >> understands. However, this approach has a number of pitfalls, largely >> because it's intentional that the proposal uses Any instead of a >> more-constrained protocol. It should be possible to return anything as the >> stand-in for an instance, including values without opaque playground quick >> look views, so that it's easier to construct an alternate structured view of >> a type (without having to override the more complex CustomReflectable >> protocol). Furthermore, by making the API in the library use a general type >> like Any, this proposal prevents revlock from occurring between IDEs and the >> libraries, as the IDE's playground logger can implement support for opaque >> logging of new types without requiring library changes. (And IDEs can opt to >> support a subset of types if they prefer, whereas if the libraries promised >> support an IDE would effectively be compelled to provide it.) >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution