memoized vs once

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

memoized vs once

Eliot Miranda-2
Hi Ben,

    via FaceBook via twitter I hear you've coined BlockClosure>>#memoized.  Allow me to beg you to rename it to BlockClosure>>#once.  There's a preexisting implementation of this in VisualWorks by Travis Griggs called once.  I hope you agree that it's good to eliminate gratuitous incompatibilities between dialects and that "once" is an elegant name.
_,,,^..^,,,_
best, Eliot
Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Nicolas Cellier
Hi Eliot,
you should have named the thread "once for all!"
+1 in any case

2017-01-25 19:56 GMT+01:00 Eliot Miranda <[hidden email]>:
Hi Ben,

    via FaceBook via twitter I hear you've coined BlockClosure>>#memoized.  Allow me to beg you to rename it to BlockClosure>>#once.  There's a preexisting implementation of this in VisualWorks by Travis Griggs called once.  I hope you agree that it's good to eliminate gratuitous incompatibilities between dialects and that "once" is an elegant name.
_,,,^..^,,,_
best, Eliot

Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Denis Kudriashov
In reply to this post by Eliot Miranda-2
Hi Eliot.

2017-01-25 19:56 GMT+01:00 Eliot Miranda <[hidden email]>:
Hi Ben,

    via FaceBook via twitter I hear you've coined BlockClosure>>#memoized.  Allow me to beg you to rename it to BlockClosure>>#once.  There's a preexisting implementation of this in VisualWorks by Travis Griggs called once.  I hope you agree that it's good to eliminate gratuitous incompatibilities between dialects and that "once" is an elegant name.

#once is not the same as #memoized. #memoized returns another block which wrap original one to perform some caching. Actually I not understand logic behind it. 
But #once supposed to evaluate receiver while #memoized creates new block.

In Pharo 6 I pushed new method #asMethodConst. Unfortunately I was not aware about #once from VisualWorks at this time and reviewers too.
But #asMethodConst is a bit different. It is Object method instead of Block. And it is based on AST modification. 
When asMethodConst is executed it replace executing AST-node of sender with receiver which produce new method where full message node is replaced by result as literal.
I put mode details here http://dionisiydk.blogspot.fr/2016/07/magic-with-pharo-reflectivity.html. In short you can write expressions like:
10 factorial asMethodConst


Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Igor Stasenko
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Torsten Bergmann
Hi,

From my perspective:

- I agree with Igor that "once" can be interpreted as "evaluate it only once" as in 
  "Halt once".

- I'm not sure but from the (now very distributed) discussion it is not clear to me if
  the #once mentioned by Eliot really has exactly the same behavior as #memoized in Pharo.

  Does it also  return a block that is caching the results and avoids a second evalution
  of the original block when having similar inputs? Also is there a similar possibility
  to give an own cache as in #memoizedUsing: for further tuning?

- #memoizing is really not well explaining what it does but this seems to be the official
  term (also in other languages like Python, Java, JS, ...): https://en.wikipedia.org/wiki/Memoization

- maybe #withMemo(r)izingResults or #withCachingResults, #withReusedResults, ... or something along that line
  would be more intention revealing selectors


Side note:
=========
- For license reason it would not make much sense to look into non-open Smalltalks
- I have no idea about the VW version (and for obvious reasons dont want to have a look)
- also dont know about other dialects if they have built in support for memoization but it would be
  good if Squeak, Pharo, Cuis, ... could align for such a case
- IMHO if #once and Pharos #memoization really have the same behavior then compatibility for VW users
  could be easily retained by adding #once to existing compatibility layers (like "Grease")

Bye
T.

Gesendet: Mittwoch, 25. Januar 2017 um 22:30 Uhr
Von: "Igor Stasenko" <[hidden email]>
An: "Pharo Development List" <[hidden email]>
Betreff: Re: [Pharo-dev] memoized vs once

#once can be interpreted as 'evaluate it once',
 
but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 
 :)
 
 --
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

philippeback
In reply to this post by Nicolas Cellier
All that is nice but I only found about it because I searched for "memoize"... Which is what it does.

Phil

On Wed, Jan 25, 2017 at 9:29 PM, Nicolas Cellier <[hidden email]> wrote:
Hi Eliot,
you should have named the thread "once for all!"
+1 in any case

2017-01-25 19:56 GMT+01:00 Eliot Miranda <[hidden email]>:
Hi Ben,

    via FaceBook via twitter I hear you've coined BlockClosure>>#memoized.  Allow me to beg you to rename it to BlockClosure>>#once.  There's a preexisting implementation of this in VisualWorks by Travis Griggs called once.  I hope you agree that it's good to eliminate gratuitous incompatibilities between dialects and that "once" is an elegant name.
_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

philippeback
In reply to this post by Igor Stasenko
If one is doing any dynamic programming, the memoization term is pretty natural.


Phil

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Aliaksei Syrel
Underscore.js names it also #memoize.

Cheers

On Jan 26, 2017 00:15, "[hidden email]" <[hidden email]> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.


Phil

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.


Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Igor Stasenko
In reply to this post by philippeback


On 26 January 2017 at 01:14, [hidden email] <[hidden email]> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.

for that purpose, i naturally using 'caching' wording. 
 

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.




--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Igor Stasenko
result := [ do something long or short or whatever] cached.

On 26 January 2017 at 01:20, Igor Stasenko <[hidden email]> wrote:


On 26 January 2017 at 01:14, [hidden email] <[hidden email]> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.

for that purpose, i naturally using 'caching' wording. 
 

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.




--
Best regards,
Igor Stasenko.



--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

philippeback
In reply to this post by Igor Stasenko
Nothing new, that's the term. 

Memoization: After computing a solution to a subproblem, store it in a table. Subsequent calls check the table to avoid redoing work.




I have been using the method for something else, caching costly REST calls.

getIssueCreateMeta
"Retrieves the metadata for all types of issues. Fields are expanded"
^ self isMemoizingMeta 
ifTrue: [ ([ :ignored | self getIssueCreateMetaWithExpandKeys: true ] memoizedUsing: self cache ) value: #issueCreateMeta ]
ifFalse: [ self getIssueCreateMetaWithExpandKeys: true ]


using:

cache
^ cache ifNil: [cache := LRUCache new maximumWeight: self defaultCacheWeight ]

It is nice to see the cache hit rate etc in the inspector.

BTW I am interested to see how one coul dwrite the code above without repeating the block.
Also, :ignored is not used by the method but is the cache key.

Phil

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

philippeback
In reply to this post by Igor Stasenko
But for caching you have a cache.

The whole point of memoization support is to have it easy to do.
Look at the bottom of this page:

So if we could have some kind of the same using manipulation of thisContext and/or Slots, it would be nicer.

e.g.

SomeClass>>#initialize
   self memoize: #someMethod:andParms:.

and bingo, automatic method memoization keyed by the objects passed.

That would be better.

Phil




On Thu, Jan 26, 2017 at 12:20 AM, Igor Stasenko <[hidden email]> wrote:


On 26 January 2017 at 01:14, [hidden email] <[hidden email]> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.

for that purpose, i naturally using 'caching' wording. 
 

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.




--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

philippeback
In reply to this post by Igor Stasenko
self memoize: #methodThatDoesSomethingLong:.

would automatically store parameters values as cache keys. No matter how many such parms.

No need to have blocks or anything,operations are memoized.
We use blocks for lack of a better way right now I guess.

Phil

On Thu, Jan 26, 2017 at 12:22 AM, Igor Stasenko <[hidden email]> wrote:
result := [ do something long or short or whatever] cached.

On 26 January 2017 at 01:20, Igor Stasenko <[hidden email]> wrote:


On 26 January 2017 at 01:14, [hidden email] <[hidden email]> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.

for that purpose, i naturally using 'caching' wording. 
 

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.




--
Best regards,
Igor Stasenko.



--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Igor Stasenko
In reply to this post by philippeback


On 26 January 2017 at 01:23, [hidden email] <[hidden email]> wrote:
Nothing new, that's the term. 

Memoization: After computing a solution to a subproblem, store it in a table. Subsequent calls check the table to avoid redoing work.




I have been using the method for something else, caching costly REST calls.

getIssueCreateMeta
"Retrieves the metadata for all types of issues. Fields are expanded"
^ self isMemoizingMeta 
ifTrue: [ ([ :ignored | self getIssueCreateMetaWithExpandKeys: true ] memoizedUsing: self cache ) value: #issueCreateMeta ]
ifFalse: [ self getIssueCreateMetaWithExpandKeys: true ]


using:

cache
^ cache ifNil: [cache := LRUCache new maximumWeight: self defaultCacheWeight ]

It is nice to see the cache hit rate etc in the inspector.

BTW I am interested to see how one coul dwrite the code above without repeating the block.
Also, :ignored is not used by the method but is the cache key.


well, for not repeating, its easy, for instance in NativeBoost i just used expressions like:

getIssueCreateMeta
^ self cacheAt: somekey ifAbsentPut: [ some data ]

which are self-explanatory (i hope)
where somekey could be 'self' or whatever seem fit.

as for the caching wihoout key, why not just store result of first evaluation and then use it directly anywhere else? why need to wrap it 
with block??

data := [some calculation ] value.

self doSomethingWith: data.
self doSomethingElseWith: data.
self doSomethingElseElseWith: data.


voila.. plain programming. Where does memoization need to be coined here? :)

Phil

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.




--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Igor Stasenko
In reply to this post by philippeback


On 26 January 2017 at 01:33, [hidden email] <[hidden email]> wrote:
self memoize: #methodThatDoesSomethingLong:.

would automatically store parameters values as cache keys. No matter how many such parms.

No need to have blocks or anything,operations are memoized.
We use blocks for lack of a better way right now I guess.

Phil

well, that's something i calling 'caching'.. because if you cashing many results, depending on input data,
then it is better to call caching..

but in original example, there's noting like this.. it is just block without arguments.. so, what you going 
to use as keys for caching evaluation of such block, how do you identify what value(s) are inputs for such block
and what not?

--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

philippeback
In reply to this post by Igor Stasenko
Yeah, I get you 100%.

I wanted to be able to cache or not and have this transparent.

Memoization in its current form in Pharo is not like I would like to have it.

As for the repeating block, I was asking to how you would avoid repeating in the given code structure.

Phil


On Thu, Jan 26, 2017 at 12:34 AM, Igor Stasenko <[hidden email]> wrote:


On 26 January 2017 at 01:23, [hidden email] <[hidden email]> wrote:
Nothing new, that's the term. 

Memoization: After computing a solution to a subproblem, store it in a table. Subsequent calls check the table to avoid redoing work.




I have been using the method for something else, caching costly REST calls.

getIssueCreateMeta
"Retrieves the metadata for all types of issues. Fields are expanded"
^ self isMemoizingMeta 
ifTrue: [ ([ :ignored | self getIssueCreateMetaWithExpandKeys: true ] memoizedUsing: self cache ) value: #issueCreateMeta ]
ifFalse: [ self getIssueCreateMetaWithExpandKeys: true ]


using:

cache
^ cache ifNil: [cache := LRUCache new maximumWeight: self defaultCacheWeight ]

It is nice to see the cache hit rate etc in the inspector.

BTW I am interested to see how one coul dwrite the code above without repeating the block.
Also, :ignored is not used by the method but is the cache key.


well, for not repeating, its easy, for instance in NativeBoost i just used expressions like:

getIssueCreateMeta
^ self cacheAt: somekey ifAbsentPut: [ some data ]

which are self-explanatory (i hope)
where somekey could be 'self' or whatever seem fit.

as for the caching wihoout key, why not just store result of first evaluation and then use it directly anywhere else? why need to wrap it 
with block??

data := [some calculation ] value.

self doSomethingWith: data.
self doSomethingElseWith: data.
self doSomethingElseElseWith: data.


voila.. plain programming. Where does memoization need to be coined here? :)

Phil

On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <[hidden email]> wrote:
#once can be interpreted as 'evaluate it once',

but i don't like the #memoized .. it sounds painful to my ears.
It sounds like something stinking smeared across my face.. and i always got stuck,confused and lost as the meaning of it always 
escaping my mind, since it naturally defends itself from any unpleasant thoughts.

IMHO, maybe #once is not the best wording for what it does , but #memoizing... yuck.. pardon me.

 :)


--
Best regards,
Igor Stasenko.




--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Igor Stasenko


On 26 January 2017 at 01:40, [hidden email] <[hidden email]> wrote:
Yeah, I get you 100%.

I wanted to be able to cache or not and have this transparent.

Memoization in its current form in Pharo is not like I would like to have it.

As for the repeating block, I was asking to how you would avoid repeating in the given code structure.

You asking me rewrite it for your example?
unless i missing something (not)obvious here, it can look like this: 

getIssueCreateMeta
"Retrieves the metadata for all types of issues. Fields are expanded"
^ self cache at:  #issueCreateMeta ifAbsentPut: [ self getIssueCreateMetaWithExpandKeys: true ]

 
Btw, it is a good question, what are the difference between caching and memoization, besides that google underlines 'memoization' word with thin red curly line while i typing? :) 


--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Igor Stasenko
Because caching are always comes with concerns, like when/where do we want to drop cached results and recalculate them, if needed..
With memoization it seems like there's simply no such concern at all.. meaning that cached data will live forever since created once.. which is never good
for dynamic system.. because i spent significant portion of my smalltalk life hunting for leaks and immortal references that you cannot get rid of,
because some guy forgot to provide a nice and easy interface or api to get rid of volatile data.. like open files or socket connections, session etc etc..
and now.. let us welcome.. memoization. :)

--
Best regards,
Igor Stasenko.
Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

philippeback
Ah ah :-D

In my example I want to be able to do the calls without caching or with caching. Without for debugging because I amend the server side at times and want always fresh data (yes, I could have a cache with TTL of about nothing).

Memoization is useful for not having to write the caching thing all the time.

DynamicVariables are darker magic that this, right?

Phil


On Thu, Jan 26, 2017 at 12:56 AM, Igor Stasenko <[hidden email]> wrote:
Because caching are always comes with concerns, like when/where do we want to drop cached results and recalculate them, if needed..
With memoization it seems like there's simply no such concern at all.. meaning that cached data will live forever since created once.. which is never good
for dynamic system.. because i spent significant portion of my smalltalk life hunting for leaks and immortal references that you cannot get rid of,
because some guy forgot to provide a nice and easy interface or api to get rid of volatile data.. like open files or socket connections, session etc etc..
and now.. let us welcome.. memoization. :)

--
Best regards,
Igor Stasenko.

Reply | Threaded
Open this post in threaded view
|

Re: memoized vs once

Igor Stasenko


On 26 January 2017 at 02:10, [hidden email] <[hidden email]> wrote:
Ah ah :-D

In my example I want to be able to do the calls without caching or with caching. Without for debugging because I amend the server side at times and want always fresh data (yes, I could have a cache with TTL of about nothing).


and why that could be the problem in my example? you can always implement #at:ifAbsentPut: in the way you see fit.. 

cache disable.
x := cache at: #something ifAbsentPut: [ blah ]. "always calculates, ignores the cache"
cache enable.
y := cache at: #something ifAbsentPut: [ blah ]. "prefers to calculate once, reuse result"

you see what i mean?
in any case you can easily avoid repeating  same block twice.. that's for sure.
 
Memoization is useful for not having to write the caching thing all the time.

DynamicVariables are darker magic that this, right?

Phil


On Thu, Jan 26, 2017 at 12:56 AM, Igor Stasenko <[hidden email]> wrote:
Because caching are always comes with concerns, like when/where do we want to drop cached results and recalculate them, if needed..
With memoization it seems like there's simply no such concern at all.. meaning that cached data will live forever since created once.. which is never good
for dynamic system.. because i spent significant portion of my smalltalk life hunting for leaks and immortal references that you cannot get rid of,
because some guy forgot to provide a nice and easy interface or api to get rid of volatile data.. like open files or socket connections, session etc etc..
and now.. let us welcome.. memoization. :)

--
Best regards,
Igor Stasenko.




--
Best regards,
Igor Stasenko.
123