Why can't a Bag answer as a dictionary?

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

Why can't a Bag answer as a dictionary?

Tim Mackinnon
I was surprised to find that a Bag can’t convert to a dictionary - e.g.

Bag new
        addAll: 'aabbbbcddd’;
        asDictionary

Gives an error - Dnu #key


It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?

I know Bag is not used that much - but it comes up a lot in programming exercises.

Tim
Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Sven Van Caekenberghe-2
Why would that work ? What would you expect the output to be ?

Try:

  #(1 2 3) asDictionary

it fails in exactly the same way. You need key/value pairs (Associations).

These do work

  Bag new add: #foo->100; asDictionary.

  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.

> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>
> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>
> Bag new
> addAll: 'aabbbbcddd’;
> asDictionary
>
> Gives an error - Dnu #key
>
>
> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>
> I know Bag is not used that much - but it comes up a lot in programming exercises.
>
> Tim


Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Richard O'Keefe
Doubtless the original poster expected aBag asDictionary
to answer a dictionary mapping the (distinct) elements of
the bag to their counts.  Mathematically, a bag can
usefully be seen as a partial function from a set U to
the positive integers, and a dictionary with U keys and
positive integer values is precisely that.

It's really not unreasonable to expect that,
considering that there *is* a method that does just
what the OP wanted: #valuesAndCounts.  It's rather
dangerous to expose private state like that, but it
is not a private method.  I would expect

asDictionary
  ^contents copy




On Thu, 7 Mar 2019 at 02:54, Sven Van Caekenberghe <[hidden email]> wrote:
Why would that work ? What would you expect the output to be ?

Try:

  #(1 2 3) asDictionary

it fails in exactly the same way. You need key/value pairs (Associations).

These do work

  Bag new add: #foo->100; asDictionary.

  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.

> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>
> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>
> Bag new
>       addAll: 'aabbbbcddd’;
>       asDictionary
>
> Gives an error - Dnu #key
>
>
> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>
> I know Bag is not used that much - but it comes up a lot in programming exercises.
>
> Tim


Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Tim Mackinnon
In reply to this post by Sven Van Caekenberghe-2
As Richard said - as a bag is relationship between keys and frequencies, I would expect it to be able to convert to a dictionary.

It displays in an inspector just like a Dictionary - which is why I figured I could convert to pass it back to the exercise that was written with Dictionaries in mind.



The code to fix it is quite simple, but on these kinds of things - I thought it worth checking before submitting a PR.

Tim


On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:

Why would that work ? What would you expect the output to be ?

Try:

 #(1 2 3) asDictionary

it fails in exactly the same way. You need key/value pairs (Associations).

These do work

 Bag new add: #foo->100; asDictionary.

 Bag new addAll: 'ABABABAAAA'; valuesAndCounts.

On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:

I was surprised to find that a Bag can’t convert to a dictionary - e.g.

Bag new
addAll: 'aabbbbcddd’;
asDictionary

Gives an error - Dnu #key


It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?

I know Bag is not used that much - but it comes up a lot in programming exercises.

Tim



Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Sven Van Caekenberghe-2
I was just explaining how it is now, what I think the rationale is behind it.

I understand #asDictionary as working on a collection of pairs/associations (because it basically goes to #withAll:).

A bag is just a collection that is optimised for many duplicates, the fact that you have values and counts is more an implementation detail than an intrinsic property.

The conversion that you want, and that already exists in #valuesAndCounts is one interpretation of what a bag is, not the only one. A bag is foremost a collection of things.

I am not immediately convinced that #valuesAndCounts should be the default #asDictionary interpretation.

What about the inverse for example ?

  { #foo->2. #bar->3 } asDictionary asBag.

But this is certainly an interesting discussion.

> On 6 Mar 2019, at 16:23, Tim Mackinnon <[hidden email]> wrote:
>
> As Richard said - as a bag is relationship between keys and frequencies, I would expect it to be able to convert to a dictionary.
>
> It displays in an inspector just like a Dictionary - which is why I figured I could convert to pass it back to the exercise that was written with Dictionaries in mind.
>
> <PastedGraphic-3.png>
>
>
> The code to fix it is quite simple, but on these kinds of things - I thought it worth checking before submitting a PR.
>
> Tim
>
>
>> On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:
>>
>> Why would that work ? What would you expect the output to be ?
>>
>> Try:
>>
>>  #(1 2 3) asDictionary
>>
>> it fails in exactly the same way. You need key/value pairs (Associations).
>>
>> These do work
>>
>>  Bag new add: #foo->100; asDictionary.
>>
>>  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.
>>
>>> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>>>
>>> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>>>
>>> Bag new
>>> addAll: 'aabbbbcddd’;
>>> asDictionary
>>>
>>> Gives an error - Dnu #key
>>>
>>>
>>> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>>>
>>> I know Bag is not used that much - but it comes up a lot in programming exercises.
>>>
>>> Tim
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

philippeback
And when asking the object:

#(1 2 4 5 6 7 2 1 4 3) asBag  isDictionary

we get false. So, not, not a dictionary.

I still have been using #valuesAndCounts to get the dictionary out of a bag on several occasions.

And is useful indeed.

#(1 2 4 5 6 7 2 1 4 3) asBag occurrencesOf: 2

and 

#(1 2 4 5 6 7 2 1 4 3) asBag valuesAndCounts at: 2 

seem pretty much the same.

But in this age of streams/reactive streams and lazy evaluations, what do we have in Pharo on that front?

Phil





On Wed, Mar 6, 2019 at 4:49 PM Sven Van Caekenberghe <[hidden email]> wrote:
I was just explaining how it is now, what I think the rationale is behind it.

I understand #asDictionary as working on a collection of pairs/associations (because it basically goes to #withAll:).

A bag is just a collection that is optimised for many duplicates, the fact that you have values and counts is more an implementation detail than an intrinsic property.

The conversion that you want, and that already exists in #valuesAndCounts is one interpretation of what a bag is, not the only one. A bag is foremost a collection of things.

I am not immediately convinced that #valuesAndCounts should be the default #asDictionary interpretation.

What about the inverse for example ?

  { #foo->2. #bar->3 } asDictionary asBag.

But this is certainly an interesting discussion.

> On 6 Mar 2019, at 16:23, Tim Mackinnon <[hidden email]> wrote:
>
> As Richard said - as a bag is relationship between keys and frequencies, I would expect it to be able to convert to a dictionary.
>
> It displays in an inspector just like a Dictionary - which is why I figured I could convert to pass it back to the exercise that was written with Dictionaries in mind.
>
> <PastedGraphic-3.png>
>
>
> The code to fix it is quite simple, but on these kinds of things - I thought it worth checking before submitting a PR.
>
> Tim
>
>
>> On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:
>>
>> Why would that work ? What would you expect the output to be ?
>>
>> Try:
>>
>>  #(1 2 3) asDictionary
>>
>> it fails in exactly the same way. You need key/value pairs (Associations).
>>
>> These do work
>>
>>  Bag new add: #foo->100; asDictionary.
>>
>>  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.
>>
>>> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>>>
>>> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>>>
>>> Bag new
>>>     addAll: 'aabbbbcddd’;
>>>     asDictionary
>>>
>>> Gives an error - Dnu #key
>>>
>>>
>>> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>>>
>>> I know Bag is not used that much - but it comes up a lot in programming exercises.
>>>
>>> Tim
>>
>>
>



Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Tim Mackinnon
I still am tempted to make asDictionary work - because the the moment you get a #key , DNU error - which is definitely not right.

So should Bag asDictionary give you a reasonable dictionary, or should it throw a proper exception - something like:

DomainError signal: ‘#asDictionary not supported, use #valueAndCounts’

Is that better - or do we accept that it inherits it from Collection and so can do something useful?

Tim

On 6 Mar 2019, at 18:11, [hidden email] wrote:

And when asking the object:

#(1 2 4 5 6 7 2 1 4 3) asBag  isDictionary

we get false. So, not, not a dictionary.

I still have been using #valuesAndCounts to get the dictionary out of a bag on several occasions.

And is useful indeed.

#(1 2 4 5 6 7 2 1 4 3) asBag occurrencesOf: 2

and 

#(1 2 4 5 6 7 2 1 4 3) asBag valuesAndCounts at: 2 

seem pretty much the same.

But in this age of streams/reactive streams and lazy evaluations, what do we have in Pharo on that front?

Phil





On Wed, Mar 6, 2019 at 4:49 PM Sven Van Caekenberghe <[hidden email]> wrote:
I was just explaining how it is now, what I think the rationale is behind it.

I understand #asDictionary as working on a collection of pairs/associations (because it basically goes to #withAll:).

A bag is just a collection that is optimised for many duplicates, the fact that you have values and counts is more an implementation detail than an intrinsic property.

The conversion that you want, and that already exists in #valuesAndCounts is one interpretation of what a bag is, not the only one. A bag is foremost a collection of things.

I am not immediately convinced that #valuesAndCounts should be the default #asDictionary interpretation.

What about the inverse for example ?

  { #foo->2. #bar->3 } asDictionary asBag.

But this is certainly an interesting discussion.

> On 6 Mar 2019, at 16:23, Tim Mackinnon <[hidden email]> wrote:
>
> As Richard said - as a bag is relationship between keys and frequencies, I would expect it to be able to convert to a dictionary.
>
> It displays in an inspector just like a Dictionary - which is why I figured I could convert to pass it back to the exercise that was written with Dictionaries in mind.
>
> <PastedGraphic-3.png>
>
>
> The code to fix it is quite simple, but on these kinds of things - I thought it worth checking before submitting a PR.
>
> Tim
>
>
>> On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:
>>
>> Why would that work ? What would you expect the output to be ?
>>
>> Try:
>>
>>  #(1 2 3) asDictionary
>>
>> it fails in exactly the same way. You need key/value pairs (Associations).
>>
>> These do work
>>
>>  Bag new add: #foo->100; asDictionary.
>>
>>  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.
>>
>>> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>>>
>>> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>>>
>>> Bag new
>>>     addAll: 'aabbbbcddd’;
>>>     asDictionary
>>>
>>> Gives an error - Dnu #key
>>>
>>>
>>> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>>>
>>> I know Bag is not used that much - but it comes up a lot in programming exercises.
>>>
>>> Tim
>>
>>
>




Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Sven Van Caekenberghe-2
I am still not convinced.

> On 6 Mar 2019, at 19:24, Tim Mackinnon <[hidden email]> wrote:
>
> I still am tempted to make asDictionary work - because the the moment you get a #key , DNU error - which is definitely not right.

The error might not be super clear, but it is not wrong, the elements of your collection do not respond to #key, a necessity to create a dictionary from a collection of associations/pairs.

Also, if you modify #asDictionary like that, then

  <some bag> as: #Dictionary

will still fail.

This is all not so simple as it seems.

> So should Bag asDictionary give you a reasonable dictionary, or should it throw a proper exception - something like:
>
> DomainError signal: ‘#asDictionary not supported, use #valueAndCounts’
>
> Is that better - or do we accept that it inherits it from Collection and so can do something useful?
>
> Tim
>
>> On 6 Mar 2019, at 18:11, [hidden email] wrote:
>>
>> And when asking the object:
>>
>> #(1 2 4 5 6 7 2 1 4 3) asBag  isDictionary
>>
>> we get false. So, not, not a dictionary.
>>
>> I still have been using #valuesAndCounts to get the dictionary out of a bag on several occasions.
>>
>> And is useful indeed.
>>
>> #(1 2 4 5 6 7 2 1 4 3) asBag occurrencesOf: 2
>>
>> and
>>
>> #(1 2 4 5 6 7 2 1 4 3) asBag valuesAndCounts at: 2
>>
>> seem pretty much the same.
>>
>> But in this age of streams/reactive streams and lazy evaluations, what do we have in Pharo on that front?
>>
>> Phil
>>
>>
>>
>>
>>
>> On Wed, Mar 6, 2019 at 4:49 PM Sven Van Caekenberghe <[hidden email]> wrote:
>> I was just explaining how it is now, what I think the rationale is behind it.
>>
>> I understand #asDictionary as working on a collection of pairs/associations (because it basically goes to #withAll:).
>>
>> A bag is just a collection that is optimised for many duplicates, the fact that you have values and counts is more an implementation detail than an intrinsic property.
>>
>> The conversion that you want, and that already exists in #valuesAndCounts is one interpretation of what a bag is, not the only one. A bag is foremost a collection of things.
>>
>> I am not immediately convinced that #valuesAndCounts should be the default #asDictionary interpretation.
>>
>> What about the inverse for example ?
>>
>>   { #foo->2. #bar->3 } asDictionary asBag.
>>
>> But this is certainly an interesting discussion.
>>
>> > On 6 Mar 2019, at 16:23, Tim Mackinnon <[hidden email]> wrote:
>> >
>> > As Richard said - as a bag is relationship between keys and frequencies, I would expect it to be able to convert to a dictionary.
>> >
>> > It displays in an inspector just like a Dictionary - which is why I figured I could convert to pass it back to the exercise that was written with Dictionaries in mind.
>> >
>> > <PastedGraphic-3.png>
>> >
>> >
>> > The code to fix it is quite simple, but on these kinds of things - I thought it worth checking before submitting a PR.
>> >
>> > Tim
>> >
>> >
>> >> On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:
>> >>
>> >> Why would that work ? What would you expect the output to be ?
>> >>
>> >> Try:
>> >>
>> >>  #(1 2 3) asDictionary
>> >>
>> >> it fails in exactly the same way. You need key/value pairs (Associations).
>> >>
>> >> These do work
>> >>
>> >>  Bag new add: #foo->100; asDictionary.
>> >>
>> >>  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.
>> >>
>> >>> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>> >>>
>> >>> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>> >>>
>> >>> Bag new
>> >>>     addAll: 'aabbbbcddd’;
>> >>>     asDictionary
>> >>>
>> >>> Gives an error - Dnu #key
>> >>>
>> >>>
>> >>> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>> >>>
>> >>> I know Bag is not used that much - but it comes up a lot in programming exercises.
>> >>>
>> >>> Tim
>> >>
>> >>
>> >
>>
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Richard Sargent
Administrator
In reply to this post by Tim Mackinnon
On Wed, Mar 6, 2019 at 10:25 AM Tim Mackinnon <[hidden email]> wrote:
I still am tempted to make asDictionary work - because the the moment you get a #key , DNU error - which is definitely not right.

This argument gives me the willies. Sorry.

I can see an argument that a sequenceable collection can implement a meaningful #asDictionary, using #keysAndValuesDo:. The key is the index of each element, so it makes sense.

But, #asDictionary for a non-sequenceable collection doesn't make sense (other than for Dictionary and its variants, obviously). What would the keys be from a Set, for example?

Bag>>#asDictionary makes sense if (and in my opinion, only if) you define it to rely on the internal implementation. #valuesAndCounts make sense because it doesn't rely on internal implementation details to define it, although it typically is implemented to use those internal implementation details. I think expressing it as a conversion is a poor choice. Asking it for a different representation is good.

[And as an aside, given that the API expresses #occurrencesOf:, #valuesAndCounts might have been better named #valuesAndOccurrences (and perhaps "With" rather than "And").]


So should Bag asDictionary give you a reasonable dictionary, or should it throw a proper exception - something like:

DomainError signal: ‘#asDictionary not supported, use #valueAndCounts’

Is that better - or do we accept that it inherits it from Collection and so can do something useful?

Tim

On 6 Mar 2019, at 18:11, [hidden email] wrote:

And when asking the object:

#(1 2 4 5 6 7 2 1 4 3) asBag  isDictionary

we get false. So, not, not a dictionary.

I still have been using #valuesAndCounts to get the dictionary out of a bag on several occasions.

And is useful indeed.

#(1 2 4 5 6 7 2 1 4 3) asBag occurrencesOf: 2

and 

#(1 2 4 5 6 7 2 1 4 3) asBag valuesAndCounts at: 2 

seem pretty much the same.

But in this age of streams/reactive streams and lazy evaluations, what do we have in Pharo on that front?

Phil





On Wed, Mar 6, 2019 at 4:49 PM Sven Van Caekenberghe <[hidden email]> wrote:
I was just explaining how it is now, what I think the rationale is behind it.

I understand #asDictionary as working on a collection of pairs/associations (because it basically goes to #withAll:).

A bag is just a collection that is optimised for many duplicates, the fact that you have values and counts is more an implementation detail than an intrinsic property.

The conversion that you want, and that already exists in #valuesAndCounts is one interpretation of what a bag is, not the only one. A bag is foremost a collection of things.

I am not immediately convinced that #valuesAndCounts should be the default #asDictionary interpretation.

What about the inverse for example ?

  { #foo->2. #bar->3 } asDictionary asBag.

But this is certainly an interesting discussion.

> On 6 Mar 2019, at 16:23, Tim Mackinnon <[hidden email]> wrote:
>
> As Richard said - as a bag is relationship between keys and frequencies, I would expect it to be able to convert to a dictionary.
>
> It displays in an inspector just like a Dictionary - which is why I figured I could convert to pass it back to the exercise that was written with Dictionaries in mind.
>
> <PastedGraphic-3.png>
>
>
> The code to fix it is quite simple, but on these kinds of things - I thought it worth checking before submitting a PR.
>
> Tim
>
>
>> On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:
>>
>> Why would that work ? What would you expect the output to be ?
>>
>> Try:
>>
>>  #(1 2 3) asDictionary
>>
>> it fails in exactly the same way. You need key/value pairs (Associations).
>>
>> These do work
>>
>>  Bag new add: #foo->100; asDictionary.
>>
>>  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.
>>
>>> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>>>
>>> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>>>
>>> Bag new
>>>     addAll: 'aabbbbcddd’;
>>>     asDictionary
>>>
>>> Gives an error - Dnu #key
>>>
>>>
>>> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>>>
>>> I know Bag is not used that much - but it comes up a lot in programming exercises.
>>>
>>> Tim
>>
>>
>




Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Richard O'Keefe
In reply to this post by Sven Van Caekenberghe-2
To me, a bag is first and foremost a multiset.
Yes, it's a collection, but it's not *just* a collection.
It's a very specific kind of collection with a very
salient "characteristic function".

In my own Smalltalk library, #asDictionary isn't even *defined*
on things that are not dictionaries or some kind of mapping,
because let's face it, a dictionary *isn't* a collection of
Associations, and trying to make it look like one made
Smalltalk-80 rather inconsistent.  For example, if a dictionary
were a collection of associations, you would expect
(Dictionary with: #a -> 1 with: #b -> 2) includes: #a -> 1
to be true. No, it's false.  You would expect
(Dictionary with: #a -> 1 with: #b -> 2) asArray
to be (a->1 b->2).  No, it's (1 2).  In order to avoid major
confusion, I had to learn never to think of Associations in
connection with Dictionaries.  So I expect #asDictionary to
have something to do with #keysAndValuesDo:.
or something like that.

For {1->2. 3->4} asDictionary I would have to write
Dictionary withAllAssociations: {1->2. 3->4}
except that I never actually found a use for it.

#valuesAndCounts is a method that violates good OO practice,
because it exposes (what you'd expect to be) private state.
For example,
  b := 'abracadabra' asBag.
  b valuesAndCounts at: $a put: 'BOOM!'.
  b
select, Print It, BOOM!.  It should *copy* the dictionary.



On Thu, 7 Mar 2019 at 04:50, Sven Van Caekenberghe <[hidden email]> wrote:
I was just explaining how it is now, what I think the rationale is behind it.

I understand #asDictionary as working on a collection of pairs/associations (because it basically goes to #withAll:).

A bag is just a collection that is optimised for many duplicates, the fact that you have values and counts is more an implementation detail than an intrinsic property.

The conversion that you want, and that already exists in #valuesAndCounts is one interpretation of what a bag is, not the only one. A bag is foremost a collection of things.

I am not immediately convinced that #valuesAndCounts should be the default #asDictionary interpretation.

What about the inverse for example ?

  { #foo->2. #bar->3 } asDictionary asBag.

But this is certainly an interesting discussion.

> On 6 Mar 2019, at 16:23, Tim Mackinnon <[hidden email]> wrote:
>
> As Richard said - as a bag is relationship between keys and frequencies, I would expect it to be able to convert to a dictionary.
>
> It displays in an inspector just like a Dictionary - which is why I figured I could convert to pass it back to the exercise that was written with Dictionaries in mind.
>
> <PastedGraphic-3.png>
>
>
> The code to fix it is quite simple, but on these kinds of things - I thought it worth checking before submitting a PR.
>
> Tim
>
>
>> On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:
>>
>> Why would that work ? What would you expect the output to be ?
>>
>> Try:
>>
>>  #(1 2 3) asDictionary
>>
>> it fails in exactly the same way. You need key/value pairs (Associations).
>>
>> These do work
>>
>>  Bag new add: #foo->100; asDictionary.
>>
>>  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.
>>
>>> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>>>
>>> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>>>
>>> Bag new
>>>     addAll: 'aabbbbcddd’;
>>>     asDictionary
>>>
>>> Gives an error - Dnu #key
>>>
>>>
>>> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>>>
>>> I know Bag is not used that much - but it comes up a lot in programming exercises.
>>>
>>> Tim
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Richard O'Keefe
In reply to this post by Sven Van Caekenberghe-2
Handling   <some bag> as: Dictionary 
is really quite straightforward.
Add a one-line method to Bag:

Bag>>
associationsDo: aBlock
    contents associationsDo: aBlock.

This is a good idea anyway, because currently there is a bug where
aBag associationsDo: aBlock
fails to pass Associations to aBlock.  Once you have done that,
'abracadabra' asBag as: Dictionary
just works.  This one simple addition
 - makes aBag associationsDo: aBlock work when it didn't before
 - makes aBag asDictionary work
 - makes aBag as: Dictionary work
 - makes Dictionary newFrom: aBag work




On Thu, 7 Mar 2019 at 07:35, Sven Van Caekenberghe <[hidden email]> wrote:
I am still not convinced.

> On 6 Mar 2019, at 19:24, Tim Mackinnon <[hidden email]> wrote:
>
> I still am tempted to make asDictionary work - because the the moment you get a #key , DNU error - which is definitely not right.

The error might not be super clear, but it is not wrong, the elements of your collection do not respond to #key, a necessity to create a dictionary from a collection of associations/pairs.

Also, if you modify #asDictionary like that, then

  <some bag> as: #Dictionary

will still fail.

This is all not so simple as it seems.

> So should Bag asDictionary give you a reasonable dictionary, or should it throw a proper exception - something like:
>
> DomainError signal: ‘#asDictionary not supported, use #valueAndCounts’
>
> Is that better - or do we accept that it inherits it from Collection and so can do something useful?
>
> Tim
>
>> On 6 Mar 2019, at 18:11, [hidden email] wrote:
>>
>> And when asking the object:
>>
>> #(1 2 4 5 6 7 2 1 4 3) asBag  isDictionary
>>
>> we get false. So, not, not a dictionary.
>>
>> I still have been using #valuesAndCounts to get the dictionary out of a bag on several occasions.
>>
>> And is useful indeed.
>>
>> #(1 2 4 5 6 7 2 1 4 3) asBag occurrencesOf: 2
>>
>> and
>>
>> #(1 2 4 5 6 7 2 1 4 3) asBag valuesAndCounts at: 2
>>
>> seem pretty much the same.
>>
>> But in this age of streams/reactive streams and lazy evaluations, what do we have in Pharo on that front?
>>
>> Phil
>>
>>
>>
>>
>>
>> On Wed, Mar 6, 2019 at 4:49 PM Sven Van Caekenberghe <[hidden email]> wrote:
>> I was just explaining how it is now, what I think the rationale is behind it.
>>
>> I understand #asDictionary as working on a collection of pairs/associations (because it basically goes to #withAll:).
>>
>> A bag is just a collection that is optimised for many duplicates, the fact that you have values and counts is more an implementation detail than an intrinsic property.
>>
>> The conversion that you want, and that already exists in #valuesAndCounts is one interpretation of what a bag is, not the only one. A bag is foremost a collection of things.
>>
>> I am not immediately convinced that #valuesAndCounts should be the default #asDictionary interpretation.
>>
>> What about the inverse for example ?
>>
>>   { #foo->2. #bar->3 } asDictionary asBag.
>>
>> But this is certainly an interesting discussion.
>>
>> > On 6 Mar 2019, at 16:23, Tim Mackinnon <[hidden email]> wrote:
>> >
>> > As Richard said - as a bag is relationship between keys and frequencies, I would expect it to be able to convert to a dictionary.
>> >
>> > It displays in an inspector just like a Dictionary - which is why I figured I could convert to pass it back to the exercise that was written with Dictionaries in mind.
>> >
>> > <PastedGraphic-3.png>
>> >
>> >
>> > The code to fix it is quite simple, but on these kinds of things - I thought it worth checking before submitting a PR.
>> >
>> > Tim
>> >
>> >
>> >> On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:
>> >>
>> >> Why would that work ? What would you expect the output to be ?
>> >>
>> >> Try:
>> >>
>> >>  #(1 2 3) asDictionary
>> >>
>> >> it fails in exactly the same way. You need key/value pairs (Associations).
>> >>
>> >> These do work
>> >>
>> >>  Bag new add: #foo->100; asDictionary.
>> >>
>> >>  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.
>> >>
>> >>> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>> >>>
>> >>> I was surprised to find that a Bag can’t convert to a dictionary - e.g.
>> >>>
>> >>> Bag new
>> >>>     addAll: 'aabbbbcddd’;
>> >>>     asDictionary
>> >>>
>> >>> Gives an error - Dnu #key
>> >>>
>> >>>
>> >>> It looks to me like Bag is inheriting a bad version of #associationsDo:  and instead could simply forward it to #doWithOccurences: instead?
>> >>>
>> >>> I know Bag is not used that much - but it comes up a lot in programming exercises.
>> >>>
>> >>> Tim
>> >>
>> >>
>> >
>>
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

Steffen Märcker
In reply to this post by Richard O'Keefe
This is exactly how I think and feel about bags. Thanks Richard.

Am .03.2019, 01:35 Uhr, schrieb Richard O'Keefe <[hidden email]>:

> To me, a bag is first and foremost a multiset.
> Yes, it's a collection, but it's not *just* a collection.
> It's a very specific kind of collection with a very
> salient "characteristic function".
>
> In my own Smalltalk library, #asDictionary isn't even *defined*
> on things that are not dictionaries or some kind of mapping,
> because let's face it, a dictionary *isn't* a collection of
> Associations, and trying to make it look like one made
> Smalltalk-80 rather inconsistent.  For example, if a dictionary
> were a collection of associations, you would expect
> (Dictionary with: #a -> 1 with: #b -> 2) includes: #a -> 1
> to be true. No, it's false.  You would expect
> (Dictionary with: #a -> 1 with: #b -> 2) asArray
> to be (a->1 b->2).  No, it's (1 2).  In order to avoid major
> confusion, I had to learn never to think of Associations in
> connection with Dictionaries.  So I expect #asDictionary to
> have something to do with #keysAndValuesDo:.
> or something like that.
>
> For {1->2. 3->4} asDictionary I would have to write
> Dictionary withAllAssociations: {1->2. 3->4}
> except that I never actually found a use for it.
>
> #valuesAndCounts is a method that violates good OO practice,
> because it exposes (what you'd expect to be) private state.
> For example,
>   b := 'abracadabra' asBag.
>   b valuesAndCounts at: $a put: 'BOOM!'.
>   b
> select, Print It, BOOM!.  It should *copy* the dictionary.
>
>
>
> On Thu, 7 Mar 2019 at 04:50, Sven Van Caekenberghe <[hidden email]> wrote:
>
>> I was just explaining how it is now, what I think the rationale is
>> behind
>> it.
>>
>> I understand #asDictionary as working on a collection of
>> pairs/associations (because it basically goes to #withAll:).
>>
>> A bag is just a collection that is optimised for many duplicates, the
>> fact
>> that you have values and counts is more an implementation detail than an
>> intrinsic property.
>>
>> The conversion that you want, and that already exists in
>> #valuesAndCounts
>> is one interpretation of what a bag is, not the only one. A bag is
>> foremost
>> a collection of things.
>>
>> I am not immediately convinced that #valuesAndCounts should be the
>> default
>> #asDictionary interpretation.
>>
>> What about the inverse for example ?
>>
>>   { #foo->2. #bar->3 } asDictionary asBag.
>>
>> But this is certainly an interesting discussion.
>>
>> > On 6 Mar 2019, at 16:23, Tim Mackinnon <[hidden email]> wrote:
>> >
>> > As Richard said - as a bag is relationship between keys and
>> frequencies,
>> I would expect it to be able to convert to a dictionary.
>> >
>> > It displays in an inspector just like a Dictionary - which is why I
>> figured I could convert to pass it back to the exercise that was written
>> with Dictionaries in mind.
>> >
>> > <PastedGraphic-3.png>
>> >
>> >
>> > The code to fix it is quite simple, but on these kinds of things - I
>> thought it worth checking before submitting a PR.
>> >
>> > Tim
>> >
>> >
>> >> On 6 Mar 2019, at 13:53, Sven Van Caekenberghe <[hidden email]> wrote:
>> >>
>> >> Why would that work ? What would you expect the output to be ?
>> >>
>> >> Try:
>> >>
>> >>  #(1 2 3) asDictionary
>> >>
>> >> it fails in exactly the same way. You need key/value pairs
>> (Associations).
>> >>
>> >> These do work
>> >>
>> >>  Bag new add: #foo->100; asDictionary.
>> >>
>> >>  Bag new addAll: 'ABABABAAAA'; valuesAndCounts.
>> >>
>> >>> On 6 Mar 2019, at 14:25, Tim Mackinnon <[hidden email]> wrote:
>> >>>
>> >>> I was surprised to find that a Bag can’t convert to a dictionary -
>> e.g.
>> >>>
>> >>> Bag new
>> >>>     addAll: 'aabbbbcddd’;
>> >>>     asDictionary
>> >>>
>> >>> Gives an error - Dnu #key
>> >>>
>> >>>
>> >>> It looks to me like Bag is inheriting a bad version of
>> #associationsDo:  and instead could simply forward it to
>> #doWithOccurences:
>> instead?
>> >>>
>> >>> I know Bag is not used that much - but it comes up a lot in
>> programming exercises.
>> >>>
>> >>> Tim
>> >>
>> >>
>> >
>>
>>
>>



Reply | Threaded
Open this post in threaded view
|

Re: Why can't a Bag answer as a dictionary?

cedreek
In reply to this post by Sven Van Caekenberghe-2

>
>  #(1 2 3) asDictionary
>


For this one,  I would expect a dictionary with integer keys
I see a dictionary as an indexed collection with key that are not only integer (like for an array).


1->1 2->2 3->3



I doubt this would be useful though.

My 2 cents,

Cédrick