[squeak-dev] #collect: on strings

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

[squeak-dev] #collect: on strings

Damien Cassou-3
Hi,

is it normal that the following code fails:

'something' collect: [ :letter | letter isVowel ].

It fails because #collect: creates a new string and tries to put
booleans in it. However, I don't think this is the desired behavior.

--
Damien Cassou
Peter von der Ahé: «I'm beginning to see why Gilad wished us good
luck». (http://blogs.sun.com/ahe/entry/override_snafu)

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] #collect: on strings

cedreek
Hi

2008/6/25 Damien Cassou <[hidden email]>:
> Hi,
>
> is it normal that the following code fails:
>
> 'something' collect: [ :letter | letter isVowel ].
>
> It fails because #collect: creates a new string and tries to put
> booleans in it. However, I don't think this is the desired behavior.
>

it seems normal to me

"Evaluate aBlock with each of the receiver's elements as the argument.
Collect the resulting values into a collection like the receiver. Answer
the new collection."

(Array withAll: 'something') collect: [ :letter | letter isVowel ].
#(false true false true false false true false false)

this one works (as with blank):
'something' collect: [ :letter | (letter isVowel ) ifTrue: [letter]
ifFalse: [$.]]. '.o.e..i..'

and you have #select: for the desired behavior
"Evaluate aBlock with each of the receiver's elements as the argument.
Collect into a new collection like the receiver, only those elements for
which aBlock evaluates to true. Answer the new collection."

My 2 cents

Cédrick




> --
> Damien Cassou
> Peter von der Ahé: «I'm beginning to see why Gilad wished us good
> luck». (http://blogs.sun.com/ahe/entry/override_snafu)
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] #collect: on strings

Damien Cassou-3
On Wed, Jun 25, 2008 at 9:39 AM, cdrick <[hidden email]> wrote:
> (Array withAll: 'something') collect: [ :letter | letter isVowel ].
> #(false true false true false false true false false)

I did that

'something' asArray collect: [ :letter | letter isVowel ].

do get the desired behavior. However, it is not intuitive to me.

--
Damien Cassou
Peter von der Ahé: «I'm beginning to see why Gilad wished us good
luck». (http://blogs.sun.com/ahe/entry/override_snafu)

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] #collect: on strings

John Thornborrow
It would be more natural to use #select: for this behaviour, as
#collect: is for the purpose of something like:

'a string' collect: [:each | each asUppercase]

Regards,
John

Damien Cassou wrote:

> On Wed, Jun 25, 2008 at 9:39 AM, cdrick <[hidden email]> wrote:
>> (Array withAll: 'something') collect: [ :letter | letter isVowel ].
>> #(false true false true false false true false false)
>
> I did that
>
> 'something' asArray collect: [ :letter | letter isVowel ].
>
> do get the desired behavior. However, it is not intuitive to me.
>

--
John Thornborrow
http://www.pinesoft.co.uk


******************************************************************************************************************************************
This email is from Pinesoft Limited. Its contents are confidential to the intended recipient(s) at the email address(es) to which it has been addressed. It may not be disclosed to or used by anyone other than the addressee(s), nor may it be copied in anyway. If received in error, please contact the sender, then delete it from your system. Although this email and attachments are believed to be free of virus, or any other defect which might affect any computer or IT system into which they are received and opened, it is the responsibility of the recipient to ensure that they are virus free and no responsibility is accepted by Pinesoft for any loss or damage arising in any way from receipt or use thereof. *******************************************************************************************************************************************


Pinesoft Limited are registered in England, Registered number: 2914825. Registered office: 266-268 High Street, Waltham Cross, Herts, EN8 7EA

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] #collect: on strings

Damien Cassou-3
On Wed, Jun 25, 2008 at 12:01 PM, John Thornborrow <[hidden email]> wrote:
> It would be more natural to use #select: for this behaviour, as #collect: is
> for the purpose of something like:
>
> 'a string' collect: [:each | each asUppercase]

I perfectly know the meaning of collect and I use it correctly,
believe me. You could replace #isVowel by #asciiValue if storing
booleans is a problem for you. The problem is the same.


--
Damien Cassou
Peter von der Ahé: «I'm beginning to see why Gilad wished us good
luck». (http://blogs.sun.com/ahe/entry/override_snafu)

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] #collect: on strings

John Thornborrow
Sorry, I misread your initial mail - I thought you wanted to
collect/select only the vowels, not a collection of booleans!

However on that note, I agree with Cédrick, #collect: should answer the
same species as it's receiver. :)

John

Damien Cassou wrote:

> On Wed, Jun 25, 2008 at 12:01 PM, John Thornborrow <[hidden email]> wrote:
>> It would be more natural to use #select: for this behaviour, as #collect: is
>> for the purpose of something like:
>>
>> 'a string' collect: [:each | each asUppercase]
>
> I perfectly know the meaning of collect and I use it correctly,
> believe me. You could replace #isVowel by #asciiValue if storing
> booleans is a problem for you. The problem is the same.
>
>

--
John Thornborrow
http://www.pinesoft.co.uk


******************************************************************************************************************************************
This email is from Pinesoft Limited. Its contents are confidential to the intended recipient(s) at the email address(es) to which it has been addressed. It may not be disclosed to or used by anyone other than the addressee(s), nor may it be copied in anyway. If received in error, please contact the sender, then delete it from your system. Although this email and attachments are believed to be free of virus, or any other defect which might affect any computer or IT system into which they are received and opened, it is the responsibility of the recipient to ensure that they are virus free and no responsibility is accepted by Pinesoft for any loss or damage arising in any way from receipt or use thereof. *******************************************************************************************************************************************


Pinesoft Limited are registered in England, Registered number: 2914825. Registered office: 266-268 High Street, Waltham Cross, Herts, EN8 7EA

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: #collect: on strings

Nicolas Cellier-3
In reply to this post by Damien Cassou-3
Damien Cassou <damien.cassou <at> gmail.com> writes:

>
> Hi,
>
> is it normal that the following code fails:
>
> 'something' collect: [ :letter | letter isVowel ].
>
> It fails because #collect: creates a new string and tries to put
> booleans in it. However, I don't think this is the desired behavior.
>

That's not only the case with String

(ByteArray with: 255) collect: [:e | e + 1000].
(ShortIntegerArray with: 1) collect: [:e | e + 16r10000].
(FloatArray with: 1.0) collect: [:e | e printString].

Nicolas



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: #collect: on strings

Klaus D. Witzel
In reply to this post by Damien Cassou-3
On Wed, 25 Jun 2008 10:46:49 +0200, Damien Cassou wrote:

> On Wed, Jun 25, 2008 at 9:39 AM, cdrick wrote:
>> (Array withAll: 'something') collect: [ :letter | letter isVowel ].
>> #(false true false true false false true false false)
>
> I did that
>
> 'something' asArray collect: [ :letter | letter isVowel ].
>
> do get the desired behavior. However, it is not intuitive to me.

I agree, in some cases I want to tell #collect: what #species to use (OT:  
and inspired by the LambdaMessageSend package, I have made a snippet which  
does feed #species into otherwise unchanged #collect:).

But what do *you* expect to happen with your original expression, mind to  
share?

>



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: #collect: on strings

Damien Cassou-3
On Wed, Jun 25, 2008 at 4:43 PM, Klaus D. Witzel <[hidden email]> wrote:

> On Wed, 25 Jun 2008 10:46:49 +0200, Damien Cassou wrote:
>
>> On Wed, Jun 25, 2008 at 9:39 AM, cdrick wrote:
>>>
>>> (Array withAll: 'something') collect: [ :letter | letter isVowel ].
>>> #(false true false true false false true false false)
>>
>> I did that
>>
>> 'something' asArray collect: [ :letter | letter isVowel ].
>>
>> do get the desired behavior. However, it is not intuitive to me.
>
> I agree, in some cases I want to tell #collect: what #species to use (OT:
> and inspired by the LambdaMessageSend package, I have made a snippet which
> does feed #species into otherwise unchanged #collect:).
>
> But what do *you* expect to happen with your original expression, mind to
> share?

A collection of boleans.


--
Damien Cassou
Peter von der Ahé: «I'm beginning to see why Gilad wished us good
luck». (http://blogs.sun.com/ahe/entry/override_snafu)

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: #collect: on strings

Klaus D. Witzel
On Wed, 25 Jun 2008 16:48:17 +0200, Damien Cassou wrote:

> On Wed, Jun 25, 2008 at 4:43 PM, Klaus D. Witzel  
> <[hidden email]> wrote:
>> On Wed, 25 Jun 2008 10:46:49 +0200, Damien Cassou wrote:
>>
>>> On Wed, Jun 25, 2008 at 9:39 AM, cdrick wrote:
>>>>
>>>> (Array withAll: 'something') collect: [ :letter | letter isVowel ].
>>>> #(false true false true false false true false false)
>>>
>>> I did that
>>>
>>> 'something' asArray collect: [ :letter | letter isVowel ].
>>>
>>> do get the desired behavior. However, it is not intuitive to me.
>>
>> I agree, in some cases I want to tell #collect: what #species to use  
>> (OT:
>> and inspired by the LambdaMessageSend package, I have made a snippet  
>> which
>> does feed #species into otherwise unchanged #collect:).
>>
>> But what do *you* expect to happen with your original expression, mind  
>> to
>> share?
>
> A collection of boleans.

Well, let's look at #collect: it has a block as argument. Because of this  
object orientedness, the implementor of #collect: cannot know what sort of  
values the block will return in the future, no?

How about this, let #collect: always collect into anOrderedCollection,  
then it can eventually

  ^ anOrderedCollection coercedWith: self

>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] #collect: on strings

Colin Putney
In reply to this post by Damien Cassou-3

On 25-Jun-08, at 1:46 AM, Damien Cassou wrote:

> On Wed, Jun 25, 2008 at 9:39 AM, cdrick <[hidden email]> wrote:
>> (Array withAll: 'something') collect: [ :letter | letter isVowel ].
>> #(false true false true false false true false false)
>
> I did that
>
> 'something' asArray collect: [ :letter | letter isVowel ].
>
> do get the desired behavior. However, it is not intuitive to me.


Let's do a thought experiment. What do you intuitively expect from this?

'something' collect: [:letter | letter asUppercase].

Something other than a String? If it did answer something other than a  
String, would that be more surprising or less surprising than the  
original example?

Colin

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] #collect: on strings

Damien Cassou-3
On Wed, Jun 25, 2008 at 6:35 PM, Colin Putney <[hidden email]> wrote:

>
> On 25-Jun-08, at 1:46 AM, Damien Cassou wrote:
>
>> On Wed, Jun 25, 2008 at 9:39 AM, cdrick <[hidden email]> wrote:
>>>
>>> (Array withAll: 'something') collect: [ :letter | letter isVowel ].
>>> #(false true false true false false true false false)
>>
>> I did that
>>
>> 'something' asArray collect: [ :letter | letter isVowel ].
>>
>> do get the desired behavior. However, it is not intuitive to me.
>
>
> Let's do a thought experiment. What do you intuitively expect from this?
>
> 'something' collect: [:letter | letter asUppercase].
>
> Something other than a String? If it did answer something other than a
> String, would that be more surprising or less surprising than the original
> example?

I'm really expecting a string a here.

--
Damien Cassou
Peter von der Ahé: «I'm beginning to see why Gilad wished us good
luck». (http://blogs.sun.com/ahe/entry/override_snafu)

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: #collect: on strings

Damien Cassou-3
In reply to this post by Klaus D. Witzel
On Wed, Jun 25, 2008 at 4:59 PM, Klaus D. Witzel <[hidden email]> wrote:

> On Wed, 25 Jun 2008 16:48:17 +0200, Damien Cassou wrote:
>
>> On Wed, Jun 25, 2008 at 4:43 PM, Klaus D. Witzel <[hidden email]>
>> wrote:
>>>
>>> On Wed, 25 Jun 2008 10:46:49 +0200, Damien Cassou wrote:
>>>
>>>> On Wed, Jun 25, 2008 at 9:39 AM, cdrick wrote:
>>>>>
>>>>> (Array withAll: 'something') collect: [ :letter | letter isVowel ].
>>>>> #(false true false true false false true false false)
>>>>
>>>> I did that
>>>>
>>>> 'something' asArray collect: [ :letter | letter isVowel ].
>>>>
>>>> do get the desired behavior. However, it is not intuitive to me.
>>>
>>> I agree, in some cases I want to tell #collect: what #species to use (OT:
>>> and inspired by the LambdaMessageSend package, I have made a snippet
>>> which
>>> does feed #species into otherwise unchanged #collect:).
>>>
>>> But what do *you* expect to happen with your original expression, mind to
>>> share?
>>
>> A collection of boleans.
>
> Well, let's look at #collect: it has a block as argument. Because of this
> object orientedness, the implementor of #collect: cannot know what sort of
> values the block will return in the future, no?
>
> How about this, let #collect: always collect into anOrderedCollection, then
> it can eventually
>
>  ^ anOrderedCollection coercedWith: self

What does #coercedWith: mean? I would agree if it is something like:
"try to make a collection of the same species as the parameter with
the content of the receiver and if it is not possible, return the
receiver"




--
Damien Cassou
Peter von der Ahé: «I'm beginning to see why Gilad wished us good
luck». (http://blogs.sun.com/ahe/entry/override_snafu)

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: #collect: on strings

Klaus D. Witzel
On Wed, 25 Jun 2008 22:37:52 +0200, Damien Cassou wrote:

> On Wed, Jun 25, 2008 at 4:59 PM, Klaus D. Witzel
...

>>>> But what do *you* expect to happen with your original expression,  
>>>> mind to share?
>>>
>>> A collection of boleans.
>>
>> Well, let's look at #collect: it has a block as argument. Because of  
>> this
>> object orientedness, the implementor of #collect: cannot know what sort  
>> of
>> values the block will return in the future, no?
>>
>> How about this, let #collect: always collect into anOrderedCollection,  
>> then it can eventually
>>
>>  ^ anOrderedCollection coercedWith: self
>
> What does #coercedWith: mean? I would agree if it is something like:
> "try to make a collection of the same species as the parameter with
> the content of the receiver and if it is not possible, return the
> receiver"

Right. It would perhaps ask (argument #couldStore: anElement) and,  
ifFalse, return a #copyFrom:to: of its array (Array should be the default,  
IHMO). And if all pass then

  ^ argument species withAll: self

For sure this all could also be moved right into the #collect: method,  
might perform a bit faster. But anyways, things seem to have such price  
tag.

>


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: #collect: on strings

Nicolas Cellier-3
Klaus D. Witzel a écrit :

> On Wed, 25 Jun 2008 22:37:52 +0200, Damien Cassou wrote:
>
>> On Wed, Jun 25, 2008 at 4:59 PM, Klaus D. Witzel
> ...
>>>>> But what do *you* expect to happen with your original expression,
>>>>> mind to share?
>>>>
>>>> A collection of boleans.
>>>
>>> Well, let's look at #collect: it has a block as argument. Because of
>>> this
>>> object orientedness, the implementor of #collect: cannot know what
>>> sort of
>>> values the block will return in the future, no?
>>>
>>> How about this, let #collect: always collect into
>>> anOrderedCollection, then it can eventually
>>>
>>>  ^ anOrderedCollection coercedWith: self
>>
>> What does #coercedWith: mean? I would agree if it is something like:
>> "try to make a collection of the same species as the parameter with
>> the content of the receiver and if it is not possible, return the
>> receiver"
>
> Right. It would perhaps ask (argument #couldStore: anElement) and,
> ifFalse, return a #copyFrom:to: of its array (Array should be the
> default, IHMO). And if all pass then
>

Another pattern: rather than testing #couldStore: as a precondition
inside the loop, do handle the Exception outside the loop.
But write the handler so as to not iterate twice on already iterated
elements (the block might have side effects).

>  ^ argument species withAll: self
>
> For sure this all could also be moved right into the #collect: method,
> might perform a bit faster. But anyways, things seem to have such price
> tag.
>

Simplicity of workaround: 'abc' asArray collect: [...] will be hard to beat.
It's probably not worth trying to save the cost of additional asArray
iteration, given the complexification and de-optimization of code
implied by genericity.

This makes my vote go to a statu quo.

Nicolas


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: #collect: on strings

Stéphane Rollandin
nicolas cellier a écrit :
> Simplicity of workaround: 'abc' asArray collect: [...] will be hard to
> beat.
> It's probably not worth trying to save the cost of additional asArray
> iteration, given the complexification and de-optimization of code
> implied by genericity.
>
> This makes my vote go to a statu quo.

+1

Stef


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: #collect: on strings

Klaus D. Witzel
In reply to this post by Nicolas Cellier-3
On Thu, 26 Jun 2008 00:18:08 +0200, Nicolas wrote:

> Klaus D. Witzel a écrit :
>> On Wed, 25 Jun 2008 22:37:52 +0200, Damien Cassou wrote:
>>
>>> On Wed, Jun 25, 2008 at 4:59 PM, Klaus D. Witzel
>> ...
>>>>>> But what do *you* expect to happen with your original expression,  
>>>>>> mind to share?
>>>>>
>>>>> A collection of boleans.
>>>>
>>>> Well, let's look at #collect: it has a block as argument. Because of  
>>>> this
>>>> object orientedness, the implementor of #collect: cannot know what  
>>>> sort of
>>>> values the block will return in the future, no?
>>>>
>>>> How about this, let #collect: always collect into  
>>>> anOrderedCollection, then it can eventually
>>>>
>>>>  ^ anOrderedCollection coercedWith: self
>>>
>>> What does #coercedWith: mean? I would agree if it is something like:
>>> "try to make a collection of the same species as the parameter with
>>> the content of the receiver and if it is not possible, return the
>>> receiver"
>>  Right. It would perhaps ask (argument #couldStore: anElement) and,  
>> ifFalse, return a #copyFrom:to: of its array (Array should be the  
>> default, IHMO). And if all pass then
>>
>
> Another pattern: rather than testing #couldStore: as a precondition  
> inside the loop, do handle the Exception outside the loop.

Sure. BTW #couldStore: can be replaced by the VM's unwillingness to store,  
say of Damien's boolean into an instance of String--and so wouldn't cost  
anything besides the handler and its work.

> But write the handler so as to not iterate twice on already iterated  
> elements (the block might have side effects).
>
>>  ^ argument species withAll: self
>>  For sure this all could also be moved right into the #collect: method,  
>> might perform a bit faster. But anyways, things seem to have such price  
>> tag.
>>
>
> Simplicity of workaround: 'abc' asArray collect: [...] will be hard to  
> beat.

Except when you don't want/can make a copy/#asArray of the source  
collection.

> It's probably not worth trying to save the cost of additional asArray  
> iteration, given the complexification and de-optimization of code  
> implied by genericity.
>
> This makes my vote go to a statu quo.

And by code duplication, #collect:into: could do the job ;)

> Nicolas
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: #collect: on strings

Bert Freudenberg
Am 26.06.2008 um 08:11 schrieb Klaus D. Witzel:
> And by code duplication, #collect:into: could do the job ;)


If you indeed need this, I'd propose as:collect:.

- Bert -



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: #collect: on strings

Klaus D. Witzel
On Thu, 26 Jun 2008 09:23:57 +0200, Bert wrote:

> Am 26.06.2008 um 08:11 schrieb Klaus D. Witzel:
>> And by code duplication, #collect:into: could do the job ;)
>
> If you indeed need this, I'd propose as:collect:.

That's even better :) Example on Damien's:

  'something' as: Array collect: [ :letter | letter isVowel ]

And it can be less "confusing" than my lambda meta programming:

  'something' <+ #species +> Array collect: [ :letter | letter isVowel ]
  "when #species is sent by #collect: answer Array"

though my intention with #<+,#+> is to avoid code duplication ;)

> - Bert -
>



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: #collect: on strings

Damien Cassou-3
In reply to this post by Bert Freudenberg
On Thu, Jun 26, 2008 at 9:23 AM, Bert Freudenberg <[hidden email]> wrote:
> Am 26.06.2008 um 08:11 schrieb Klaus D. Witzel:
>>
>> And by code duplication, #collect:into: could do the job ;)
>
>
> If you indeed need this, I'd propose as:collect:.

+1

--
Damien Cassou
Peter von der Ahé: «I'm beginning to see why Gilad wished us good
luck». (http://blogs.sun.com/ahe/entry/override_snafu)

12