Smalltalk string API

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

Smalltalk string API

Nicolas Cellier
I started referencing Smalltalk idioms at
http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)
I could have focused on ANSI but have chosen Squeak/Pharo. Feel free
to correct me and to complete me.

This is a very enlighting exercize, especially for pointing when API
turns to be not that bright.
During my perigrination, I notably noticed this:

#compare: returns 1, 2, or 3 : this is both very object oriented, very
intuitive and very standard and the rest of the world is stupid,
unless...

#findLastOccurrenceOfString:startingAt: in its current form is stupid
to my taste, because
1) implementation is inefficient
2) the startingAt: only skip the beginning of the string which seems
odd for a rfind operation
I would rather expect this kind of usage:
last := aString findLastOccurrenceOfString: 'to' startingAt: aString size.
lastButOne := aString findLastOccurrenceOfString: 'to' startingAt: last - 1.

The CamelCase is sometimes abusive like #includesSubString:

There is no format. I know, purists will tell me that encoding a
format in a cryptic string is not in the Smalltalk spirit, but please
then tell me how to specify a formatting efficiently and also remove
cryptic regex encoding (a pity, it's not in trunk).

I let a few holes (split/join etc...)

Cheers

Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] Smalltalk string API

SergeStinckwich
On Wed, Feb 16, 2011 at 4:24 PM, Nicolas Cellier
<[hidden email]> wrote:

> I started referencing Smalltalk idioms at
> http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)
> I could have focused on ANSI but have chosen Squeak/Pharo. Feel free
> to correct me and to complete me.
>
> This is a very enlighting exercize, especially for pointing when API
> turns to be not that bright.
> During my perigrination, I notably noticed this:
>
> #compare: returns 1, 2, or 3 : this is both very object oriented, very
> intuitive and very standard and the rest of the world is stupid,
> unless...

Yes, really stupid, but maybe Squeak/Pharo should align here to the
rest of the world or
better, remove this method. We could use comparaison methods instead: <, >, ...

--
Serge Stinckwich
UMI UMMISCO 209 (IRD/UPMC), Hanoi, Vietnam
Every DSL ends up being Smalltalk
http://doesnotunderstand.org/

Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] Smalltalk string API

Stéphane Ducasse
In reply to this post by Nicolas Cellier
Hi nicolas

propose something and we can react :)
I'm busy with project proposal, teaching and 1.2 right now.

Stef


On Feb 16, 2011, at 10:24 AM, Nicolas Cellier wrote:

> I started referencing Smalltalk idioms at
> http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)
> I could have focused on ANSI but have chosen Squeak/Pharo. Feel free
> to correct me and to complete me.
>
> This is a very enlighting exercize, especially for pointing when API
> turns to be not that bright.
> During my perigrination, I notably noticed this:
>
> #compare: returns 1, 2, or 3 : this is both very object oriented, very
> intuitive and very standard and the rest of the world is stupid,
> unless...
>
> #findLastOccurrenceOfString:startingAt: in its current form is stupid
> to my taste, because
> 1) implementation is inefficient
> 2) the startingAt: only skip the beginning of the string which seems
> odd for a rfind operation
> I would rather expect this kind of usage:
> last := aString findLastOccurrenceOfString: 'to' startingAt: aString size.
> lastButOne := aString findLastOccurrenceOfString: 'to' startingAt: last - 1.
>
> The CamelCase is sometimes abusive like #includesSubString:
>
> There is no format. I know, purists will tell me that encoding a
> format in a cryptic string is not in the Smalltalk spirit, but please
> then tell me how to specify a formatting efficiently and also remove
> cryptic regex encoding (a pity, it's not in trunk).
>
> I let a few holes (split/join etc...)
>
> Cheers
>


Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] Smalltalk string API

Bert Freudenberg
In reply to this post by SergeStinckwich

On 16.02.2011, at 10:39, Serge Stinckwich wrote:

> On Wed, Feb 16, 2011 at 4:24 PM, Nicolas Cellier
> <[hidden email]> wrote:
>> I started referencing Smalltalk idioms at
>> http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)
>> I could have focused on ANSI but have chosen Squeak/Pharo. Feel free
>> to correct me and to complete me.
>>
>> This is a very enlighting exercize, especially for pointing when API
>> turns to be not that bright.
>> During my perigrination, I notably noticed this:
>>
>> #compare: returns 1, 2, or 3 : this is both very object oriented, very
>> intuitive and very standard and the rest of the world is stupid,
>> unless...
>
> Yes, really stupid, but maybe Squeak/Pharo should align here to the
> rest of the world or
> better, remove this method. We could use comparaison methods instead: <, >, ...

It is a low-level primitive, better indeed to use those operators instead, not call the compare* methods directly. For case-insensitive comparisons you should use e.g. caseInsensitiveLessOrEqual:.

If we want to provide a method that answers -1, 0, and 1 I'd leave the #compare: family alone, and instead add the operator <=> as in Ruby (which would be case-sensitive).

My 0.02€

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Tobias Pape
In reply to this post by Nicolas Cellier
Hi,

Am 2011-02-16 um 10:24 schrieb Nicolas Cellier:

> I started referencing Smalltalk idioms at
> http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)
> I could have focused on ANSI but have chosen Squeak/Pharo. Feel free
> to correct me and to complete me.
>
> This is a very enlighting exercize, especially for pointing when API
> turns to be not that bright.
> During my perigrination, I notably noticed this:
>
> #compare: returns 1, 2, or 3 : this is both very object oriented, very
> intuitive and very standard and the rest of the world is stupid,
> unless...
>
> #findLastOccurrenceOfString:startingAt: in its current form is stupid
> to my taste, because
> 1) implementation is inefficient
> 2) the startingAt: only skip the beginning of the string which seems
> odd for a rfind operation
> I would rather expect this kind of usage:
> last := aString findLastOccurrenceOfString: 'to' startingAt: aString size.
> lastButOne := aString findLastOccurrenceOfString: 'to' startingAt: last - 1.
>
> The CamelCase is sometimes abusive like #includesSubString:

While I’m with you in the preceding part,
the following is incorrect:
>
> There is no format. I know, purists will tell me that encoding a
> format in a cryptic string is not in the Smalltalk spirit, but please
> then tell me how to specify a formatting efficiently and also remove
> cryptic regex encoding (a pity, it's not in trunk).

see String>>format:
        "format the receiver with aCollection  
         
        simplest example:  
        'foo {1} bar' format: {Date today}.
         
        complete example:  
        '\{ \} \\ foo {1} bar {2}' format: {12. 'string'}.
        "

as well as the String>>expandMacros* methods. The latter
seem more elaborate but unused, however.


So Long,
        -Tobias




Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Nicolas Cellier
2011/2/16 Tobias Pape <[hidden email]>:

> Hi,
>
> Am 2011-02-16 um 10:24 schrieb Nicolas Cellier:
>> I started referencing Smalltalk idioms at
>> http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)
>> I could have focused on ANSI but have chosen Squeak/Pharo. Feel free
>> to correct me and to complete me.
>>
>> This is a very enlighting exercize, especially for pointing when API
>> turns to be not that bright.
>> During my perigrination, I notably noticed this:
>>
>> #compare: returns 1, 2, or 3 : this is both very object oriented, very
>> intuitive and very standard and the rest of the world is stupid,
>> unless...
>>
>> #findLastOccurrenceOfString:startingAt: in its current form is stupid
>> to my taste, because
>> 1) implementation is inefficient
>> 2) the startingAt: only skip the beginning of the string which seems
>> odd for a rfind operation
>> I would rather expect this kind of usage:
>> last := aString findLastOccurrenceOfString: 'to' startingAt: aString size.
>> lastButOne := aString findLastOccurrenceOfString: 'to' startingAt: last - 1.
>>
>> The CamelCase is sometimes abusive like #includesSubString:
>
> While I’m with you in the preceding part,
> the following is incorrect:
>>
>> There is no format. I know, purists will tell me that encoding a
>> format in a cryptic string is not in the Smalltalk spirit, but please
>> then tell me how to specify a formatting efficiently and also remove
>> cryptic regex encoding (a pity, it's not in trunk).
>
> see String>>format:
>        "format the receiver with aCollection
>
>        simplest example:
>        'foo {1} bar' format: {Date today}.
>
>        complete example:
>        '\{ \} \\ foo {1} bar {2}' format: {12. 'string'}.
>        "
>
> as well as the String>>expandMacros* methods. The latter
> seem more elaborate but unused, however.
>

Ah yes,  this is a start, I was focusing on number formatting like
most foreign format do
sprintf('%+.5f',pi)


>
> So Long,
>        -Tobias
>
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Levente Uzonyi-2
In reply to this post by Nicolas Cellier
On Wed, 16 Feb 2011, Nicolas Cellier wrote:

> I started referencing Smalltalk idioms at
> http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)
> I could have focused on ANSI but have chosen Squeak/Pharo. Feel free
> to correct me and to complete me.
>
> This is a very enlighting exercize, especially for pointing when API
> turns to be not that bright.
> During my perigrination, I notably noticed this:
>
> #compare: returns 1, 2, or 3 : this is both very object oriented, very
> intuitive and very standard and the rest of the world is stupid,
> unless...

1, 2 and 3 was a bad choice, -1, 0 and 1 would have been better, though I
don't like those either.

>
> #findLastOccurrenceOfString:startingAt: in its current form is stupid
> to my taste, because
> 1) implementation is inefficient
> 2) the startingAt: only skip the beginning of the string which seems
> odd for a rfind operation
> I would rather expect this kind of usage:
> last := aString findLastOccurrenceOfString: 'to' startingAt: aString size.
> lastButOne := aString findLastOccurrenceOfString: 'to' startingAt: last - 1.

Agreed.

>
> The CamelCase is sometimes abusive like #includesSubString:

This part of the system is really messy. There are also several methods
for doing the same (or very similary) things. For example:

includesSubString:
includesSubstring:caseSensitive:

indexOfSubCollection:*
findString:*

or my favorites

findTokens:
subStrings:
findBetweenSubStrs:
splitBy:

etc

>
> There is no format. I know, purists will tell me that encoding a
> format in a cryptic string is not in the Smalltalk spirit, but please
> then tell me how to specify a formatting efficiently and also remove
> cryptic regex encoding (a pity, it's not in trunk).

Should we create our own fork of VB-Regex or should we resurrect the PCRE
regex support (it's available on SqueakMap IIRC)?

>
> I let a few holes (split/join etc...)

I badly needed #join: yesterday. Writing the following multiple times is
not fun:
String streamContents: [ :stream | foo asStringOn: stream delimiter: bar ]

What Wikipedia contains* as the Squeak/Pharo implementation of join is
"interesting":

array_of_strings reduce: [:left :right | left , separator , right ])

- it's inefficent (O(n^2) worst case runtime, unnecessary allocations)
- it suggests that _ in a valid character in Smalltalk variable names


Levente

*http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)#join

>
> Cheers
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Nicolas Cellier
2011/2/19 Levente Uzonyi <[hidden email]>:

> On Wed, 16 Feb 2011, Nicolas Cellier wrote:
>
>> I started referencing Smalltalk idioms at
>>
>> http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)
>> I could have focused on ANSI but have chosen Squeak/Pharo. Feel free
>> to correct me and to complete me.
>>
>> This is a very enlighting exercize, especially for pointing when API
>> turns to be not that bright.
>> During my perigrination, I notably noticed this:
>>
>> #compare: returns 1, 2, or 3 : this is both very object oriented, very
>> intuitive and very standard and the rest of the world is stupid,
>> unless...
>
> 1, 2 and 3 was a bad choice, -1, 0 and 1 would have been better, though I
> don't like those either.
>
>>
>> #findLastOccurrenceOfString:startingAt: in its current form is stupid
>> to my taste, because
>> 1) implementation is inefficient
>> 2) the startingAt: only skip the beginning of the string which seems
>> odd for a rfind operation
>> I would rather expect this kind of usage:
>> last := aString findLastOccurrenceOfString: 'to' startingAt: aString size.
>> lastButOne := aString findLastOccurrenceOfString: 'to' startingAt: last -
>> 1.
>
> Agreed.
>
>>
>> The CamelCase is sometimes abusive like #includesSubString:
>
> This part of the system is really messy. There are also several methods for
> doing the same (or very similary) things. For example:
>
> includesSubString:
> includesSubstring:caseSensitive:
>
> indexOfSubCollection:*
> findString:*
>
> or my favorites
>
> findTokens:
> subStrings:
> findBetweenSubStrs:
> splitBy:
>
> etc
>
>>
>> There is no format. I know, purists will tell me that encoding a
>> format in a cryptic string is not in the Smalltalk spirit, but please
>> then tell me how to specify a formatting efficiently and also remove
>> cryptic regex encoding (a pity, it's not in trunk).
>
> Should we create our own fork of VB-Regex or should we resurrect the PCRE
> regex support (it's available on SqueakMap IIRC)?
>
>>
>> I let a few holes (split/join etc...)
>
> I badly needed #join: yesterday. Writing the following multiple times is not
> fun:
> String streamContents: [ :stream | foo asStringOn: stream delimiter: bar ]
>
> What Wikipedia contains* as the Squeak/Pharo implementation of join is
> "interesting":
>
> array_of_strings reduce: [:left :right | left , separator , right ])
>
> - it's inefficent (O(n^2) worst case runtime, unnecessary allocations)
> - it suggests that _ in a valid character in Smalltalk variable names
>
>
> Levente

Yes I know, I wrote this thing (before me Smalltalk was not mentionned).
Maybe it was a bit late at night ;) , anyway I had not so many choices:
- use join: (I think it is integrated in Pharo)
- use String streamContents: [:stream | arrayOfStrings do:
[:eachString | stream nextPutAll: eachString] separatedBy: [stream
nextPutAll: separator]]
  I would have written this form in Smalltalk, however I find the
periphrase a bit long versus other languages
- use reduce: to find a shorter form comprehensible by foreign
programming language users, though not optimal

Of course, it would also be nice to see a Xtreams solution.

Nicolas

>
> *http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)#join
>
>>
>> Cheers
>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Levente Uzonyi-2
On Sun, 20 Feb 2011, Nicolas Cellier wrote:

snip

>
> Yes I know, I wrote this thing (before me Smalltalk was not mentionned).

Thanks.

> Maybe it was a bit late at night ;) , anyway I had not so many choices:
> - use join: (I think it is integrated in Pharo)

I don't like that implementation. To me it's overengineered and
unintuitive. The following is enough for most of cases IMHO:

Collection >> join: delimiter

  ^String streamContents: [ :stream |
  self
  do: [ :each | each putOn: stream ]
  separatedBy: [ delimiter putOn: stream ] ]

This reflects my preference (receiver is the collection, argument is the
delimiter) and is not compatible with Pharo's implementation.

> - use String streamContents: [:stream | arrayOfStrings do:
> [:eachString | stream nextPutAll: eachString] separatedBy: [stream
> nextPutAll: separator]]
>  I would have written this form in Smalltalk, however I find the
> periphrase a bit long versus other languages

I see you updated the page, and yes, the phrase is pretty long compared to
other languages'.

> - use reduce: to find a shorter form comprehensible by foreign
> programming language users, though not optimal

#reduce: combined with #, may give the impression to outsiders that
strings have dynamic implementation (like in C++).


Levente

>
> Of course, it would also be nice to see a Xtreams solution.
>
> Nicolas
>
>>
>> *http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)#join
>>
>>>
>>> Cheers
>>>
>>>
>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Eliot Miranda-2


On Sun, Feb 20, 2011 at 4:46 PM, Levente Uzonyi <[hidden email]> wrote:
On Sun, 20 Feb 2011, Nicolas Cellier wrote:

snip



Yes I know, I wrote this thing (before me Smalltalk was not mentionned).

Thanks.


Maybe it was a bit late at night ;) , anyway I had not so many choices:
- use join: (I think it is integrated in Pharo)

I don't like that implementation. To me it's overengineered and unintuitive. The following is enough for most of cases IMHO:

Collection >> join: delimiter

       ^String streamContents: [ :stream |
               self
                       do: [ :each | each putOn: stream ]
                       separatedBy: [ delimiter putOn: stream ] ]

+1.  This is pellucidly clear and elegant.  It might not be super fast but Marcus and I are working on adaptive optimization/speculative inlining precisely to optimize cases like this into fast executable code.  Hopefully we'll be able to demonstrate automatic optimization of code like this into flatter faster code this year.  Keep writing beautiful code and somehow we'll figure out how to make it go fast.
 

This reflects my preference (receiver is the collection, argument is the delimiter) and is not compatible with Pharo's implementation.


- use String streamContents: [:stream | arrayOfStrings do:
[:eachString | stream nextPutAll: eachString] separatedBy: [stream
nextPutAll: separator]]
 I would have written this form in Smalltalk, however I find the
periphrase a bit long versus other languages

I see you updated the page, and yes, the phrase is pretty long compared to other languages'.


- use reduce: to find a shorter form comprehensible by foreign
programming language users, though not optimal

#reduce: combined with #, may give the impression to outsiders that strings have dynamic implementation (like in C++).


Levente



Of course, it would also be nice to see a Xtreams solution.

Nicolas


*http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)#join


Cheers










Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Eliot Miranda-2
In reply to this post by Levente Uzonyi-2


On Sun, Feb 20, 2011 at 4:46 PM, Levente Uzonyi <[hidden email]> wrote:
On Sun, 20 Feb 2011, Nicolas Cellier wrote:

snip



Yes I know, I wrote this thing (before me Smalltalk was not mentionned).

Thanks.


Maybe it was a bit late at night ;) , anyway I had not so many choices:
- use join: (I think it is integrated in Pharo)

I don't like that implementation. To me it's overengineered and unintuitive. The following is enough for most of cases IMHO:

Collection >> join: delimiter

       ^String streamContents: [ :stream |
               self
                       do: [ :each | each putOn: stream ]
                       separatedBy: [ delimiter putOn: stream ] ]

Actually, thinking a little, why not


Collection >> join: delimiter

       ^self species streamContents: [ :stream |
               self
                       do: [ :each | each putOn: stream ]
                       separatedBy: [ delimiter putOn: stream ] ]

?
 

This reflects my preference (receiver is the collection, argument is the delimiter) and is not compatible with Pharo's implementation.


- use String streamContents: [:stream | arrayOfStrings do:
[:eachString | stream nextPutAll: eachString] separatedBy: [stream
nextPutAll: separator]]
 I would have written this form in Smalltalk, however I find the
periphrase a bit long versus other languages

I see you updated the page, and yes, the phrase is pretty long compared to other languages'.


- use reduce: to find a shorter form comprehensible by foreign
programming language users, though not optimal

#reduce: combined with #, may give the impression to outsiders that strings have dynamic implementation (like in C++).


Levente



Of course, it would also be nice to see a Xtreams solution.

Nicolas


*http://en.wikipedia.org/wiki/Comparison_of_programming_languages_(string_functions)#join


Cheers










Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Levente Uzonyi-2
In reply to this post by Eliot Miranda-2
On Mon, 21 Feb 2011, Eliot Miranda wrote:

> On Sun, Feb 20, 2011 at 4:46 PM, Levente Uzonyi <[hidden email]> wrote:

snip

>> Collection >> join: delimiter
>>
>>        ^String streamContents: [ :stream |
>>                self
>>                        do: [ :each | each putOn: stream ]
>>                        separatedBy: [ delimiter putOn: stream ] ]
>>
>
> +1.  This is pellucidly clear and elegant.  It might not be super fast but
> Marcus and I are working on adaptive optimization/speculative inlining
> precisely to optimize cases like this into fast executable code.  Hopefully
> we'll be able to demonstrate automatic optimization of code like this into
> flatter faster code this year.  Keep writing beautiful code and somehow
> we'll figure out how to make it go fast.

Great. Is the developement open?


Levente

snip

Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Levente Uzonyi-2
In reply to this post by Eliot Miranda-2
On Mon, 21 Feb 2011, Eliot Miranda wrote:

snip

> Actually, thinking a little, why not
>
>
> Collection >> join: delimiter
>
>       ^self species streamContents: [ :stream |
>               self
>                       do: [ :each | each putOn: stream ]
>                       separatedBy: [ delimiter putOn: stream ] ]
>
> ?

Because I'd like this:
#('foo' 'bar' 'baz') join: $-
to return this:
'foo-bar-baz'
rather than this:
#($f $o $o $- $b $a $r $- $b $a $z).

Pharo's implementation dispatches on the class of the delimiter. That's
fine, but requires multiple methods. Also I've never used #join: to create
anything else but Strings.


Levente

snip

Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Eliot Miranda-2
In reply to this post by Levente Uzonyi-2


On Mon, Feb 21, 2011 at 9:28 PM, Levente Uzonyi <[hidden email]> wrote:
On Mon, 21 Feb 2011, Eliot Miranda wrote:

On Sun, Feb 20, 2011 at 4:46 PM, Levente Uzonyi <[hidden email]> wrote:

snip


Collection >> join: delimiter

      ^String streamContents: [ :stream |
              self
                      do: [ :each | each putOn: stream ]
                      separatedBy: [ delimiter putOn: stream ] ]


+1.  This is pellucidly clear and elegant.  It might not be super fast but
Marcus and I are working on adaptive optimization/speculative inlining
precisely to optimize cases like this into fast executable code.  Hopefully
we'll be able to demonstrate automatic optimization of code like this into
flatter faster code this year.  Keep writing beautiful code and somehow
we'll figure out how to make it go fast.

Great. Is the developement open?

It will be soon.  Marcus wants to get his SSA compiler to a state where he can do a round-trip, converting bytecoded methods into SSA and back into bytecode.  His code worked pre-closures and is now being upgraded.   I'll be committing a VM with the low-level support for performance counters on conditional branches and a primitive to answer the state of PICs and counters soon.  We are no more than a few weeks away.

cheers
Eliot



Levente

snip




Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Eliot Miranda-2
In reply to this post by Levente Uzonyi-2


On Mon, Feb 21, 2011 at 9:37 PM, Levente Uzonyi <[hidden email]> wrote:
On Mon, 21 Feb 2011, Eliot Miranda wrote:

snip


Actually, thinking a little, why not


Collection >> join: delimiter

     ^self species streamContents: [ :stream |
             self
                     do: [ :each | each putOn: stream ]
                     separatedBy: [ delimiter putOn: stream ] ]

?

Because I'd like this:
#('foo' 'bar' 'baz') join: $-
to return this:
'foo-bar-baz'
rather than this:
#($f $o $o $- $b $a $r $- $b $a $z).

So then why not

SequenceableCollection >> join: delimiter

       ^self isEmpty
           ifTrue: [ self ]
           ifFalse:
                [ self first species streamContents:
                     [ :stream |
                     self
                         do: [ :each | each putOn: stream ]
                         separatedBy: [ delimiter putOn: stream ] ] ]

with first replaced by anyOne in Collection?
 

Pharo's implementation dispatches on the class of the delimiter. That's fine, but requires multiple methods. Also I've never used #join: to create anything else but Strings.


Levente

snip




Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Levente Uzonyi-2
On Tue, 22 Feb 2011, Eliot Miranda wrote:

> On Mon, Feb 21, 2011 at 9:37 PM, Levente Uzonyi <[hidden email]> wrote:
>
>> On Mon, 21 Feb 2011, Eliot Miranda wrote:
>>
>> snip
>>
>>
>>  Actually, thinking a little, why not
>>>
>>>
>>> Collection >> join: delimiter
>>>
>>>      ^self species streamContents: [ :stream |
>>>              self
>>>                      do: [ :each | each putOn: stream ]
>>>                      separatedBy: [ delimiter putOn: stream ] ]
>>>
>>> ?
>>>
>>
>> Because I'd like this:
>> #('foo' 'bar' 'baz') join: $-
>> to return this:
>> 'foo-bar-baz'
>> rather than this:
>> #($f $o $o $- $b $a $r $- $b $a $z).
>>
>
> So then why not
>
> SequenceableCollection >> join: delimiter
>
>       ^self isEmpty
>           ifTrue: [ self ]
>           ifFalse:
>                [ self first species streamContents:
>                     [ :stream |
>                     self
>                         do: [ :each | each putOn: stream ]
>                         separatedBy: [ delimiter putOn: stream ] ] ]
>
> with first replaced by anyOne in Collection?

This assumes that the receiver is a collection of objects whose species is
Array or a subclass of String (#streamContents: doesn't work with other
collections IIRC). If that's the case, then there's no need to use
#putOn:, because #nextPutAll: does the same and it's faster too.

With my version, this:
#(1 2 3) join: $-
returns this:
'1-2-3'.


Levente

>
>
>>
>> Pharo's implementation dispatches on the class of the delimiter. That's
>> fine, but requires multiple methods. Also I've never used #join: to create
>> anything else but Strings.
>>
>>
>> Levente
>>
>> snip
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk string API

Eliot Miranda-2


On Tue, Feb 22, 2011 at 9:59 AM, Levente Uzonyi <[hidden email]> wrote:
On Tue, 22 Feb 2011, Eliot Miranda wrote:

On Mon, Feb 21, 2011 at 9:37 PM, Levente Uzonyi <[hidden email]> wrote:

On Mon, 21 Feb 2011, Eliot Miranda wrote:

snip


 Actually, thinking a little, why not


Collection >> join: delimiter

    ^self species streamContents: [ :stream |
            self
                    do: [ :each | each putOn: stream ]
                    separatedBy: [ delimiter putOn: stream ] ]

?


Because I'd like this:
#('foo' 'bar' 'baz') join: $-
to return this:
'foo-bar-baz'
rather than this:
#($f $o $o $- $b $a $r $- $b $a $z).


So then why not

SequenceableCollection >> join: delimiter

     ^self isEmpty
         ifTrue: [ self ]
         ifFalse:
              [ self first species streamContents:
                   [ :stream |
                   self
                       do: [ :each | each putOn: stream ]
                       separatedBy: [ delimiter putOn: stream ] ] ]

with first replaced by anyOne in Collection?

This assumes that the receiver is a collection of objects whose species is Array or a subclass of String (#streamContents: doesn't work with other collections IIRC). If that's the case, then there's no need to use #putOn:, because #nextPutAll: does the same and it's faster too.

With my version, this:
#(1 2 3) join: $- returns this:
'1-2-3'.

got it. finally.  sorry :)
 


Levente





Pharo's implementation dispatches on the class of the delimiter. That's
fine, but requires multiple methods. Also I've never used #join: to create
anything else but Strings.


Levente

snip