Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
December 2008
- 55 participants
- 655 messages
Re: [Pharo-project] Dictionary as a Set
by Stéphane Ducasse
>
> For me the sole specification is that a Bag unlike a Set can hold
> several equal elements.
> The fact that it can count them fast rather than enumerating the whole
> collection is an implementation detail (an important detail of
> course).
exact this is why for me a dictionary is more like a set than a bag
because
I can only have one key for #a for example.
This is why I did not totally understand your bag relationships.
>>> a) multiple values can be in the dictionary:
>>> (Dictionary new) at: 'one' put: 1; at: 'first' put: 1; yourself.
>>
>> For me to be bag would mean more
>>
>>> dc := (DictionaryBag new) at: 'one' put: 1; at: 'one' put: 2;
>>> yourself.
>> dc at: one
>> -> #(1 2)
>>
>> Stef
>>
>
> a DictionaryOfBags ?
No I mean if you want to see Dictionary as a bag then
it means that you could have multiple similar keys 'one' in the above
example.
For a Dictionary (as for now and which I see as a set)
you get only one value for the key 'one'
>
>
> One thing Dictionary is not : a Bag of associations.
> Think of it as a Bag of values.
> As long as you don't override a key, a Dictionary behaves like a Bag:
>
> digits := 0 to: 9.
> b := Bag new.
> d := Dictionary new.
> digits do: [:i | b add: i//2].
> digits do: [:i | d at: i printString put: i//2].
> digits do: [:i |
> self assert: (b occurrencesOf: i) = (d occurrencesOf: i)].
>
> Personnally, I would expect
> d values.
> to answer a Bag (unordered) rather than an Array (arbitrary order)...
> The only advantage of an Array is that it is faster than a Bag...
>
>
> _______________________________________________
> Pharo-project mailing list
> Pharo-project(a)lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
Dec. 31, 2008
Re: [Pharo-project] About SmallDIctionary
by Stéphane Ducasse
thanks.
I will harvest that when I'm done with my floor.
Stef
> While inquiring generalization of #removeAll and #removeAll: related
> to Klaus fix http://bugs.squeak.org/view.php?id=6937 ,
> I came across two SmallDictionary minor bugs
> http://bugs.squeak.org/view.php?id=7256 ,
> http://bugs.squeak.org/view.php?id=7257 .
>
> The first one by reading code, the second one by this procedure :
> - a) fileOut DictionaryTest,
> - b) replaced Dictionary with SmallDictionary (ALT+j),
> - c) fileIn again.
>
> Of course, the tests should be factored better rather than just
> duplicated.
> But I don't know how to inherit tests from super...
> (super tests are not executed by the TestRunner)
>
> See attached .st
>
> --------------------------------
>
> Oh, and i had to change this test:
>
> testKeyAtValue
> | dict |
> dict := Dictionary new.
> dict at: #a put: 1.
> dict at: #c put: 1.
> self assert: (dict keyAtValue: 1) = #c.
> "ugly may be a bug, why not having a set #a and #c"
>
> Should be :
>
> self assert: ((dict keyAtValue: 1) = #c) | (dict keyAtValue: 1) =
> #a).
> The result highly depends on:
> - 1) hash algorithm
> - 2) Dictionary capacity (the default capacity for this test)
> Asserting that it is #c :
> - 1) does not help the reader to guess the specification (i would
> understand it is always #c)
> - 2) is very fragile, not portable, and might change unexpectedly
>
> For the case of SmallDictionary, we could eventually assert:
> self assert: (dict keyAtValue: 1) = #a.
> Because keys are ordered and will retain addition order.
>
> --------------------------------
>
> Another point: these two methods should be removed shouldn't they?
> SmallDictionary removeSelector: #keyForPatternVariableNode:.
> SmallDictionary removeSelector: #valueForPatternVariableNode:.
>
> 'From Pharo0.1 of 16 May 2008 [Latest update: #10201] on 30 December
> 2008 at 10:45:19 pm'!
> TestCase subclass: #SmallDictionaryTest
> uses: TIncludesTest + TCloneTest
> instanceVariableNames: 'emptyDict nonEmptyDict'
> classVariableNames: ''
> poolDictionaries: ''
> category: 'CollectionsTests-Unordered'!
>
> !SmallDictionaryTest methodsFor: 'testing' stamp: 'nice 12/30/2008
> 19:26'!
> testCapacity
> "this is a non regression test for http://bugs.squeak.org/view.php?id=7256
> "
>
> self shouldnt: [SmallDictionary new capacity] raise: Error! !
>
> !SmallDictionaryTest methodsFor: 'testing' stamp: 'ar 6/13/2008
> 00:14'!
> testCollect
> "Ensure that SmallDictionary>>collect: answers a dictionary not
> something else"
> | dict expected result |
> dict := SmallDictionary newFromPairs:{
> #first. 1.
> #second. 2.
> #third. 3.
> #fourth. 4.
> #fifth. 5.
> }.
> result := dict collect:[:each| each asWords].
> expected := SmallDictionary newFromPairs:{
> #first. 'one'.
> #second. 'two'.
> #third. 'three'.
> #fourth. 'four'.
> #fifth. 'five'.
> }.
> self assert: result = expected.! !
>
> !SmallDictionaryTest methodsFor: 'testing' stamp: 'nice 12/30/2008
> 19:43'!
> testDictionaryConcatenation
> "self run: #testDictionaryConcatenation"
>
>
> | dict1 dict2 dict3 |
> dict1 := SmallDictionary new.
> dict1 at: #a put: 'Nicolas' ; at: #b put: 'Damien'.
>
> dict2 := SmallDictionary new.
> dict2 at: #a put: 'Christophe' ; at: #c put: 'Anthony'.
> dict3 := dict1, dict2.
>
> self assert: (dict3 at: #a) = 'Christophe'.
> self assert: (dict3 at: #b) = 'Damien'.
> self assert: (dict3 at: #c) = 'Anthony'.
>
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'testing' stamp: 'ar 6/13/2008
> 00:13'!
> testReject
> "Ensure that SmallDictionary>>reject: answers a dictionary not
> something else"
> | dict expected result |
> dict := SmallDictionary newFromPairs:{
> #first. 1.
> #second. 2.
> #third. 3.
> #fourth. 4.
> #fifth. 5.
> }.
> result := dict reject:[:each| each odd].
> expected := SmallDictionary newFromPairs:{
> #second. 2.
> #fourth. 4.
> }.
> self assert: result = expected.! !
>
> !SmallDictionaryTest methodsFor: 'testing' stamp: 'ar 6/13/2008
> 00:12'!
> testSelect
> "Ensure that SmallDictionary>>select: answers a dictionary not
> something else"
> | dict expected result |
> dict := SmallDictionary newFromPairs:{
> #first. 1.
> #second. 2.
> #third. 3.
> #fourth. 4.
> #fifth. 5.
> }.
> result := dict select:[:each| each odd].
> expected := SmallDictionary newFromPairs:{
> #first. 1.
> #third. 3.
> #fifth. 5.
> }.
> self assert: result = expected.! !
>
>
> !SmallDictionaryTest methodsFor: 'setup' stamp: 'stephane.ducasse
> 11/21/2008 15:03'!
> setUp
>
> emptyDict := SmallDictionary new.
> nonEmptyDict := SmallDictionary new.
> nonEmptyDict
> at: #a put: 20;
> at: #b put: 30;
> at: #c put: 40;
> at: #d put: 30.! !
>
>
> !SmallDictionaryTest methodsFor: 'tests - includes' stamp:
> 'stephane.ducasse 11/21/2008 15:05'!
> anotherElementNotIn
> ^ 42! !
>
> !SmallDictionaryTest methodsFor: 'tests - includes' stamp:
> 'stephane.ducasse 11/21/2008 15:04'!
> collection
> ^ #(1 2 3)! !
>
> !SmallDictionaryTest methodsFor: 'tests - includes' stamp:
> 'stephane.ducasse 11/21/2008 15:04'!
> elementNotIn
>
> ^ 666! !
>
> !SmallDictionaryTest methodsFor: 'tests - includes' stamp:
> 'stephane.ducasse 11/21/2008 15:04'!
> empty
> ^ emptyDict! !
>
> !SmallDictionaryTest methodsFor: 'tests - includes' stamp:
> 'stephane.ducasse 11/21/2008 15:04'!
> nonEmpty
> ^ nonEmptyDict! !
>
>
>
> !SmallDictionaryTest methodsFor: 'association tests' stamp: 'NDCC
> 3/8/2006 08:14'!
> testAddAssociation
> "self run:#testAddAssociation"
> "self debug:#testAddAssociation"
>
> | dict |
> dict := SmallDictionary new.
> dict at: #a put: 1.
> dict at: #b put: 2.
> self assert: (dict at: #a) = 1.
> self assert: (dict at: #b) = 2.
>
> dict at: #a put: 10.
> dict at: #c put: 2.
>
> self assert: (dict at: #a) = 10.
> self assert: (dict at: #b) = 2.
> self assert: (dict at: #c) = 2
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'association tests' stamp:
> 'ndCollectionsTests-Unordered 3/16/2006 10:30'!
> testAssociationsSelect
> | answer d |
> d := SmallDictionary new.
> d at: (Array with: #hello with: #world)
> put: #fooBar.
> d at: Smalltalk put: #'Smalltalk is the key'.
> d at: #Smalltalk put: Smalltalk.
> answer := d
> associationsSelect: [:assoc | assoc key == #Smalltalk
> and: [assoc value == Smalltalk]].
> self
> should: [answer isKindOf: SmallDictionary].
> self
> should: [answer size == 1].
> self
> should: [(answer at: #Smalltalk)
> == Smalltalk].
> answer := d
> associationsSelect: [:assoc | assoc key == #NoSuchKey
> and: [assoc value == #NoSuchValue]].
> self
> should: [answer isKindOf: SmallDictionary].
> self
> should: [answer size == 0]! !
>
> !SmallDictionaryTest methodsFor: 'association tests' stamp:
> 'stephane.ducasse 11/21/2008 15:00'!
> testIncludesAssociation
> "self run:#testIncludesAssociation"
>
> | dict |
> dict := SmallDictionary new.
> dict at: #a put: 1.
> dict at: #b put: 2.
> self assert: (dict includesAssociation: (#a -> 1)).
> self assert: (dict includesAssociation: (#b -> 2)).
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'association tests' stamp:
> 'ndCollectionsTests-Unordered 3/16/2006 10:25'!
> testIncludesAssociationNoValue
> "self run:#testIncludesAssociationNoValue"
> "self debug:#testIncludesAssociationNoValue"
>
> | dict a1 a3 |
> a1 := Association key: #Italie.
> a3 := Association key: #France value: 'Paris'.
>
> self assert: (a1 key = #Italie).
> self assert: (a1 value isNil).
>
> dict := SmallDictionary new.
> dict add: a1.
> dict add: a3.
> self assert: (dict includesKey: #France).
> self assert: (dict includesKey: #Italie).
> self assert: (dict at: #Italie) isNil.
> self assert: (dict at: #France) = 'Paris'
>
>
>
> ! !
>
>
> !SmallDictionaryTest methodsFor: 'basic tests' stamp:
> 'ndCollectionsTests-Unordered 3/16/2006 10:26'!
> testAtError
> "self run: #testAtError"
>
> | dict |
> dict := SmallDictionary new.
> dict at: #a put: 666.
> self shouldnt: [ dict at: #a ] raise: Error.
> self should: [ dict at: #b ] raise: Error.
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'basic tests' stamp: 'NDCC 3/1/2006
> 14:27'!
> testAtIfAbsent
> "self run: #testAtIfAbsent"
>
> | dict |
> dict := SmallDictionary new.
> dict at: #a put: 666.
>
> self assert: (dict at: #a ifAbsent: [nil]) = 666.
>
> self assert: (dict at: #b ifAbsent: [nil]) isNil.
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'basic tests' stamp: 'NDCC 3/8/2006
> 09:28'!
> testAtPut
> "self run: #testAtPut"
> "self debug: #testAtPut"
>
> | adictionary |
> adictionary := SmallDictionary new.
> adictionary at: #a put: 3.
> self assert: (adictionary at: #a) = 3.
> adictionary at: #a put: 3.
> adictionary at: #a put: 4.
> self assert: (adictionary at: #a) = 4.
> adictionary at: nil put: 666.
> self assert: (adictionary at: nil) = 666! !
>
> !SmallDictionaryTest methodsFor: 'basic tests' stamp: 'marcus.denker
> 9/14/2008 21:15'!
> testAtPutNil
> "self run: #testAtPut"
> "self debug: #testAtPut"
>
> | dict |
> dict := SmallDictionary new.
> dict at: nil put: 1.
> self assert: (dict at: nil) = 1.
> dict at: #a put: nil.
> self assert: (dict at: #a) isNil.
> dict at: nil put: nil.
> self assert: (dict at: nil) isNil.
>
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'basic tests' stamp:
> 'ndCollectionsTests-Unordered 3/16/2006 10:24'!
> testIncludesKey
> "self run:#testIncludesKey"
> "self debug:#testIncludesKey"
>
> | dict a1 a2 a3 |
> a1 := Association key: 'Italie'.
> a2 := Association new.
> a3 := Association key: 'France' value: 'Paris'.
>
> dict := SmallDictionary new.
> dict add: a1 .
> dict add: a2.
> dict add: a3.
> self assert: (dict includesKey: #France).
> self assert: (dict includesKey: 'France').
> self assert: (dict includesKey: #Italie).
> self assert: (dict includesKey: nil).
>
> self assert: (dict at: 'France' ) = 'Paris'.
> ! !
>
> !SmallDictionaryTest methodsFor: 'basic tests' stamp: 'NDCC 3/8/2006
> 09:41'!
> testOccurrencesOf
> "self run:#testOccurrencesOf"
>
> | dict |
> dict := SmallDictionary new.
> dict at: #a put: 1.
> dict at: #b put: 2.
> dict at: #c put: 1.
> dict at: #d put: 3.
> dict at: nil put: nil.
> dict at: #z put: nil.
>
>
> self assert: (dict occurrencesOf: 1 ) = 2.
> self assert: (dict occurrencesOf: nil ) = 2.
>
>
>
> ! !
>
>
> !SmallDictionaryTest methodsFor: 'implementation tests' stamp:
> 'stephaneducasse 9/18/2005 10:48'!
> testAtNil
> "(self run: #testAtNil)"
> "nil is a valid key in squeak. In VW nil is not a valid key"
> "Ansi 1.9 p, 168
> 5.7.2.5 Message: at: key put: newElement
> Synopsis
> Store newElement at key in the receiver. Answer newElement.
> Definition: <abstractSmallDictionary>
> If lookup succeeds for key, then newElement replaces the
> element previously stored at key.
> Otherwise, the newElement is stored at the new key. In either
> case, subsequent successful
> lookups for key will answer newElement. Answer newElement.
>
> The result is undefined if the key is nil.
>
> This clearly indicates that different smalltalks where doing
> different assumptions."
>
>
>
> | dict1 |
> dict1 := SmallDictionary new.
> self shouldnt: [ dict1 at: nil put: #none] raise: Error.
> self assert: (dict1 at: nil) = #none.
> ! !
>
> !SmallDictionaryTest methodsFor: 'implementation tests' stamp:
> 'ndCollectionsTests-Unordered 3/16/2006 10:29'!
> testPseudoVariablesAreValidKeys
> "(self run: #testPseudoVariablesAreValidKeys)"
> "true and false are valid keys"
>
> | dict1 |
> dict1 := SmallDictionary new.
> self shouldnt: [dict1 at: true put: #true] raise: Error.
> self assert: (dict1 at: true) = #true.
>
> self shouldnt: [dict1 at: false put: #false] raise: Error.
> self assert: (dict1 at: false) = #false.! !
>
>
> !SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'nice
> 12/30/2008 22:43'!
> testKeyAtValue
> "self run: #testKeyAtValue"
> "self debug: #testKeyAtValue"
>
> | dict |
> dict := SmallDictionary new.
> dict at: #a put: 1.
> dict at: #b put: 2.
> dict at: #c put: 1.
>
> self assert: (dict keyAtValue: 2) = #b.
> self assert: (dict keyAtValue: 1) = #c | ((dict keyAtValue: 1) = #a).
> "ugly may be a bug, why not having a set #a and #c"
>
> self should: [dict keyAtValue: 0] raise: Error
>
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'keys and value tests' stamp:
> 'ndCollectionsTests-Unordered 3/16/2006 10:23'!
> testKeys
>
> "self run:#testKeys "
>
> | a1 a2 dict |
> a1 := Association key: 'France' value: 'Paris'.
> a2 := Association key: 'Italie' value: 'Rome'.
> dict := SmallDictionary new.
> dict add: a1.
> dict add: a2.
>
> self assert: (dict keys size) = 2.
>
> self assert: (dict keys includes: #France)
>
>
>
>
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'NDCC
> 3/8/2006 09:13'!
> testKeysDo
> "self run: #testKeysDo"
> "self debug: #testKeysDo"
>
> | dict res |
> dict := SmallDictionary new.
>
> dict at: #a put: 33.
> dict at: #b put: 66.
>
> res := OrderedCollection new.
> dict keysDo: [ :each | res add: each].
>
> self assert: res asSet = #(a b) asSet.
>
>
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'NDCC
> 3/8/2006 08:56'!
> testRemoveKey
> "self run:#testRemoveKey "
>
> | dict |
> dict := SmallDictionary new.
> dict at: #a put: 1.
> dict at: #b put: 2.
>
> self assert: (dict keys size) = 2.
> dict removeKey: #a.
> self assert: dict keys size = 1.
>
> self should: [dict at: #a] raise: Error.
> self assert: (dict at: #b) = 2
>
>
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'NDCC
> 3/8/2006 08:16'!
> testSmallDictionaryConcatenation
> "self run: #testSmallDictionaryConcatenation"
>
>
> | dict1 dict2 dict3 |
> dict1 := SmallDictionary new.
> dict1 at: #a put: 'Nicolas' ; at: #b put: 'Damien'.
>
> dict2 := SmallDictionary new.
> dict2 at: #a put: 'Christophe' ; at: #c put: 'Anthony'.
> dict3 := dict1, dict2.
>
> self assert: (dict3 at: #a) = 'Christophe'.
> self assert: (dict3 at: #b) = 'Damien'.
> self assert: (dict3 at: #c) = 'Anthony'.
>
>
> ! !
>
> !SmallDictionaryTest methodsFor: 'keys and value tests' stamp:
> 'ndCollectionsTests-Unordered 3/16/2006 10:23'!
> testValues
> "self run:#testValues "
>
> | a1 a2 a3 dict |
> a1 := Association key: 'France' value: 'Paris'.
> a2 := Association key: 'Italie' value: 'Rome'.
> dict := SmallDictionary new.
> dict add: a1.
> dict add: a2.
>
> self assert: (dict values size ) = 2.
> self assert: (dict values includes: 'Paris').
>
> a3 := Association new.
> dict add: a3.
> self assert: (dict values size ) = 3.
> self assert: (dict values includes: nil).
>
>
>
>
>
>
>
>
>
> ! !
>
>
> !SmallDictionaryTest methodsFor: 'tests' stamp: 'zz 12/7/2005 19:59'!
> testAdd
>
> | dict |
> dict := SmallDictionary new.
> dict add: #a -> 1.
> dict add: #b -> 2.
> self assert: (dict at: #a) = 1.
> self assert: (dict at: #b) = 2! !
>
> !SmallDictionaryTest methodsFor: 'tests' stamp: 'zz 12/7/2005 19:55'!
> testAddAll
>
> | dict1 dict2 |
> dict1 := SmallDictionary new.
> dict1 at: #a put:1 ; at: #b put: 2.
> dict2 := SmallDictionary new.
> dict2 at: #a put: 3 ; at: #c put: 4.
> dict1 addAll: dict2.
> self assert: (dict1 at: #a) = 3.
> self assert: (dict1 at: #b) = 2.
> self assert: (dict1 at: #c) = 4.! !
>
> !SmallDictionaryTest methodsFor: 'tests' stamp: 'zz 12/7/2005 19:57'!
> testComma
>
> | dict1 dict2 dict3 |
> dict1 := SmallDictionary new.
> dict1 at: #a put:1 ; at: #b put: 2.
> dict2 := SmallDictionary new.
> dict2 at: #a put: 3 ; at: #c put: 4.
> dict3 := dict1, dict2.
> self assert: (dict3 at: #a) = 3.
> self assert: (dict3 at: #b) = 2.
> self assert: (dict3 at: #c) = 4.! !
>
> !SmallDictionaryTest methodsFor: 'tests' stamp: 'stephaneducasse
> 9/18/2005 10:45'!
> testPseudo
> "(self run: #testPseudo)"
> "true and false are valid keys"
>
> | dict1 |
> dict1 := SmallDictionary new.
> self shouldnt: [dict1 at: true put: #true] raise: Error.
> self assert: (dict1 at: true) = #true.
>
> self shouldnt: [dict1 at: false put: #false] raise: Error.
> self assert: (dict1 at: false) = #false.! !
>
> "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
>
> SmallDictionaryTest class
> uses: TIncludesTest classTrait + TCloneTest classTrait
> instanceVariableNames: 'testToto pt1'!
> _______________________________________________
> Pharo-project mailing list
> Pharo-project(a)lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Dec. 31, 2008
[Pharo-project] Dictionary as a Set
by nicolas cellier
I reported some important distinction between Dictionaries and Sets at
http://bugs.squeak.org/view.php?id=7258.
The problem has been introduced by the change of Association>>#=.
Logically, Dictionary should have been detached from Set at this time,
since it was no more a Set of associations as it used to.
Stéphane Ducasse <stephane.ducasse@...> writes:
>
> This is interesting that you present that as a Bag. I'm too sick now
> (my brain
> is wandering across my room) to really reply something clever.
>
> I thought that a bag was more an counting elements container
>
For me the sole specification is that a Bag unlike a Set can hold
several equal elements.
The fact that it can count them fast rather than enumerating the whole
collection is an implementation detail (an important detail of course).
> > a) multiple values can be in the dictionary:
> > (Dictionary new) at: 'one' put: 1; at: 'first' put: 1; yourself.
>
> For me to be bag would mean more
>
> > dc := (DictionaryBag new) at: 'one' put: 1; at: 'one' put: 2;
> > yourself.
> dc at: one
> -> #(1 2)
>
> Stef
>
a DictionaryOfBags ?
One thing Dictionary is not : a Bag of associations.
Think of it as a Bag of values.
As long as you don't override a key, a Dictionary behaves like a Bag:
digits := 0 to: 9.
b := Bag new.
d := Dictionary new.
digits do: [:i | b add: i//2].
digits do: [:i | d at: i printString put: i//2].
digits do: [:i |
self assert: (b occurrencesOf: i) = (d occurrencesOf: i)].
Personnally, I would expect
d values.
to answer a Bag (unordered) rather than an Array (arbitrary order)...
The only advantage of an Array is that it is faster than a Bag...
Dec. 30, 2008
[Pharo-project] About SmallDIctionary
by nicolas cellier
While inquiring generalization of #removeAll and #removeAll: related to
Klaus fix http://bugs.squeak.org/view.php?id=6937 ,
I came across two SmallDictionary minor bugs
http://bugs.squeak.org/view.php?id=7256 ,
http://bugs.squeak.org/view.php?id=7257 .
The first one by reading code, the second one by this procedure :
- a) fileOut DictionaryTest,
- b) replaced Dictionary with SmallDictionary (ALT+j),
- c) fileIn again.
Of course, the tests should be factored better rather than just duplicated.
But I don't know how to inherit tests from super...
(super tests are not executed by the TestRunner)
See attached .st
--------------------------------
Oh, and i had to change this test:
testKeyAtValue
| dict |
dict := Dictionary new.
dict at: #a put: 1.
dict at: #c put: 1.
self assert: (dict keyAtValue: 1) = #c.
"ugly may be a bug, why not having a set #a and #c"
Should be :
self assert: ((dict keyAtValue: 1) = #c) | (dict keyAtValue: 1) = #a).
The result highly depends on:
- 1) hash algorithm
- 2) Dictionary capacity (the default capacity for this test)
Asserting that it is #c :
- 1) does not help the reader to guess the specification (i would
understand it is always #c)
- 2) is very fragile, not portable, and might change unexpectedly
For the case of SmallDictionary, we could eventually assert:
self assert: (dict keyAtValue: 1) = #a.
Because keys are ordered and will retain addition order.
--------------------------------
Another point: these two methods should be removed shouldn't they?
SmallDictionary removeSelector: #keyForPatternVariableNode:.
SmallDictionary removeSelector: #valueForPatternVariableNode:.
'From Pharo0.1 of 16 May 2008 [Latest update: #10201] on 30 December 2008 at 10:45:19 pm'!
TestCase subclass: #SmallDictionaryTest
uses: TIncludesTest + TCloneTest
instanceVariableNames: 'emptyDict nonEmptyDict'
classVariableNames: ''
poolDictionaries: ''
category: 'CollectionsTests-Unordered'!
!SmallDictionaryTest methodsFor: 'testing' stamp: 'nice 12/30/2008 19:26'!
testCapacity
"this is a non regression test for http://bugs.squeak.org/view.php?id=7256"
self shouldnt: [SmallDictionary new capacity] raise: Error! !
!SmallDictionaryTest methodsFor: 'testing' stamp: 'ar 6/13/2008 00:14'!
testCollect
"Ensure that SmallDictionary>>collect: answers a dictionary not something else"
| dict expected result |
dict := SmallDictionary newFromPairs:{
#first. 1.
#second. 2.
#third. 3.
#fourth. 4.
#fifth. 5.
}.
result := dict collect:[:each| each asWords].
expected := SmallDictionary newFromPairs:{
#first. 'one'.
#second. 'two'.
#third. 'three'.
#fourth. 'four'.
#fifth. 'five'.
}.
self assert: result = expected.! !
!SmallDictionaryTest methodsFor: 'testing' stamp: 'nice 12/30/2008 19:43'!
testDictionaryConcatenation
"self run: #testDictionaryConcatenation"
| dict1 dict2 dict3 |
dict1 := SmallDictionary new.
dict1 at: #a put: 'Nicolas' ; at: #b put: 'Damien'.
dict2 := SmallDictionary new.
dict2 at: #a put: 'Christophe' ; at: #c put: 'Anthony'.
dict3 := dict1, dict2.
self assert: (dict3 at: #a) = 'Christophe'.
self assert: (dict3 at: #b) = 'Damien'.
self assert: (dict3 at: #c) = 'Anthony'.
! !
!SmallDictionaryTest methodsFor: 'testing' stamp: 'ar 6/13/2008 00:13'!
testReject
"Ensure that SmallDictionary>>reject: answers a dictionary not something else"
| dict expected result |
dict := SmallDictionary newFromPairs:{
#first. 1.
#second. 2.
#third. 3.
#fourth. 4.
#fifth. 5.
}.
result := dict reject:[:each| each odd].
expected := SmallDictionary newFromPairs:{
#second. 2.
#fourth. 4.
}.
self assert: result = expected.! !
!SmallDictionaryTest methodsFor: 'testing' stamp: 'ar 6/13/2008 00:12'!
testSelect
"Ensure that SmallDictionary>>select: answers a dictionary not something else"
| dict expected result |
dict := SmallDictionary newFromPairs:{
#first. 1.
#second. 2.
#third. 3.
#fourth. 4.
#fifth. 5.
}.
result := dict select:[:each| each odd].
expected := SmallDictionary newFromPairs:{
#first. 1.
#third. 3.
#fifth. 5.
}.
self assert: result = expected.! !
!SmallDictionaryTest methodsFor: 'setup' stamp: 'stephane.ducasse 11/21/2008 15:03'!
setUp
emptyDict := SmallDictionary new.
nonEmptyDict := SmallDictionary new.
nonEmptyDict
at: #a put: 20;
at: #b put: 30;
at: #c put: 40;
at: #d put: 30.! !
!SmallDictionaryTest methodsFor: 'tests - includes' stamp: 'stephane.ducasse 11/21/2008 15:05'!
anotherElementNotIn
^ 42! !
!SmallDictionaryTest methodsFor: 'tests - includes' stamp: 'stephane.ducasse 11/21/2008 15:04'!
collection
^ #(1 2 3)! !
!SmallDictionaryTest methodsFor: 'tests - includes' stamp: 'stephane.ducasse 11/21/2008 15:04'!
elementNotIn
^ 666! !
!SmallDictionaryTest methodsFor: 'tests - includes' stamp: 'stephane.ducasse 11/21/2008 15:04'!
empty
^ emptyDict! !
!SmallDictionaryTest methodsFor: 'tests - includes' stamp: 'stephane.ducasse 11/21/2008 15:04'!
nonEmpty
^ nonEmptyDict! !
!SmallDictionaryTest methodsFor: 'association tests' stamp: 'NDCC 3/8/2006 08:14'!
testAddAssociation
"self run:#testAddAssociation"
"self debug:#testAddAssociation"
| dict |
dict := SmallDictionary new.
dict at: #a put: 1.
dict at: #b put: 2.
self assert: (dict at: #a) = 1.
self assert: (dict at: #b) = 2.
dict at: #a put: 10.
dict at: #c put: 2.
self assert: (dict at: #a) = 10.
self assert: (dict at: #b) = 2.
self assert: (dict at: #c) = 2
! !
!SmallDictionaryTest methodsFor: 'association tests' stamp: 'ndCollectionsTests-Unordered 3/16/2006 10:30'!
testAssociationsSelect
| answer d |
d := SmallDictionary new.
d at: (Array with: #hello with: #world)
put: #fooBar.
d at: Smalltalk put: #'Smalltalk is the key'.
d at: #Smalltalk put: Smalltalk.
answer := d
associationsSelect: [:assoc | assoc key == #Smalltalk
and: [assoc value == Smalltalk]].
self
should: [answer isKindOf: SmallDictionary].
self
should: [answer size == 1].
self
should: [(answer at: #Smalltalk)
== Smalltalk].
answer := d
associationsSelect: [:assoc | assoc key == #NoSuchKey
and: [assoc value == #NoSuchValue]].
self
should: [answer isKindOf: SmallDictionary].
self
should: [answer size == 0]! !
!SmallDictionaryTest methodsFor: 'association tests' stamp: 'stephane.ducasse 11/21/2008 15:00'!
testIncludesAssociation
"self run:#testIncludesAssociation"
| dict |
dict := SmallDictionary new.
dict at: #a put: 1.
dict at: #b put: 2.
self assert: (dict includesAssociation: (#a -> 1)).
self assert: (dict includesAssociation: (#b -> 2)).
! !
!SmallDictionaryTest methodsFor: 'association tests' stamp: 'ndCollectionsTests-Unordered 3/16/2006 10:25'!
testIncludesAssociationNoValue
"self run:#testIncludesAssociationNoValue"
"self debug:#testIncludesAssociationNoValue"
| dict a1 a3 |
a1 := Association key: #Italie.
a3 := Association key: #France value: 'Paris'.
self assert: (a1 key = #Italie).
self assert: (a1 value isNil).
dict := SmallDictionary new.
dict add: a1.
dict add: a3.
self assert: (dict includesKey: #France).
self assert: (dict includesKey: #Italie).
self assert: (dict at: #Italie) isNil.
self assert: (dict at: #France) = 'Paris'
! !
!SmallDictionaryTest methodsFor: 'basic tests' stamp: 'ndCollectionsTests-Unordered 3/16/2006 10:26'!
testAtError
"self run: #testAtError"
| dict |
dict := SmallDictionary new.
dict at: #a put: 666.
self shouldnt: [ dict at: #a ] raise: Error.
self should: [ dict at: #b ] raise: Error.
! !
!SmallDictionaryTest methodsFor: 'basic tests' stamp: 'NDCC 3/1/2006 14:27'!
testAtIfAbsent
"self run: #testAtIfAbsent"
| dict |
dict := SmallDictionary new.
dict at: #a put: 666.
self assert: (dict at: #a ifAbsent: [nil]) = 666.
self assert: (dict at: #b ifAbsent: [nil]) isNil.
! !
!SmallDictionaryTest methodsFor: 'basic tests' stamp: 'NDCC 3/8/2006 09:28'!
testAtPut
"self run: #testAtPut"
"self debug: #testAtPut"
| adictionary |
adictionary := SmallDictionary new.
adictionary at: #a put: 3.
self assert: (adictionary at: #a) = 3.
adictionary at: #a put: 3.
adictionary at: #a put: 4.
self assert: (adictionary at: #a) = 4.
adictionary at: nil put: 666.
self assert: (adictionary at: nil) = 666! !
!SmallDictionaryTest methodsFor: 'basic tests' stamp: 'marcus.denker 9/14/2008 21:15'!
testAtPutNil
"self run: #testAtPut"
"self debug: #testAtPut"
| dict |
dict := SmallDictionary new.
dict at: nil put: 1.
self assert: (dict at: nil) = 1.
dict at: #a put: nil.
self assert: (dict at: #a) isNil.
dict at: nil put: nil.
self assert: (dict at: nil) isNil.
! !
!SmallDictionaryTest methodsFor: 'basic tests' stamp: 'ndCollectionsTests-Unordered 3/16/2006 10:24'!
testIncludesKey
"self run:#testIncludesKey"
"self debug:#testIncludesKey"
| dict a1 a2 a3 |
a1 := Association key: 'Italie'.
a2 := Association new.
a3 := Association key: 'France' value: 'Paris'.
dict := SmallDictionary new.
dict add: a1 .
dict add: a2.
dict add: a3.
self assert: (dict includesKey: #France).
self assert: (dict includesKey: 'France').
self assert: (dict includesKey: #Italie).
self assert: (dict includesKey: nil).
self assert: (dict at: 'France' ) = 'Paris'.
! !
!SmallDictionaryTest methodsFor: 'basic tests' stamp: 'NDCC 3/8/2006 09:41'!
testOccurrencesOf
"self run:#testOccurrencesOf"
| dict |
dict := SmallDictionary new.
dict at: #a put: 1.
dict at: #b put: 2.
dict at: #c put: 1.
dict at: #d put: 3.
dict at: nil put: nil.
dict at: #z put: nil.
self assert: (dict occurrencesOf: 1 ) = 2.
self assert: (dict occurrencesOf: nil ) = 2.
! !
!SmallDictionaryTest methodsFor: 'implementation tests' stamp: 'stephaneducasse 9/18/2005 10:48'!
testAtNil
"(self run: #testAtNil)"
"nil is a valid key in squeak. In VW nil is not a valid key"
"Ansi 1.9 p, 168
5.7.2.5 Message: at: key put: newElement
Synopsis
Store newElement at key in the receiver. Answer newElement.
Definition: <abstractSmallDictionary>
If lookup succeeds for key, then newElement replaces the element previously stored at key.
Otherwise, the newElement is stored at the new key. In either case, subsequent successful
lookups for key will answer newElement. Answer newElement.
The result is undefined if the key is nil.
This clearly indicates that different smalltalks where doing different assumptions."
| dict1 |
dict1 := SmallDictionary new.
self shouldnt: [ dict1 at: nil put: #none] raise: Error.
self assert: (dict1 at: nil) = #none.
! !
!SmallDictionaryTest methodsFor: 'implementation tests' stamp: 'ndCollectionsTests-Unordered 3/16/2006 10:29'!
testPseudoVariablesAreValidKeys
"(self run: #testPseudoVariablesAreValidKeys)"
"true and false are valid keys"
| dict1 |
dict1 := SmallDictionary new.
self shouldnt: [dict1 at: true put: #true] raise: Error.
self assert: (dict1 at: true) = #true.
self shouldnt: [dict1 at: false put: #false] raise: Error.
self assert: (dict1 at: false) = #false.! !
!SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'nice 12/30/2008 22:43'!
testKeyAtValue
"self run: #testKeyAtValue"
"self debug: #testKeyAtValue"
| dict |
dict := SmallDictionary new.
dict at: #a put: 1.
dict at: #b put: 2.
dict at: #c put: 1.
self assert: (dict keyAtValue: 2) = #b.
self assert: (dict keyAtValue: 1) = #c | ((dict keyAtValue: 1) = #a).
"ugly may be a bug, why not having a set #a and #c"
self should: [dict keyAtValue: 0] raise: Error
! !
!SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'ndCollectionsTests-Unordered 3/16/2006 10:23'!
testKeys
"self run:#testKeys "
| a1 a2 dict |
a1 := Association key: 'France' value: 'Paris'.
a2 := Association key: 'Italie' value: 'Rome'.
dict := SmallDictionary new.
dict add: a1.
dict add: a2.
self assert: (dict keys size) = 2.
self assert: (dict keys includes: #France)
! !
!SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'NDCC 3/8/2006 09:13'!
testKeysDo
"self run: #testKeysDo"
"self debug: #testKeysDo"
| dict res |
dict := SmallDictionary new.
dict at: #a put: 33.
dict at: #b put: 66.
res := OrderedCollection new.
dict keysDo: [ :each | res add: each].
self assert: res asSet = #(a b) asSet.
! !
!SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'NDCC 3/8/2006 08:56'!
testRemoveKey
"self run:#testRemoveKey "
| dict |
dict := SmallDictionary new.
dict at: #a put: 1.
dict at: #b put: 2.
self assert: (dict keys size) = 2.
dict removeKey: #a.
self assert: dict keys size = 1.
self should: [dict at: #a] raise: Error.
self assert: (dict at: #b) = 2
! !
!SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'NDCC 3/8/2006 08:16'!
testSmallDictionaryConcatenation
"self run: #testSmallDictionaryConcatenation"
| dict1 dict2 dict3 |
dict1 := SmallDictionary new.
dict1 at: #a put: 'Nicolas' ; at: #b put: 'Damien'.
dict2 := SmallDictionary new.
dict2 at: #a put: 'Christophe' ; at: #c put: 'Anthony'.
dict3 := dict1, dict2.
self assert: (dict3 at: #a) = 'Christophe'.
self assert: (dict3 at: #b) = 'Damien'.
self assert: (dict3 at: #c) = 'Anthony'.
! !
!SmallDictionaryTest methodsFor: 'keys and value tests' stamp: 'ndCollectionsTests-Unordered 3/16/2006 10:23'!
testValues
"self run:#testValues "
| a1 a2 a3 dict |
a1 := Association key: 'France' value: 'Paris'.
a2 := Association key: 'Italie' value: 'Rome'.
dict := SmallDictionary new.
dict add: a1.
dict add: a2.
self assert: (dict values size ) = 2.
self assert: (dict values includes: 'Paris').
a3 := Association new.
dict add: a3.
self assert: (dict values size ) = 3.
self assert: (dict values includes: nil).
! !
!SmallDictionaryTest methodsFor: 'tests' stamp: 'zz 12/7/2005 19:59'!
testAdd
| dict |
dict := SmallDictionary new.
dict add: #a -> 1.
dict add: #b -> 2.
self assert: (dict at: #a) = 1.
self assert: (dict at: #b) = 2! !
!SmallDictionaryTest methodsFor: 'tests' stamp: 'zz 12/7/2005 19:55'!
testAddAll
| dict1 dict2 |
dict1 := SmallDictionary new.
dict1 at: #a put:1 ; at: #b put: 2.
dict2 := SmallDictionary new.
dict2 at: #a put: 3 ; at: #c put: 4.
dict1 addAll: dict2.
self assert: (dict1 at: #a) = 3.
self assert: (dict1 at: #b) = 2.
self assert: (dict1 at: #c) = 4.! !
!SmallDictionaryTest methodsFor: 'tests' stamp: 'zz 12/7/2005 19:57'!
testComma
| dict1 dict2 dict3 |
dict1 := SmallDictionary new.
dict1 at: #a put:1 ; at: #b put: 2.
dict2 := SmallDictionary new.
dict2 at: #a put: 3 ; at: #c put: 4.
dict3 := dict1, dict2.
self assert: (dict3 at: #a) = 3.
self assert: (dict3 at: #b) = 2.
self assert: (dict3 at: #c) = 4.! !
!SmallDictionaryTest methodsFor: 'tests' stamp: 'stephaneducasse 9/18/2005 10:45'!
testPseudo
"(self run: #testPseudo)"
"true and false are valid keys"
| dict1 |
dict1 := SmallDictionary new.
self shouldnt: [dict1 at: true put: #true] raise: Error.
self assert: (dict1 at: true) = #true.
self shouldnt: [dict1 at: false put: #false] raise: Error.
self assert: (dict1 at: false) = #false.! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
SmallDictionaryTest class
uses: TIncludesTest classTrait + TCloneTest classTrait
instanceVariableNames: 'testToto pt1'!
Dec. 30, 2008
Re: [Pharo-project] Dictionary as a Set
by Stéphane Ducasse
This is interesting that you present that as a Bag. I'm too sick now
(my brain
is wandering across my room) to really reply something clever.
I thought that a bag was more an counting elements container
> a) multiple values can be in the dictionary:
> (Dictionary new) at: 'one' put: 1; at: 'first' put: 1; yourself.
For me to be bag would mean more
> dc := (DictionaryBag new) at: 'one' put: 1; at: 'one' put: 2;
> yourself.
dc at: one
-> #(1 2)
Stef
>>>
>> From the st80 origin, Dictionary is a Bag of values.
> Each value is indexed with a unique key.
>
> It is a Bag because:
> a) multiple values can be in the dictionary:
> (Dictionary new) at: 'one' put: 1; at: 'first' put: 1; yourself.
> b) values are unordered:
> | d1 d2 |
> (d1 := Dictionary new: 3) at: 'one' put: 1; at: 'two' put: 2.
> (d2 := Dictionary new: 4) at: 'one' put: 1; at: 'two' put: 2.
> stream := (String new: 64) writeStream.
> d1 do: [:v | stream print: v; cr].
> d2 do: [:v | stream print: v; cr].
> stream contents.
> And as you can see, #do: does apply on values, as would #collect:
> #select:
> #reject: #includes: etc...
>
> The fact that Dictionary is implemented with Associations could be
> seen as a
> private implementation defined feature.
> Though, by tradition, associationsDo: has been made a public
> interface, so as
> the possibility to directly add an Association.
>
> But semantically, Dictionary is not a Set of Associations.
> Example:
> (Set new) add: $a->65; add: $a->1; yourself.
> (Dictionary new) add: $a->65; add: $a->1; yourself.
>
> Dictionary could be viewed as a Set of keys.
>> From that POV, it shared enough property with Set to be implemented
>> as a
> subclass. That's all.
> I proposed once to detach Set and Dictionary from a common ancestor
> just for
> clarity...
>
> Nicolas
>
>
>
>
> _______________________________________________
> Pharo-project mailing list
> Pharo-project(a)lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
Dec. 30, 2008
Re: [Pharo-project] Dictionary as a Set
by Stéphane Ducasse
> There was a discussion about Dicts/Sets on squeak dev more than year
> ago
> http://lists.squeakfoundation.org/pipermail/squeak-dev/2007-June/117840.html
>
> IMO making Dictionary a subclass of Set was mistake.
subclassing indeed is not really a good choice.
> But there's little what can be done without risk of breaking many
> code.
Yes this is not the point. What we want to do is to build another
library for
Smalltalk 3000 :)
> Some related problem - about letting Sets include nils and 'self' as
> elements, also was discussed on squeak-dev.
> It can be done w/o breaking much compatibility.
I would love that this issue gets solved. As eliot pointed it out
this could be done with one primitive been able to preallocate with
a default value. Now I may be wrong.
>
>
> 2008/12/30 nicolas cellier <ncellier(a)ifrance.com>:
>> Sorry to repost, seems that gmane did not like my first attempt...
>>
>>
>> Stéphane Ducasse <stephane.ducasse@...> writes:
>>>
>>>
>>> On Dec 29, 2008, at 12:23 PM, Alexandre Bergel wrote:
>>>
>>>> Dear List,
>>>>
>>>> I was wondering whether I am the only one shocked when I see this:
>>>>
>>>> (Set new add: #b -> 'B'; yourself) includes: #b -> 'B' ====>
>>>> true
>>>> (Set new add: #b -> 'B'; yourself) includes: 'B' ====> false
>>>
>>> this is correct
>>>
>>>> (Dictionary new add: #b -> 'B'; yourself) includes: #b -> 'B'
>>>> ====> false
>>>> (Dictionary new add: #b -> 'B'; yourself) includes: 'B' ====>
>>>> true
>>>
>>> we should check the semantics of includes:
>>>
>>>> Dictionary inherits from Set. This means that if Set would have a
>>>> contract, it would break in Dictionary.
>>>> IMO, we should have
>>>> (Dictionary new add: #b -> 'B'; yourself) includes: #b -> 'B'
>>>> ====>
>>>> true
>>>> (Dictionary new add: #b -> 'B'; yourself) includes: 'B' ====>
>> false
>>>>
>>>> No?
>>>
>>> Dictionary and Set relationship is subclassing so a lot can be
>>> strange.
>>> We should fix that in Bloc.
>>>
>>
>> From the st80 origin, Dictionary is a Bag of values.
>> Each value of this Bag is indexed with a unique key.
>>
>> It is a Bag because:
>> a) multiple values can be in the dictionary:
>> (Dictionary new) at: 'one' put: 1; at: 'first' put: 1; yourself.
>> b) values are unordered:
>> | d1 d2 |
>> (d1 := Dictionary new: 3) at: 'one' put: 1; at: 'two' put: 2.
>> (d2 := Dictionary new: 4) at: 'one' put: 1; at: 'two' put: 2.
>> stream := (String new: 64) writeStream.
>> d1 do: [:v | stream print: v; cr].
>> d2 do: [:v | stream print: v; cr].
>> stream contents.
>> And as you can see, #do: does apply on values, as would #collect:
>> #select: #reject: #includes: etc...
>>
>> The fact that Dictionary is implemented with Associations could be
>> seen
>> as a private implementation-defined feature.
>> Though, by tradition, associationsDo: has been made a public
>> interface,
>> so as the possibility to directly add an Association.
>>
>> But semantically, Dictionary is not a Set of Associations.
>> Example:
>> (Set new) add: $a->65; add: $a->1; yourself.
>> (Dictionary new) add: $a->65; add: $a->1; yourself.
>>
>> Dictionary could be viewed as a Set of keys.
>> From that POV, it shared enough property with Set to be implemented
>> as
>> a subclass. That's all.
>> I proposed once to detach Set and Dictionary and derive them from a
>> common ancestor just for
>> clarity...
>>
>> Nicolas
>>
>>
>> _______________________________________________
>> Pharo-project mailing list
>> Pharo-project(a)lists.gforge.inria.fr
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>
>
>
>
> --
> Best regards,
> Igor Stasenko AKA sig.
> _______________________________________________
> Pharo-project mailing list
> Pharo-project(a)lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
Dec. 30, 2008
Re: [Pharo-project] About the merging tool and "affordance"
by Stéphane Ducasse
excellent because it always takes me one or two minutes to understand
what is presented
and how to interpret it.
On Dec 30, 2008, at 4:18 PM, Gary Chambers wrote:
> Hopefully I'll get some time in the new year to complete the diff
> tool to
> allow in-method merging (composited from either alternative along with
> manual editing). I'll take Damien's suggestion first to label the
> left &
> right panes with their origin.
>
> Regards, Gary.
>
> ----- Original Message -----
> From: "Simon Denier" <Simon.Denier(a)inria.fr>
> To: <pharo-project(a)lists.gforge.inria.fr>
> Sent: Wednesday, December 17, 2008 3:50 PM
> Subject: [Pharo-project] About the merging tool and "affordance"
>
>
>> Hi all
>>
>> With Stef today, we kept scratching our head about how the new
>> merging
>> tool works. Sure it looks cool, but it is not 100% intuitive. A few
>> suggestions:
>>
>> - above the compare panels, show which version is displayed (or which
>> one is the current, which one is the incoming)
>> - the direction of the arrow left/right, depending on whether we keep
>> the current or the incoming, seems wrong. Inverse it?
>>
>> --
>> Simon
>>
>>
>>
>>
>> _______________________________________________
>> Pharo-project mailing list
>> Pharo-project(a)lists.gforge.inria.fr
>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
>
> _______________________________________________
> Pharo-project mailing list
> Pharo-project(a)lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
Dec. 30, 2008
Re: [Pharo-project] About the merging tool and "affordance"
by Gary Chambers
Perhaps the Polymorph groupbox could be used to good effect!
Regards, Gary.
----- Original Message -----
From: David Mitchell
To: Pharo-project(a)lists.gforge.inria.fr
Sent: Tuesday, December 30, 2008 4:35 PM
Subject: Re: [Pharo-project] About the merging tool and "affordance"
Labeling panes would be a nice change for Pharo generally!
On Tue, Dec 30, 2008 at 9:18 AM, Gary Chambers <gazzaguru2(a)btinternet.com> wrote:
Hopefully I'll get some time in the new year to complete the diff tool to
allow in-method merging (composited from either alternative along with
manual editing). I'll take Damien's suggestion first to label the left &
right panes with their origin.
Regards, Gary.
----- Original Message -----
From: "Simon Denier" <Simon.Denier(a)inria.fr>
To: <pharo-project(a)lists.gforge.inria.fr>
Sent: Wednesday, December 17, 2008 3:50 PM
Subject: [Pharo-project] About the merging tool and "affordance"
> Hi all
>
> With Stef today, we kept scratching our head about how the new merging
> tool works. Sure it looks cool, but it is not 100% intuitive. A few
> suggestions:
>
> - above the compare panels, show which version is displayed (or which
> one is the current, which one is the incoming)
> - the direction of the arrow left/right, depending on whether we keep
> the current or the incoming, seems wrong. Inverse it?
>
> --
> Simon
>
>
>
>
> _______________________________________________
> Pharo-project mailing list
> Pharo-project(a)lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________
Pharo-project mailing list
Pharo-project(a)lists.gforge.inria.fr
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
------------------------------------------------------------------------------
_______________________________________________
Pharo-project mailing list
Pharo-project(a)lists.gforge.inria.fr
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Dec. 30, 2008
Re: [Pharo-project] About the merging tool and "affordance"
by David Mitchell
Labeling panes would be a nice change for Pharo generally!
On Tue, Dec 30, 2008 at 9:18 AM, Gary Chambers <gazzaguru2(a)btinternet.com>wrote:
> Hopefully I'll get some time in the new year to complete the diff tool to
> allow in-method merging (composited from either alternative along with
> manual editing). I'll take Damien's suggestion first to label the left &
> right panes with their origin.
>
> Regards, Gary.
>
> ----- Original Message -----
> From: "Simon Denier" <Simon.Denier(a)inria.fr>
> To: <pharo-project(a)lists.gforge.inria.fr>
> Sent: Wednesday, December 17, 2008 3:50 PM
> Subject: [Pharo-project] About the merging tool and "affordance"
>
>
> > Hi all
> >
> > With Stef today, we kept scratching our head about how the new merging
> > tool works. Sure it looks cool, but it is not 100% intuitive. A few
> > suggestions:
> >
> > - above the compare panels, show which version is displayed (or which
> > one is the current, which one is the incoming)
> > - the direction of the arrow left/right, depending on whether we keep
> > the current or the incoming, seems wrong. Inverse it?
> >
> > --
> > Simon
> >
> >
> >
> >
> > _______________________________________________
> > Pharo-project mailing list
> > Pharo-project(a)lists.gforge.inria.fr
> > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
>
> _______________________________________________
> Pharo-project mailing list
> Pharo-project(a)lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
Dec. 30, 2008
[Pharo-project] [ANN] Seaside 2.9 Alpha 2
by Lukas Renggli
Over a month has passed since the last release of Seaside 2.9. We are
very pleased to announced Seaside 2.9 Alpha 2 as a next step towards
the release of Seaside 2.9.
We've mainly worked on two things: (1) closing critical issues that
have been collected in the bug tracker, and (2) making different
configurations of Seaside a snap to load.
1. Closed Issues
================
- Issue 3: A RESTful configuration editor would be very useful
- Issue 87: ColorValue>>hex fixes
- Issue 126: review request handler documentation
- Issue 165: consider WAPainter refactoring
- Issue 193: do we really need #vmStatisticsReportString?
- Issue 200: Seaside 2.9 project page on SqueakSource outdated
- Issue 206: check weird #value call on block in WADebugErrorHandler
- Issue 211: deprecate the scriptcaulous convenience methods on Canvas
- Issue 216: RSS Changes demo produces invalid XML
- Issue 218: WADispatcherEditor doing a #call: in #initialRequest:
- Issue 219: Why does WADecorationTask override #updateStates: ?
- Issue 227: #halt should always halt
- Issue 228: Move the Swazoo server adapter over to WAServerAdaptor
- Issue 234: Source code view is broken after painter refactoring
- Issue 240: JSJsonTests are not portable
- Issue 241: WANumberPrinter>>#digitsOf:base: uses a Float as an Array index
- Issue 242: Using a niladic actionBlock with on:do: in not portable
- Issue 245: WAHalo Source View is broken
- Issue 246: Anchor callbacks should not accept blocks with one argument
- Issue 249: WATree broken in example browser
- Issue 250: JQuery Droppable does not seem to work right
- Issue 251: Accepting code in the browser opens a deprecation warning in Pharo
- Issue 254: Sourceview via halo does not seem to work
- Issue 256: Setting the default entry point does not seem to work
- Issue 258: Bad XHTML for versionuploader
- Issue 259: Request modification to WAPlatformTest>>#testIsResumable
... and uncounted enhancements to the core code and various other
optional packages such as JQuery, JQuery-UI, Swazoo Server Adapters,
etc. We've further improved portability to other Smalltalk dialects,
in this round we mostly focused on VA Smalltalk.
2. The Seaside Builder
======================
We are proud to announce the Seaside Builder, the tool that makes it a
snap to load a specific set of Seaside 2.9 packages into any recent
Pharo or Squeak image:
http://builder.seaside.st
The Seaside Builder lets you either select a predefined configuration
of Seaside packages or manually choose the packages you need. The
builder automatically ensures that all prerequisites are selected and
loaded in the right order. For the first time it is possible to
conveniently choose between the MIT licensed Comanche or the LGPL
licensed Swazoo web server.
At the bottom of the page there are two download options available:
"Load Script" creates a change-set that can be dragged onto any image
causing it to load the selected Seaside packages. There is also the
possibility to download a "Monticello Configuration" of the selected
packages. In the future more download options might become available.
3. Things to be aware of
========================
First of all, it is important to remember that this is an Alpha
release and therefore might not be suited to be used in production. We
are however rapidly approaching the beta phase and disruptive changes
are unlikely. Some of the core team members are already using Seaside
2.9 in production.
You'll find a list of current migration issues at
http://seaside.st/documentation/migration/28to29.
4. When things go wrong
=======================
If you run into problems or encounter problems, please let us know
using the issue tracker at
http://code.google.com/p/seaside/issues/list or through the mailing
list. We are especially interested into feedback concerning "The
Seaside Builder".
--
Lukas Renggli
http://www.lukas-renggli.ch
Dec. 30, 2008