join

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

RE: join

Ramon Leon-5
> that seems obvious to me:
>
> it's ' ,' that joins the items in #('a' 'b' 'c'), acting as a
> glue, while the expression
>
> #('a' 'b' 'c') join: ' ,'
>
> does not make any sense when you read it.
> we do "small talk" after all... not "reverse talk"
>
>
> just my 2 cents
>
> Stef

I see it the other way, I have an array, I want a string, I ask the array to
join: itself on some delimiter, it's the array's data, therefore the array
needs to do the work.


Reply | Threaded
Open this post in threaded view
|

Re: join

keith1y

> I see it the other way, I have an array, I want a string, I ask the array to
> join: itself on some delimiter, it's the array's data, therefore the array
> needs to do the work.
>  
Ramon,

indeed I can see your point but have a look at the rest of the smalltalk
system and look at how many things are implemented backwards to your way
of thinking and how much more power and flexibility is available by
doing things this way.

For example, using your logic, you would never come up with this idea.

1 to: 10 do: [:b ].

I think your version might look like something from another thread on
squeak-dev at the moment. ACollection>>from:to:apply:

In this case Number>>to:do: is implemented on Number as syntactic sugar
onto Interval>>do: which actually does the work.

I think that it is relatively common to have classes that are not the
actual data holder doing the work. This is primarily because of the
power of the Smalltalk collections and their iterators.

best regards

Keith


       
       
               
___________________________________________________________
All new Yahoo! Mail "The new Interface is stunning in its simplicity and ease of use." - PC Magazine
http://uk.docs.yahoo.com/nowyoucan.html

Reply | Threaded
Open this post in threaded view
|

RE: join

Ramon Leon-5
> 1 to: 10 do: [:b ].
> I think your version might look like something from another
> thread on squeak-dev at the moment. ACollection>>from:to:apply:

Nope, my version would be implemented just like it already is, to: on number
and do: on interval.

>
> In this case Number>>to:do: is implemented on Number as
> syntactic sugar onto Interval>>do: which actually does the work.

Which is how I'd think of it, to: belongs on number, do: belongs on
interval, to:do: is just a shortcut to the common case so you don't have to
put parens to disambiguate the statement.

> I think that it is relatively common to have classes that are
> not the actual data holder doing the work. This is primarily
> because of the power of the Smalltalk collections and their iterators.
>
> best regards
>
> Keith

I think it's common to have shortcuts that make it appear so, but having
classes that hold the data do the work, is a fundamental concept of object
orientation, this case is no different.


Reply | Threaded
Open this post in threaded view
|

Re: join

Klaus D. Witzel
In reply to this post by keith1y
On Wed, 20 Sep 2006 01:21:57 +0200, Keith Hodges wrote:
...
> For example, using your logic, you would never come up with this idea.
>
> 1 to: 10 do: [:b ].
>
> I think your version might look like something from another thread on  
> squeak-dev at the moment. ACollection>>from:to:apply:

And I thought that would slip through unnoticed ;-)

The original suggestion was, aBlock>>apply: aCollection from: start to:  
stop.

Since only collections can know how to do that, aBlock and aCollection had  
to be swapped. Of course your suggestion #from:to:apply: is also a good  
one.

-----------

Wrt #join, my favorites are your joinUsing: and useToJoin: this is  
Smalltalk land and people (incl. newbies) use method finder, if not for  
finding #substring.

I use #substring as an exmple for the utility of method finder because in  
other languages is takes one or two arguments and so in Smalltalk *must*  
have another name.

/Klaus


Reply | Threaded
Open this post in threaded view
|

Apply vs. do (was: Re: join)

Bert Freudenberg
Klaus D. Witzel wrote:

> On Wed, 20 Sep 2006 01:21:57 +0200, Keith Hodges wrote:
> ...
>> For example, using your logic, you would never come up with this idea.
>>
>> 1 to: 10 do: [:b ].
>>
>> I think your version might look like something from another thread on
>> squeak-dev at the moment. ACollection>>from:to:apply:
>
> And I thought that would slip through unnoticed ;-)
>
> The original suggestion was, aBlock>>apply: aCollection from: start to:
> stop.
>
> Since only collections can know how to do that, aBlock and aCollection
> had to be swapped. Of course your suggestion #from:to:apply: is also a
> good one.


I was wondering why it is called "apply" anyway - the traditional term
would be "do". The only reason to call it "apply" is if it's a Block method.

I'd suggest that the proper selector for that method would be

        from:to:do:

which indeed exists already, and which would just get a speed
enhancement by the new primitive.

- Bert -

Reply | Threaded
Open this post in threaded view
|

Re: Apply vs. do (was: Re: join)

Klaus D. Witzel
On Wed, 20 Sep 2006 15:40:29 +0200, Bert Freudenberg wrote:

> Klaus D. Witzel wrote:
>> On Wed, 20 Sep 2006 01:21:57 +0200, Keith Hodges wrote:
>> ...
>>> For example, using your logic, you would never come up with this idea.
>>>
>>> 1 to: 10 do: [:b ].
>>>
>>> I think your version might look like something from another thread on  
>>> squeak-dev at the moment. ACollection>>from:to:apply:
>>  And I thought that would slip through unnoticed ;-)
>>  The original suggestion was, aBlock>>apply: aCollection from: start  
>> to: stop.
>>  Since only collections can know how to do that, aBlock and aCollection  
>> had to be swapped. Of course your suggestion #from:to:apply: is also a  
>> good one.
>
>
> I was wondering why it is called "apply" anyway - the traditional term  
> would be "do". The only reason to call it "apply" is if it's a Block  
> method.

:)

> I'd suggest that the proper selector for that method would be
>
> from:to:do:

Done.

> which indeed exists already, and which would just get a speed  
> enhancement by the new primitive.

Oh no! that's too easy! Only the one-liner <primitive: ...> has to be  
added to an existing method. Will this count as an enhancement, a change,  
a VM extension, or what ;-)

Thank you Bert.

/Klaus

> - Bert -


Reply | Threaded
Open this post in threaded view
|

Re: join

J J-6
In reply to this post by Lex Spoon
I think the best version of all these things was recomended by Kieth, and
his version just joined collections.  If they happen to be string then it
makes a string.

My vote is for his submission and I will go back through my mail and find it
again if you don't know the one I'm talking about.


>From: Lex Spoon <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: [hidden email]
>Subject: Re: join
>Date: 19 Sep 2006 13:49:50 +0200
>
>"Ramon Leon" <[hidden email]> writes:
> > > Join is popular for people who use Perl, but it seems weird
> >
> > And Python, Ruby, JavaScript, CSharp, and Visual Basic.Net.  Split and
>join
> > are the common names in most languages that use them.
>
>OK, that's a good reason to call it "join".
>
>Just to be sure, though, which "join" do these languages have?  "join"
>sounds right for the method posted initially in this thread, but
>sounds wrong for the method that creates a string regardless of the
>initial collection types.
>
>
>-Lex
>
>



Reply | Threaded
Open this post in threaded view
|

Re: join

J J-6
In reply to this post by keith1y
I like your previous example the best.  I think smalltalk is different
enough from the other languages that it needs a "Smalltalk for <language>
programmers" for the different languages (which it has for some).  Then you
can just put their join and smalltalks.


>From: Keith Hodges <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: The general-purpose Squeak developers
>list<[hidden email]>
>Subject: Re: join
>Date: Tue, 19 Sep 2006 15:40:11 +0100
>
>It appears to be to be a discrepancy between the smalltalk way and these
>'other' languages.
>
>in ruby
>
>[ 'a', 'b', 'c' ].join(', ')
>
>in smalltalk to achieve the same thing, including the specification that
>the result should be a String, arguably could be
>
>' ,' join: #('a' 'b' 'c')
>
>but I can bet that if you are trying to satisfy the aesthetic requirements
>of users of 'other' languages (those languages with supposedly less
>brackets), they will take one look at this smalltalk version and say that
>it is the wrong way around.
>
>so... if you do want the wrong way around for them, we need a right way
>around for us.
>how about #joining:
>
>aCollection>>join:bCollection
>^bCollection joining: aCollection
>
>#('a' 'b' 'c') join: ', '.
>
>', ' joining: #('a' 'b' 'c')
>
>
>Keith
>
>
>
>
>___________________________________________________________ Copy addresses
>and emails from any email account to Yahoo! Mail - quick, easy and free.
>http://uk.docs.yahoo.com/trueswitch2.html
>



Reply | Threaded
Open this post in threaded view
|

Re: join

Lex Spoon
In reply to this post by J J-6
"J J" <[hidden email]> writes:
> I think the best version of all these things was recomended by Kieth,
> and his version just joined collections.  If they happen to be string
> then it makes a string.


Isn't returning a string practically the only use case?


  $('red' 'green' 'blue') join: ', '    "gives: red, green, blue"

  $(1 2 3) join: ', '    "gives: 1, 2, 3"


If "join" is not to be the above method, the above method would still
be nice to have.


-Lex


Reply | Threaded
Open this post in threaded view
|

Re: join

J J-6
What about:

#( 241 243 248 ) joinWith: #(255 253).

Now you could make the argument that what I'm going for is a string (the
numbers are almost certainly wrong, but I was trying to encode some telnet
options), but I'm sure with some sleep I can come up with some examples
where you would want to join a collection with collections or anything else.

Duplicating what others have when you don't have it is important.  But if
you can improve on it at no extra cost then why not?


>From: Lex Spoon <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: [hidden email]
>Subject: Re: join
>Date: 25 Sep 2006 14:25:58 +0200
>
>"J J" <[hidden email]> writes:
> > I think the best version of all these things was recomended by Kieth,
> > and his version just joined collections.  If they happen to be string
> > then it makes a string.
>
>
>Isn't returning a string practically the only use case?
>
>
>   $('red' 'green' 'blue') join: ', '    "gives: red, green, blue"
>
>   $(1 2 3) join: ', '    "gives: 1, 2, 3"
>
>
>If "join" is not to be the above method, the above method would still
>be nice to have.
>
>
>-Lex
>
>



Reply | Threaded
Open this post in threaded view
|

Re: join

Lex Spoon
"J J" <[hidden email]> writes:
> Duplicating what others have when you don't have it is important.  But
> if you can improve on it at no extra cost then why not?

You did not address the example I gave:

> >   $(1 2 3) join: ', '    "gives: 1, 2, 3"

For this kind of use case, it would be nice if the join called
asString on the elements of the receiver.

I expect that this kind of use case, where you are turning a
collection into a space- or comma-delimited string for output, is the
most common use case.


-Lex


Reply | Threaded
Open this post in threaded view
|

Re: join

J J-6
Actually, the implimentation that Keith had did a double dispatch as I
recall (I guess I will dig that up and resend it if I ever get more then 5
minutes online at a time) and in this case, i.e. the argument to join: is a
string, would result in a string.


>From: Lex Spoon <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: [hidden email]
>Subject: Re: join
>Date: 26 Sep 2006 23:02:09 +0200
>
>"J J" <[hidden email]> writes:
> > Duplicating what others have when you don't have it is important.  But
> > if you can improve on it at no extra cost then why not?
>
>You did not address the example I gave:
>
> > >   $(1 2 3) join: ', '    "gives: 1, 2, 3"
>
>For this kind of use case, it would be nice if the join called
>asString on the elements of the receiver.
>
>I expect that this kind of use case, where you are turning a
>collection into a space- or comma-delimited string for output, is the
>most common use case.
>
>
>-Lex
>
>



Reply | Threaded
Open this post in threaded view
|

Re: join

Göran Krampe
In reply to this post by Lex Spoon
Hi fellas!

Lex Spoon <[hidden email]> wrote:

> "J J" <[hidden email]> writes:
> > Duplicating what others have when you don't have it is important.  But
> > if you can improve on it at no extra cost then why not?
>
> You did not address the example I gave:
>
> > >   $(1 2 3) join: ', '    "gives: 1, 2, 3"
>
> For this kind of use case, it would be nice if the join called
> asString on the elements of the receiver.

I fainlty remember implementing a method that does the above, but with
this added twist:

#('1' '2' '3') join: ', ' last: ' and '  ==> '1, 2 and 3'

So if anyone is hoing to add something like this, then include this
extra feature too somehow. :)

And since you are then rumming about in Collection and friends - add
#removeAll while you are at it with efficient implementations in
suitable subclasses. I tried a few years back but got my head bitten off
and retreated. ;)

Soo... who is the steward for Collections? :)

regards, Göran

Reply | Threaded
Open this post in threaded view
|

Re: join

Lex Spoon
In reply to this post by J J-6
"J J" <[hidden email]> writes:
> Actually, the implimentation that Keith had did a double dispatch as I
> recall (I guess I will dig that up and resend it if I ever get more
> then 5 minutes online at a time) and in this case, i.e. the argument
> to join: is a string, would result in a string.

That would sound fine to me, and it sounds so fine to you that
apparently you assumed this is what the original code did!  However, I
just looked it up and it is not the case.  Here's is the top of
Keith's message again:


> Whenever I find myself wanting to join a bunch of items together
> (e.g. to make a path) I am never satisfied with the result and so I
> took a look at the Collections/String classes to see whether anything
> fitted nicely.
>
> I came up with
>
> SequencableCollection>>join: aCollection
>
>     ^ self class streamContents: [ :stream |
>         aCollection
>             do: [ :each | stream nextPut: each ]
>             separatedBy: [ stream nextPutAll: self ] ]


It is great but for two things: it creates an instance of the
*receiver's* class, and it never calls asString.


When I read the idea, I thought of the following method:


join: separatorString
        "Create a string composed of the elements of the receiver separated by the specified separator.  For example: ['/', (#('usr' 'bin' 'squeak') join: '/')] or [#(1 2 3) join: ', ']"
       
        ^String streamContents: [ :result |
                self
                        do: [ :each | result nextPutAll: each asString ]
                        separatedBy: [ result nextPutAll: separatorString ] ]
               
               


By the way, I still find "join" to be a funny name here, but everyone
in the thread insists it is common....

-Lex


Reply | Threaded
Open this post in threaded view
|

Re: join

Ramon Leon-4

> By the way, I still find "join" to be a funny name here, but everyone
> in the thread insists it is common....
>
> -Lex

Really?  Seems to make sense to me, telling a collection to join all of
it's elements together with a string.  Here's a list of words, join them
all with ', '.  Here's a list of conditions, join them all with ' and ',
or ' or '.  It's used so much, I can't think of a shorter more precise
name.  It's certainly a common name in many other languages, maybe we're
all just acclimated to that name.

Of course, I thought #ifTrue:ifFalse: looked pretty funny at first as
well, even stubbed out #if:else: just to see if I could make it look
more normal, but only at first. ;)

Ramon Leon
http://onsmalltalk.com



Reply | Threaded
Open this post in threaded view
|

removeAll (Re: join)

Lex Spoon
In reply to this post by Göran Krampe
[hidden email] writes:
> And since you are then rumming about in Collection and friends - add
> #removeAll while you are at it with efficient implementations in
> suitable subclasses. I tried a few years back but got my head bitten off
> and retreated. ;)

Curiously, there is no removeAll method in Collection, in 3.7, 3.8, or
3.9.  There are very few removeAll methods at all, most are not in the
Collection hierarchy, and one of them is deprecated.  Maybe you are
thinking of a *proposed* removeAll method or methods?

Speaking of which, why is SharedQueue2>>removeAll marked
"Deprecated3.9".  It seems like a useful method, and there is no
replacement.  Especially odd is that SharedQueue2>>flush is marked as
"deprecated: 'use removeAll'".

-Lex


Reply | Threaded
Open this post in threaded view
|

removeAll (Re: join)

Göran Krampe
Hi!

Lex Spoon <[hidden email]> wrote:

> [hidden email] writes:
> > And since you are then rumming about in Collection and friends - add
> > #removeAll while you are at it with efficient implementations in
> > suitable subclasses. I tried a few years back but got my head bitten off
> > and retreated. ;)
>
> Curiously, there is no removeAll method in Collection, in 3.7, 3.8, or
> 3.9.  There are very few removeAll methods at all, most are not in the
> Collection hierarchy, and one of them is deprecated.  Maybe you are
> thinking of a *proposed* removeAll method or methods?

Yes, I am proposing to add it. I wrote *add* :). I argumented for such a
method a few years back but as I said - I did not have the energy to
argue with other prominent Smalltalkers saying that it was a bad idea. I
still think it is an obviously good idea - especially since it can be
concretely efficiently implemented in selected subclasses.

> Speaking of which, why is SharedQueue2>>removeAll marked
> "Deprecated3.9".  It seems like a useful method, and there is no
> replacement.  Especially odd is that SharedQueue2>>flush is marked as
> "deprecated: 'use removeAll'".
>
> -Lex

No idea. I also think SharedBufferStreams on SM is better than
SharedQueue. ;)

regards, Göran

Reply | Threaded
Open this post in threaded view
|

Re: join

J J-6
In reply to this post by keith1y
Ok, I went and dug it up.  I think this was the best proposal for adding
"join" to Squeak 3.10.


>From: Keith Hodges <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: The general-purpose Squeak developers
>list<[hidden email]>
>Subject: Re: join
>Date: Sat, 16 Sep 2006 01:54:50 +0100
>
>I think that join: should be more than a simple string generator. Using the
>power of Smalltalk collections you will find all sorts of wierd and
>wonderful operators that work on all manner of collections, and I think
>that join: should demonstrate some of this power.
>
>avi's joinTokens: aStringToken does just what it say it does, it just
>creates a string. Simple and unambiguous.
>
>My proposed join: implementation is able to do much more, but there are
>some ambiguities as to what behaviour is desired/obtained. I have no idea
>what other Smalltalks do but here are my ideas so far:
>
>Character-useTojoin: result will be a string.
>String-useToJoin: result will be a string.
>$/ useToJoin: #('hello' 'my' 'world')   -> 'hello/my/world'
>', ' useToJoin: #('hello' my' 'world') -> 'hello, my, world'
>
>SequencableCollection-useToJoin result will be a SequencableCollection.
>#(1 2) useToJoin: #(3 4 5) ->  #(3 1 2 4 1 2 5)
>
>The double dispatch approach can be used.
>
>#('hello' 'my' world') joinUsing: $/
>
>SequenceableCollestion>>joinUsing: joiner
>^ joiner useToJoin: self
>
>----
>ideas:
>
>useToJoin:  <-> joinUsing:
>join: <-> joinWith:
>
>Keith
>
>
>
>
>
>
>
>
>
>
>
>___________________________________________________________ NEW Yahoo! Cars
>- sell your car and browse thousands of new and used cars online!
>http://uk.cars.yahoo.com/
>



Reply | Threaded
Open this post in threaded view
|

Re: split:

J J-6
In reply to this post by keith1y
And here is my vote for split.


>From: Keith Hodges <[hidden email]>
>Reply-To: The general-purpose Squeak developers
>list<[hidden email]>
>To: The general-purpose Squeak developers
>list<[hidden email]>
>Subject: Re: split:
>Date: Sat, 16 Sep 2006 02:20:17 +0100
>
>The question as to whether split: should work with Strings or Regex's is
>something that should be handled with a double dispatch. If you feed it a
>String it should use a string if you feed it a Regex then it will use a
>Regex.
>
>eg := 'Now is the time for all good men to come to the aid of the  party'.
>
>eg splitOnEvery: 'the'
>eg splitOnEvery: ( '+[\s]' asRegex ).
>eg splitOnEvery: $e.
>#(1 2 3 4 5 6 7 8 9) splitOnEvery: #(4).
>#(1 2 3 4 5 6 7 8 9) splitOnEvery: #(4 5 6).
>#(1 2 3 4 5 6 7 8 9) splitOnEvery: [ :n | n isPrimeNumber ]
>
>SequencableCollection>>splitOnEvery: aSpliter
>^aSpliter  splitUp:  self
>
>aRegex>>splitUp: aString.
>...regex implementation
>aString>>splitUp: aString.
>...string implementation
>aCharacter>>splitUp: aString.
>...character implementation
>aSequencableCollection>>splitUp: aSequencableCollection
>... generic collection implementation.
>aMonadicBlock>>splitOnEvery: thing
>^ thing splitUsing: aBlock.
>
>more ideas
>
>Keith
>
>
>
>
> >In my viewer I saw two spaces at "the  party".
> >So what should happen for #split: on a single space.
> >Should there be an extra item with value nil or an
> >empty string? Or should there be no extra item?
>
>I think that the convention is to return an empty string. -> #('the' ''
>'party')
>
>
>
>
>
>___________________________________________________________ Yahoo!
>Messenger - NEW crystal clear PC to PC calling worldwide with voicemail
>http://uk.messenger.yahoo.com
>



Reply | Threaded
Open this post in threaded view
|

Re: join

keith1y
In reply to this post by J J-6
Thanks JJ, I think I prefer this option overall. Sorry I just havent had
any time to do anything about writing tests etc as requested.

Keith

J J wrote:

> Ok, I went and dug it up.  I think this was the best proposal for
> adding "join" to Squeak 3.10.
>
>
>> From: Keith Hodges <[hidden email]>
>> Reply-To: The general-purpose Squeak developers
>> list<[hidden email]>
>> To: The general-purpose Squeak developers
>> list<[hidden email]>
>> Subject: Re: join
>> Date: Sat, 16 Sep 2006 01:54:50 +0100
>>
>> I think that join: should be more than a simple string generator.
>> Using the power of Smalltalk collections you will find all sorts of
>> wierd and wonderful operators that work on all manner of collections,
>> and I think that join: should demonstrate some of this power.
>>
>> avi's joinTokens: aStringToken does just what it say it does, it just
>> creates a string. Simple and unambiguous.
>>
>> My proposed join: implementation is able to do much more, but there
>> are some ambiguities as to what behaviour is desired/obtained. I have
>> no idea what other Smalltalks do but here are my ideas so far:
>>
>> Character-useTojoin: result will be a string.
>> String-useToJoin: result will be a string.
>> $/ useToJoin: #('hello' 'my' 'world')   -> 'hello/my/world'
>> ', ' useToJoin: #('hello' my' 'world') -> 'hello, my, world'
>>
>> SequencableCollection-useToJoin result will be a SequencableCollection.
>> #(1 2) useToJoin: #(3 4 5) ->  #(3 1 2 4 1 2 5)
>>
>> The double dispatch approach can be used.
>>
>> #('hello' 'my' world') joinUsing: $/
>>
>> SequenceableCollestion>>joinUsing: joiner
>> ^ joiner useToJoin: self
>>
>> ----
>> ideas:
>>
>> useToJoin:  <-> joinUsing:
>> join: <-> joinWith:
>>
>> Keith
>>

               
___________________________________________________________
Try the all-new Yahoo! Mail. "The New Version is radically easier to use" – The Wall Street Journal
http://uk.docs.yahoo.com/nowyoucan.html

123