> On Jan 12, 2018, at 11:02 PM, Chris Lattner <clatt...@nondot.org> wrote:
>> On Jan 12, 2018, at 6:22 PM, Connor Wakamo <cwak...@apple.com 
>> <mailto:cwak...@apple.com>> wrote:
>>>> The second case, and the one I’m more worried about, is subclassing. If, 
>>>> for instance, you have the following:
>>>>    class FooView: UIView, CustomPlaygroundRepresentable {
>>>>            var playgroundRepresentation: Any {
>>>>                    return “A string describing this view"
>>>>            }
>>>>    }
>>>>    class BarView: FooView {
>>>>            override var playgroundRepresentation: Any {
>>>>                    // BarView instances wanted to be logged as themselves, 
>>>> but there’s no way to express that
>>>>                    return ???
>>>>            }
>>>>    }
>>>> There’s nothing that BarView can do to ensure it gets logged like a view 
>>>> because FooView declared a conformance to CustomPlaygroundRepresentable.
>>> I really don’t understand this.  FooView declares that it conforms, and it 
>>> provides a “playgroundRepresentation” member.  Cool for FooView.
>>> BarView comes around and overrides FooView’s implementation.  They don’t 
>>> have to conform, because it *isa* FooView, so of course it conforms.  If it 
>>> wants to customize its presentation, it overrides its  
>>> “playgroundRepresentation” method and it… just works.  If it conditionally 
>>> wants the FooView representation for some reason, it can even call 
>>> “super.playgroundRepresentation”.  What’s the problem?  This seems ideal to 
>>> me.
>> The issue is that there’s no way for `BarView` to recover the default 
>> playground representation which `UIView` and its subclasses get.
> I get it now, thanks.
>> For a `UIView`, the PlaygroundLogger library renders an image of the view 
>> and packages that up in a log entry. If `BarView` wants that instead of 
>> `FooView`’s custom representation, there’s no way for it to request it.
> I can think of two different ways to solve this problem:
> 1) Go with your suggestion upthread, where a custom enum is used: 
> implementations do:
>   if predicate() {
>     return .custom(“my representation)
>   } else {
>     return .default
>   }
> The problem with this is that you’re forcing implementations of this to deal 
> with the enum just because of the rare case.  Not a showstopper, but doesn’t 
> feel right.
> 2) Go with the simple approach of returning Any, and add a new function to 
> the Playground API somewhere that produces the default representation that 
> they can call, the unusual case above would look like this:
>   if predicate() {
>     return “my representation
>   } else {
>     return SomePlaygroundAPI.getDefaultPlaygroundRepresentation(self)
>   }
> This seems like the best of both worlds to me.

Yes, agreed. I’m not going to propose adding this to PlaygroundSupport as part 
of this proposal (under the assumption that this is an extreme edge case to 
begin with), but I’ll include a reference to it in the “alternatives 
considered” section so it can be referenced in the future should this be 
important enough that it warrants support.

>>> IMO, every time you choose to privilege “well known” types in the standard 
>>> library with special code in Xcode (or some other high level system loosely 
>>> integrated with swift.org <http://swift.org/>) you are introducing 
>>> technical debt into the Swift ecosystem.  This is because you are violating 
>>> the basic principles on which Swift was established, which is that users 
>>> can [re]define primitives to build their own abstractions and carve out new 
>>> domains beyond what was originally envisioned when you’re writing the UI 
>>> code.
>> So given that, I think it’s not unreasonable for a platform/toolchain’s 
>> playground logger to know about that platform/toolchain’s important types so 
>> it can produce the appropriate opaque log entries. If there’s some approach 
>> that I’m overlooking — or if I’m dismissing the suite of protocols case too 
>> quickly — I would love to hear it, because I’m open to suggestions.
> Yes, you are completely right: Unless you are willing to make the structured 
> schema public, there is no point to doing what I suggest.
> I do think that there is a schema which would make sense to take public 
> (similar to the abstract format used in treeviews like the navigator and UI 
> debugger for variables, strikingly similar to what JSON can express with a 
> fancier terminal than strings), but there is no rush to do that, and it is 
> best to take time to consider it deliberately.

Likewise, agreed — I don’t want to try to figure out what that would look like 
with the time pressure imposed by trying to get this in Swift 4.1 prior to ABI 
stability. And even in a world where this is exposed in a way to allow custom 
implementations at that low level, I think that a 
`CustomPlaygroundConvertible`-style API is still useful as the simple way of 
customizing display for most clients.


>>> Is the problem the “one” case?  If that is the problem, then it might be 
>>> better to take a completely different approach where you embrace the fact 
>>> that you have structured data producing 2D results that need to be 
>>> displayed.  Each result could either return an atomic result or a result 
>>> that wraps some other recursive 2D presentation.
>> No, the issue is that the playground logger would see that `Foo.two` 
>> conforms to `CustomPlaygroundConvertible`, and would therefore call 
>> `playgroundDescription` another time, which would return another `Foo.two`, 
>> and this would continue endlessly. I plan to guard against that in 
>> PlaygroundLogger with a limit on chaining, but this protocol should not 
>> require a failsafe as a feature.
> Right, it seems like the best way to solve this is to provide explicit access 
> to the default presentation.
> -Chris

swift-evolution mailing list

Reply via email to