Transcript: printString or asString

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Transcript: printString or asString

arcanosam
Hi folks.
I'm starting in Pharo studies by FUN Mooc.
In Week 03, on An Overview of Essential Collections there is the example below:

| days |
days := Dictionary new.

days
at: #January put: 31;
at: #February put: 28;
at: #March put: 31.

days keysAndValuesDo:
[ :k :v | Transcript show: k asString, ' has ', v printString, ' days'
; cr ]


The code in blue I change for 

days keysAndValuesDo:
[ :k :v | Transcript show: k asString, ' has ', v asString, ' days'
; cr ]

And works too on Playground.

There is something different about both? There is someone better than other?

Thanks in advance,


Samuel T. Santos
and so we lay... we lay in the same grave....
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

Tim Mackinnon

Hi - While I’m sure everyone can give you an answer - it’s more useful to teach you how to answer these questions for your self.  

Try right clicking with your cursor on asString and choose “implementors of” (it may have a slightly different name friending on Pharo version - or press “meta”-m. Do the same for printString and compare the results. Also, do the same using  “senders of” (meta-n).

Most code in Pharo is explorable like this, and you can generally answer most questions by seeing his other code in the system interacts or uses what you are exploring.

Tim


Sent from my iPhone

On 13 Oct 2019, at 11:50, Samuel Teixeira Santos <[hidden email]> wrote:

Hi folks.
I'm starting in Pharo studies by FUN Mooc.
In Week 03, on An Overview of Essential Collections there is the example below:

| days |
days := Dictionary new.

days
at: #January put: 31;
at: #February put: 28;
at: #March put: 31.

days keysAndValuesDo:
[ :k :v | Transcript show: k asString, ' has ', v printString, ' days'
; cr ]


The code in blue I change for 

days keysAndValuesDo:
[ :k :v | Transcript show: k asString, ' has ', v asString, ' days'
; cr ]

And works too on Playground.

There is something different about both? There is someone better than other?

Thanks in advance,


Samuel T. Santos
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

arcanosam
Hi Tim.

I just learned in previous videos of the mooc about using nautilus to explore using "Implementers of..." or "Senders of..."

I will do that for sure now.

Thanks for your tip. 


Regards
and so we lay... we lay in the same grave....
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

Richard O'Keefe
In reply to this post by arcanosam
days keysAndValuesDo: [:key :value |
    Transcript print: key; nextPutAll: ' has '; print: value;
nextPutAll: ' days'; cr].
Transcript endEntry.
works too and in some Smalltalks is easily the most efficient approach, as it
does not construct any strings you have no other use for.

In Pharo, however, there is a reason to prefer
    Transcript nextPutAll: (key asString, ' has ', value asString, '
days', String cr).
The reason is that in Pharo 7, Transcript is an instance of
*ThreadSafe*Transcript,
and each public operation like #nextPut: or #print: locks the stream.
In fact we have
    show: anObject
      self critical: [self print: anObject; endEntry].
    print: anObject
      self nextPutAll: anObject asString.
    nextPutAll: aString
      self critical: [stream nextPutAll: aString].
      ^aString
    cr
      self nextPut: Character cr.
    nextPut: aCharacter
      self critical: [stream nextPut: aCharacter].
      ^aCharacter

So the code I exhibited second (using #nextPutAll:) locks the Transcript *once*
ensuring that nothing else can be written between 'days' and cr, whereas both
versions you exhibited have a timing window between #show: and #cr where
another Smalltalk process could write something.

But you are asking about the difference between #asString and #printString.
So look up the definitions!  In a Playground, type
asString
and then Ctrl-m (for iMplementors).  We see almost at once that
Object>>
    asString
      ^self printString
so that for numbers there is NO difference between the two (except a
little bit of
overhead for #asString).  But we also see
String>>
    asString
      ^self
Symbol>>
    asString
      "complicated code logically equivalent to"
      ^String withAll: self
Just for grins, the following interaction was with GNU Smalltalk.
st> #January asString
'January'
st> #January printString
'#January'
st> 31 asString
'31'
st> 31 printString
'31'
Pharo does exactly the same.

On Sun, 13 Oct 2019 at 23:51, Samuel Teixeira Santos
<[hidden email]> wrote:

>
> Hi folks.
> I'm starting in Pharo studies by FUN Mooc.
> In Week 03, on An Overview of Essential Collections there is the example below:
>
> | days |
> days := Dictionary new.
>
> days
> at: #January put: 31;
> at: #February put: 28;
> at: #March put: 31.
>
> days keysAndValuesDo:
> [ :k :v | Transcript show: k asString, ' has ', v printString, ' days'
> ; cr ]
>
> The code in blue I change for
>
> days keysAndValuesDo:
> [ :k :v | Transcript show: k asString, ' has ', v asString, ' days'
> ; cr ]
>
> And works too on Playground.
>
> There is something different about both? There is someone better than other?
>
> Thanks in advance,
>
>
> Samuel T. Santos

Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

arcanosam
Thank you too Richard.

Very interesting and elucidative.

Regards to all.
and so we lay... we lay in the same grave....
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

Sean P. DeNigris
Administrator
In reply to this post by arcanosam
arcanosam wrote
> printString... v asString... There is something different about both?

I will add that conceptually:
- #printString = what a developer would want to see, e.g. in an inspector
- #displayString = a string suitable for UI (i.e. in production)
- #asString - while typically implemented to be the same as #printString,
the meaning for me is a bit different, which is "what this object converted
to a string means in my domain"

That said, IMHO as a community we are not great about properly
distinguishing these, especially #displayString.



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

arcanosam
I like the way you put because it's a nice way to remember and to teach too.

I'm just bit confusing, and I think this because Object Oriented it's not one of my strong skills, when you say when: "what this object converted to a string means in my domain" - what really means, specially about when you say 'domain'?

Could you give some example for this?

Thanks 
and so we lay... we lay in the same grave....
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

Christopher Fuhrman-3
On Mon, Oct 14, 2019, 08:49 Samuel Teixeira Santos <[hidden email]> wrote:
when you say when: "what this object converted to a string means in my domain" - what really means, specially about when you say 'domain'?

Could you give some example for this?

Thanks 

A good example might be PLU codes [1] on produce in North America. They're 4 or 5 digits, and employees of a grocery store usually know them by heart (they're in the "employee of a grocery store" domain). Customers, however, are interested in knowing what the vegetable or fruit is, not the code. 

So, depending on the application domain, #asString might print the code (for grocery store employees) or the name of the item (for customers).

Delving deeper, we find these codes even contain info about whether produce is GMO, organic, etc. which could also be used by #asString depending on requirements.

Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

arcanosam
Very clear to me now.

Thank you and to others too by your previous answers
and so we lay... we lay in the same grave....
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

Richard Sargent
Administrator
Samuel,

One thing I don't recall seeing in this thread is a discussion of the semantics of the methods names.

I find it helpful to consider #asWhatever to be a conversion method, used to convert one object to another essentially compatible class. e.g. #asFloat sent to an integer would be expected to yield a floating point number with the same value, but #asInteger sent to a floating point number would lose precision but might still be sensible for some purposes. [more on this below]

But, #printString and its ilk (#displayString, #storeString, others) are not intended to be conversion methods. They are to provide an external representation of a format suitable for the intended audience. Typically, (and I say that guardedly), #printString's intended audience is the programmers working on the system and #displayString is intended for the system's users.

In simple cases, #printString is reversible and can be parsed to recover the value of the original object. In general, it doesn't include enough information to do so. The same is true of #displayString. If we consider a slightly more complex example than a number, consider a User Profile. Its #printString might be 'UserProfile(John Doe)'. Its #displayString might be 'John Doe'. Neither of those provide all the details of the object, although they could be parsed and so used to look up an existing object.


----------
Continuing from [more on this below] above...

I find #asString is one of the most problematic methods that I have ever seen. It is deceptive, an "attractive nuisance", as one colleague liked to say. Clarity comes from being explicit in one's programming. Say what you mean and mean what you say. If you are trying to convert from one object form to another, use a conversion method whose name is precise. If you are trying to provide information for a programmer about an object, #printString is the choice.(e.g. in a stack dump).

As a general rule, #asWhatever methods that are generally applicable to the set of possible values. e.g. number conversion methods are a good example, even though there are exceptions (loss of precision, NaN, and Inf are some).


I have seen a lot of #asWhatever methods added to the String hierarchy, but almost all of them are dubious, in my opinion of course. Most strings are not numbers, for example. String>>#asNumber is one of the worst things I have ever seen, both from a consistency perspective and an implementation perspective. 'abc123def456' asNumber has more variant results than I can enumerate.



On Mon, Oct 14, 2019 at 9:28 AM Samuel Teixeira Santos <[hidden email]> wrote:
Very clear to me now.

Thank you and to others too by your previous answers
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

arcanosam
Hi Richard.

Very useful your considerations. I find too the messages like #asWhatever, like you said, were about type conversions, similar like we have in other languages.

#printString and the others remember me the special method in Python __str__ or __unicode__ which allow change the default representation of object you dealing of.

Thank you, I will pay attention when dealing with this messages
and so we lay... we lay in the same grave....
Reply | Threaded
Open this post in threaded view
|

Re: Transcript: printString or asString

Richard O'Keefe
It may be worth noting that the 1998 ANSI Smalltalk standard defines
#asString for
Character, <readableString>, String, and Symbol and for those classes only.
VisualWorks extends #asString to things like Filename and URIs and Text and
several other things for which "convert to String" makes sense and are not
locale-dependent.  VW does *not* extend #asString to Object.
Visual Age Smalltalk *does* define Object>>asString ^self printString
but overrides this so that nil asString => ''.
Put it this way: if you use #asString for anything that is not some
kind of text or
some kind of 'locator' having an externally defined representation which can
be converted back to an equal 'locator' (file name, URI, network host name,
X11 font, ISO country currency or language code), don't expect your code to
be even close to portable.

On Wed, 16 Oct 2019 at 00:13, Samuel Teixeira Santos
<[hidden email]> wrote:
>
> Hi Richard.
>
> Very useful your considerations. I find too the messages like #asWhatever, like you said, were about type conversions, similar like we have in other languages.
>
> #printString and the others remember me the special method in Python __str__ or __unicode__ which allow change the default representation of object you dealing of.
>
> Thank you, I will pay attention when dealing with this messages