Saagar Jha

> On Jan 10, 2018, at 14:10, Connor Wakamo <> wrote:
>> On Jan 10, 2018, at 12:39 PM, Saagar Jha < 
>> <>> wrote:
>> Well, in my experience performance issues tend to come not from trying to 
>> display a single object, but when you have an aggregation of many objects. 
>> For example, displaying one Int is pretty lightweight, as is an [Int] with a 
>> handful of elements, but displaying an [Int] with million elements is not 
>> (this is assuming that collections will run the playgroundRepresentation on 
>> their individual elements as they do currently). I don’t think the current 
>> proposal can solve this issue as it’s pitched currently. (For those curious, 
>> this doesn’t have a good solution today, either: the best “solution” I’ve 
>> been able to come up with is to move performance-sensitive out into a 
>> Playground’s Sources folder, which isn’t displayed.)
> Yes, this proposal does not affect this case: the playground transform will 
> still instrument all of the source code in the main source file. This 
> proposal is merely about deprecating/removing a substandard API for 
> controlling how values are presented in playgrounds with a better, more 
> flexible one. (Though see my other reply to Chris where I present an 
> alternative which could be extended to include support for disabling logging 
> altogether for an instance.)
>> Fundamentally, I don’t think it’s clear what the “default” value is supposed 
>> to be: we already have three different interpretations of what it could do: 
>> do literally nothing (i.e. display an empty representation), use a 
>> superclass’s representation, or use a structural representation based on 
>> whether the type is an enum, struct, class, etc. I think we need to clear up 
>> what the default actually means (and if we even need it at all) before we 
>> can proceed.
> This API is a bit wishy-washy as to what the “default” is. That’s somewhat 
> intentional — the default presentation of an arbitrary Swift value/object is 
> defined by the IDE, not by an API in Swift. I think my terminology is a bit 
> confused here, and I’ll try to address that in a revision of the proposal. 
> Let me try to clarify this a bit:
> The fundamental design of playgrounds is that the compiler will insert calls 
> to a logging function which is effectively required to take an `Any`. So 
> therefore every instance of every type must be loggable by the playground 
> logger. The PlaygroundLogger framework in swift-xcode-playground-support 
> <> implements this by 
> generating either structured log entries using `Mirror` or specialized, 
> opaque (aka IDERepr) log entries. PlaygroundLogger will generate a structured 
> log entry for most instances, but for instances of special types it knows 
> about (e.g. String, Int, NSColor, UIView, etc.) it will generate an opaque 
> log entry which an IDE can then consume and display as is appropriate.
> The CustomPlaygroundRepresentable API I’ve proposed does exactly one thing: 
> it allows instances of conforming types to provide an optional stand-in to be 
> used by the playground logger. So PlaygroundLogger would handle the following 
> cases thusly:
>       - If a type conforms to CustomPlaygroundRepresentable and returns a 
> non-nil value, PlaygroundLogger will generate the appropriate log entry for 
> the returned value
>       - If a type conforms to CustomPlaygroundRepresentable and returns nil, 
> PlaygroundLogger will generate the appropriate log entry for `self`
>               - If `self` is one of the types (or a subclass of one of the 
> types) for which PlaygroundLogger generates an opaque entry, PlaygroundLogger 
> will generate an opaque log entry
>               - Otherwise, PlaygroundLogger will generate a structured log 
> entry

Just wanted to make it totally clear here: is the superclass selected the one 
that is the closest to the current type, or the one that is the most distant 
parent? Referring back to the example I had further upthread:

class FooView: UIView {
        override var playgroundRepresentation: Any? {
                return “foo”

class BarView: FooView {
        override var playgroundRepresentation: Any? {
                return nil

Does BarView show up as a UIView, or a FooView? If it’s shown as a FooView, 
then returning nil is superfluous: you can just not override 
playgroundRepresentation and it’ll pick up the one from FooView.

> This process if potentially recursive (likely up to an implementation-defined 
> limit): if `Foo: CustomPlaygroundRepresentable` and `Bar: 
> CustomPlaygroundRepresentable`, and a `Foo` instance returns an instance of 
> `Bar` from `playgroundRepresentation`, then the playground logger should 
> effectively log `self.playgroundRepresentation.playgroundRepresentation`.
> Connor

swift-evolution mailing list

Reply via email to