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 |
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/ |
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 > |
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 - |
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 |
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 > > > > > |
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 > > |
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 >> >> > > |
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 >>> >>> >> >> > > |
On Sun, Feb 20, 2011 at 4:46 PM, Levente Uzonyi <[hidden email]> wrote: On Sun, 20 Feb 2011, Nicolas Cellier wrote: +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.
|
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: Actually, thinking a little, why not Collection >> join: delimiter ^self species streamContents: [ :stream | self do: [ :each | each putOn: stream ] separatedBy: [ delimiter putOn: stream ] ] ?
|
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 |
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 |
In reply to this post by Levente Uzonyi-2
On Mon, Feb 21, 2011 at 9:28 PM, Levente Uzonyi <[hidden email]> wrote:
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
|
In reply to this post by Levente Uzonyi-2
On Mon, Feb 21, 2011 at 9:37 PM, Levente Uzonyi <[hidden email]> wrote:
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?
|
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 >> >> > |
On Tue, Feb 22, 2011 at 9:59 AM, Levente Uzonyi <[hidden email]> wrote:
got it. finally. sorry :)
|
Free forum by Nabble | Edit this page |