[stdlib] Array.description calls debugDescription on its contents


(Wojciech Czekalski) #1

Hi,

while I was working on this <https://github.com/apple/swift/pull/348> PR I encountered unexpected behavior from Array.description. It iterates over its items and calls debugDescription on them. I found it a bit unexpected thus my question here. Is it desired behavior? I would expect description and debugDescription call respective methods on the contents.

(I asked the same question in the PR but thought it’s general, so might be worth posting here)


Printing Foundation objects shows only class names, no values
(Dmitri Gribenko) #2

Array's description shouldn't be presented to the user in raw form, ever,
so the use case here is debugging. Thus, it makes sense to present the
debug representation of the elements in both cases. Consider an array of
strings:

var myArray = [ "", "", "" ]

If we used the regular description, then String(myArray) would be "[ , ,
]", which looks like a library bug.

Dmitri

···

On Fri, Dec 11, 2015 at 1:38 PM, Wojciech Czekalski via swift-dev < swift-dev@swift.org> wrote:

Hi,

while I was working on this <https://github.com/apple/swift/pull/348> PR
I encountered unexpected behavior from Array.description. It iterates
over its items and calls debugDescription on them. I found it a bit
unexpected thus my question here. Is it desired behavior? I would expect
description and debugDescription call respective methods on the contents.

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Brent Royal-Gordon) #3

while I was working on this PR I encountered unexpected behavior from Array.description. It iterates over its items and calls debugDescription on them. I found it a bit unexpected thus my question here. Is it desired behavior? I would expect description and debugDescription call respective methods on the contents.

Array's description shouldn't be presented to the user in raw form, ever, so the use case here is debugging. Thus, it makes sense to present the debug representation of the elements in both cases.

I keep noticing threads where people are confused about this kind of thing—I’ve seen it with Array, Optional, and several others. I wonder if these kinds of types simply *shouldn’t* offer .description properties, as a way of saying “no user-visible conversion inside”.

···

--
Brent Royal-Gordon
Architechies


(Dmitri Gribenko) #4

Nobody should be using '.description' or '.debugDescription' directly
in any case. One should be using String(x) or String(reflecting: x),
because that works with any instances, including those cases when the
runtime will synthesize the string representation for you.

Dmitri

···

On Fri, Dec 11, 2015 at 3:02 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

while I was working on this PR I encountered unexpected behavior from Array.description. It iterates over its items and calls debugDescription on them. I found it a bit unexpected thus my question here. Is it desired behavior? I would expect description and debugDescription call respective methods on the contents.

Array's description shouldn't be presented to the user in raw form, ever, so the use case here is debugging. Thus, it makes sense to present the debug representation of the elements in both cases.

I keep noticing threads where people are confused about this kind of thing—I’ve seen it with Array, Optional, and several others. I wonder if these kinds of types simply *shouldn’t* offer .description properties, as a way of saying “no user-visible conversion inside”.

--
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr@gmail.com>*/


(Brent Royal-Gordon) #5

Nobody should be using '.description' or '.debugDescription' directly
in any case. One should be using String(x) or String(reflecting: x),
because that works with any instances, including those cases when the
runtime will synthesize the string representation for you.

It would similarly be nice if String.init(_: Any) were instead String.init(_: CustomStringConvertible), and passing something to it that wasn’t convertible was an error. Similarly for string interpolation (although particular types would need a way to specify additional interpolatable types they supported).

···

--
Brent Royal-Gordon
Architechies


(Dave Abrahams) #6

It would similarly be nice if String.init(_: Any) were instead String.init(_: CustomStringConvertible), and passing something to it that wasn’t convertible was an error.

Why would that be nice? It is an explicit goal that every type can be represented as a string, whatever its conformance a, FWIW

···

Sent from my moss-covered three-handled family gradunza

On Dec 12, 2015, at 9:09 AM, Brent Royal-Gordon via swift-dev <swift-dev@swift.org> wrote:


(Wojciech Czekalski) #7

I agree with Brent that offering description on Arrays where it "shouldn't be presented to the user in raw form, ever, so the use case here is debugging” is misleading. Is there any specific reason for them to offer it? Also, there is a slightly difference in representation of description and debugDescription for ContiguousArray and ArraySlice. If the motivation behind it is unclear it might be worth to remove either the difference in implementation or the conformance to CustomStringConvertible altogether.

-Wojtek

···

Wiadomość napisana przez Dave Abrahams via swift-dev <swift-dev@swift.org> w dniu 12.12.2015, o godz. 21:41:

Sent from my moss-covered three-handled family gradunza

On Dec 12, 2015, at 9:09 AM, Brent Royal-Gordon via swift-dev <swift-dev@swift.org> wrote:

It would similarly be nice if String.init(_: Any) were instead String.init(_: CustomStringConvertible), and passing something to it that wasn’t convertible was an error.

Why would that be nice? It is an explicit goal that every type can be represented as a string, whatever its conformance a, FWIW
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


(Dave Abrahams) #8

I agree with Brent that offering description on Arrays where it "shouldn't be presented to the user in raw form, ever, so the use case here is debugging” is misleading.

I think it's a bit too absolute—there are a few applications where users could interact with the raw form of an array but these are mostly programming tools ;-). I don't, however see how Dmitri's statement is in any way misleading.

Is there any specific reason for them to offer it?

Who is "them" and what is "it?"

Also, there is a slightly difference in representation of description and debugDescription for ContiguousArray and ArraySlice. If the motivation behind it is unclear it might be worth to remove either the difference in implementation or the conformance to CustomStringConvertible altogether.

Removing the conformance would make their printed representation useless and/or needlessly verbose depending on how you did it (try it yourself).

Dmitri's example is the driving use-case: when you print a string you want the literal contents, but when you print an array of strings you want the strings quoted, and to get the quoted representation of the elements when they are strings you need String(reflecting: arrayElement), not String(arrayElement).

-Wojtek

Wiadomość napisana przez Dave Abrahams via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> w dniu 12.12.2015, o godz. 21:41:

Sent from my moss-covered three-handled family gradunza

It would similarly be nice if String.init(_: Any) were instead String.init(_: CustomStringConvertible), and passing something to it that wasn’t convertible was an error.

Why would that be nice? It is an explicit goal that every type can be represented as a string, whatever its conformance a, FWIW
_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

-Dave

···

On Dec 13, 2015, at 12:43 PM, Wojciech Czekalski <wczekalski@me.com> wrote:

On Dec 12, 2015, at 9:09 AM, Brent Royal-Gordon via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:


(Dave Abrahams) #9

I agree with Brent that offering description on Arrays where it "shouldn't be presented to the user in raw form, ever, so the use case here is debugging” is misleading.

I think it's a bit too absolute—there are a few applications where users could interact with the raw form of an array but these are mostly programming tools ;-). I don't, however see how Dmitri's statement is in any way misleading.

Is there any specific reason for them to offer it?

Who is "them" and what is "it?"

Sorry, I didn't read carefully enough: I think you're saying that it's misleading for Arrays to offer a description property.

I don't think so, personally, but I understand why you'd say so. If the problem is that you don't understand why ContiguousArray and ArraySlice have slightly different behavior for debugDescription, it's because an unadorned array literal is already an Array, but ContiguousArray and ArraySlice need some help to be coerced, and ideally, a debugDescription should be interpreted by the compiler as an identical copy of the receiver.

Also, there is a slightly difference in representation of description and debugDescription for ContiguousArray and ArraySlice. If the motivation behind it is unclear it might be worth to remove either the difference in implementation or the conformance to CustomStringConvertible altogether.

Removing the conformance would make their printed representation useless and/or needlessly verbose depending on how you did it (try it yourself).

Dmitri's example is the driving use-case: when you print a string you want the literal contents, but when you print an array of strings you want the strings quoted, and to get the quoted representation of the elements when they are strings you need String(reflecting: arrayElement), not String(arrayElement).

-Wojtek

Wiadomość napisana przez Dave Abrahams via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> w dniu 12.12.2015, o godz. 21:41:

Sent from my moss-covered three-handled family gradunza

It would similarly be nice if String.init(_: Any) were instead String.init(_: CustomStringConvertible), and passing something to it that wasn’t convertible was an error.

Why would that be nice? It is an explicit goal that every type can be represented as a string, whatever its conformance a, FWIW
_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

-Dave

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev

-Dave

···

On Dec 13, 2015, at 11:08 PM, Dave Abrahams via swift-dev <swift-dev@swift.org> wrote:

On Dec 13, 2015, at 12:43 PM, Wojciech Czekalski <wczekalski@me.com <mailto:wczekalski@me.com>> wrote:

On Dec 12, 2015, at 9:09 AM, Brent Royal-Gordon via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: