Dictionary >> #at:ifAbsentPut:ifPresentPut:

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

Dictionary >> #at:ifAbsentPut:ifPresentPut:

Christoph Thiede

Hi all,


recently I stumbled upon an extension method for Dictionary which *might* fit well into the Trunk:


Dictionary >> #at: key ifAbsentPut: startBlock ifPresentPut: nextBlock
"(c) 2020 Basti Kruck und Marcel Taeumel. :-)" (self includesKey: key) ifFalse: [
^ self at: key put: startBlock value]. ^ self
at: key
put: (nextBlock value: (self at: key))

See https://github.com/hpi-swa/vivide/blob/c4ac5ea562bd563358d52ee41c149a3fbcffd90e/repository/Vivide.package/Dictionary.extension/instance/at.ifAbsentPut.ifPresentPut..st.


Usage:

counter := counters at: key ifAbsentPut: [0] ifPresentPut: [:i | i + 1]

What do you think, should we copy this into the Trunk? Or is it just fine to do something like this instead at the sender side:

counter := counters at: key put: (counters at: key ifAbsent: [0] ifPresent: [:i | i + 1])

Also, I'm not sure about the order of arguments.

Best,
Christoph


Carpe Squeak!
Reply | Threaded
Open this post in threaded view
|

Re: Dictionary >> #at:ifAbsentPut:ifPresentPut:

Tobias Pape
Hi



> On 30. Apr 2021, at 18:36, Thiede, Christoph <[hidden email]> wrote:
>
> Hi all,
>
> recently I stumbled upon an extension method for Dictionary which *might* fit well into the Trunk:
>
> Dictionary >> #at: key ifAbsentPut: startBlock ifPresentPut: nextBlock
> "(c) 2020 Basti Kruck und Marcel Taeumel. :-)"
> (self includesKey: key) ifFalse: [
> ^ self at: key put: startBlock value].
> ^ self
> at: key
> put: (nextBlock value: (self at: key))
>
> See https://github.com/hpi-swa/vivide/blob/c4ac5ea562bd563358d52ee41c149a3fbcffd90e/repository/Vivide.package/Dictionary.extension/instance/at.ifAbsentPut.ifPresentPut..st.
>
> Usage:
> counter := counters at: key ifAbsentPut: [0] ifPresentPut: [:i | i + 1]
>
> What do you think, should we copy this into the Trunk? Or is it just fine to do something like this instead at the sender side:
> counter := counters at: key put: (counters at: key ifAbsent: [0] ifPresent: [:i | i + 1])
>
> Also, I'm not sure about the order of arguments.

I find it a bit too specific for trunk.
It's quite an edge case...

-t


Reply | Threaded
Open this post in threaded view
|

Re: Dictionary >> #at:ifAbsentPut:ifPresentPut:

Levente Uzonyi
In reply to this post by Christoph Thiede
On Fri, 30 Apr 2021, Thiede, Christoph wrote:

>
> Hi all,
>
>
> recently I stumbled upon an extension method for Dictionary which *might* fit well into the Trunk:
>
>
> Dictionary >> #at: key ifAbsentPut: startBlock ifPresentPut: nextBlock
> "(c) 2020 Basti Kruck und Marcel Taeumel. :-)" (self includesKey: key) ifFalse: [
> ^ self at: key put: startBlock value]. ^ self
> at: key
> put: (nextBlock value: (self at: key))
>
> SeeĀ https://github.com/hpi-swa/vivide/blob/c4ac5ea562bd563358d52ee41c149a3fbcffd90e/repository/Vivide.package/Dictionary.extension/instance/at.ifAbsentPut.ifPresentPut..st.
>
>
> Usage:
>
> counter := counters at: key ifAbsentPut: [0] ifPresentPut: [:i | i + 1]
>
> What do you think, should we copy this into the Trunk? Or is it just fine to do something like this instead at the sender side:
>
> counter := counters at: key put: (counters at: key ifAbsent: [0] ifPresent: [:i | i + 1])
The alternative I would use is the following:

counter := counters at: key put: (counters at: key ifAbsent: [0]) + 1

And I think that is good enough. If wanted to have a special method for
that case, I would try to look up the key only once.


Levente

Reply | Threaded
Open this post in threaded view
|

Re: Dictionary >> #at:ifAbsentPut:ifPresentPut:

stlutz
Christoph Thiede wrote
What do you think, should we copy this into the Trunk?
Personally, I'd get good use out of at:ifPresentPut: and at:ifPresentPut:ifAbsentPut:.
I seriously considered adding them as extensions in a couple of projects.
Christoph Thiede wrote
Also, I'm not sure about the order of arguments.
The pattern other selectors in Squeak follow is present first, absent second.
We should probably keep to that pattern.
Tobias Pape wrote
I find it a bit too specific for trunk.
It's quite an edge case...
FWIW I encountered this case quite a few times over the years.
It's essentially always a concern when storing and updating value objects in dictionaries.
Levente Uzonyi wrote
If wanted to have a special method for that case, I would try to look up the key only once.
+1

Stephan

Sent from the Squeak - Dev mailing list archive at Nabble.com.


Reply | Threaded
Open this post in threaded view
|

Re: Dictionary >> #at:ifAbsentPut:ifPresentPut:

Tobias Pape


> On 1. May 2021, at 01:26, stlutz <[hidden email]> wrote:
>
> Christoph Thiede wrote
> What do you think, should we copy this into the Trunk?
> Personally, I'd get good use out of at:ifPresentPut: and at:ifPresentPut:ifAbsentPut:.
> I seriously considered adding them as extensions in a couple of projects.
> Christoph Thiede wrote
> Also, I'm not sure about the order of arguments.
> The pattern other selectors in Squeak follow is present first, absent second.
> We should probably keep to that pattern.
> Tobias Pape wrote
> I find it a bit too specific for trunk.
> It's quite an edge case...
> FWIW I encountered this case quite a few times over the years.
> It's essentially always a concern when storing and updating value objects in dictionaries.

Temporary variables are not your enemy.

Or even:

 (foo hasKey: 'abc')
   ifTrue: [foo at: 'abc' put: 'def']

Updating existing values really does not need shortcuts.

Initial defaults are another thing, but I think ifPresentPut: is a malpatternā€¦

Best regards
        -Tobias

> Levente Uzonyi wrote
> If wanted to have a special method for that case, I would try to look up the key only once.
> +1
>
> Stephan
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>