<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div class="">
<div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Saagar Jha</div>

</div>
<div><br class=""><blockquote type="cite" class=""><div class="">On Jan 10, 2018, at 14:10, Connor Wakamo &lt;<a href="mailto:cwakamo@apple.com" class="">cwakamo@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 10, 2018, at 12:39 PM, Saagar Jha &lt;<a href="mailto:saagar@saagarjha.com" class="">saagar@saagarjha.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">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&nbsp;<span style="font-family: SFProText-Regular;" class="">playgroundRepresentation on their individual elements as they do currently).</span>&nbsp;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.)</div></div></blockquote><div class=""><br class=""></div><div class="">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.)</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">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 <i class="">could</i>&nbsp;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.</div></div></div></blockquote><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class="">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 <i class="">every</i>&nbsp;instance of every type must be loggable by the playground logger. The PlaygroundLogger framework in&nbsp;<a href="https://github.com/apple/swift-xcode-playground-support" class="">swift-xcode-playground-support</a>&nbsp;implements this by generating either <i class="">structured</i>&nbsp;log entries using `Mirror` or specialized,&nbsp;<i class="">opaque</i>&nbsp;(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.</div><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- If a type conforms to CustomPlaygroundRepresentable and returns a non-nil value, PlaygroundLogger will generate the appropriate log entry for the returned value</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- If a type conforms to CustomPlaygroundRepresentable and returns nil, PlaygroundLogger will generate the appropriate log entry for `self`</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>- 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</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>- Otherwise, PlaygroundLogger will generate a structured log entry</div></div></div></div></blockquote><div><br class=""></div><div>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:</div><div><br class=""></div><div><div style="font-family: SFProText-Regular;" class="">class FooView: UIView {</div><div style="font-family: SFProText-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>override&nbsp;var playgroundRepresentation: Any? {</div><div style="font-family: SFProText-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>return “foo”</div><div style="font-family: SFProText-Regular;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</div><div style="font-family: SFProText-Regular;" class="">}</div><div style="font-family: SFProText-Regular;" class=""><br class=""></div><div style="font-family: SFProText-Regular;" class=""><div class="">class BarView: FooView {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>override&nbsp;var playgroundRepresentation: Any? {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>return nil</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">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.</div></div></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">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`.</div><div class=""><br class=""></div><div class="">Connor</div></div></div></div></blockquote></div><br class=""></body></html>