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
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 <eliot.miranda@gmail.com>:
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
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 < nicolas.cellier.aka.nice@gmail.com> 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 <eliot.miranda@gmail.com>:
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
Hi Eliot. 2017-01-25 19:56 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
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
#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.
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" <siguctua@gmail.com> An: "Pharo Development List" <pharo-dev@lists.pharo.org> 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.
Hi Torsten, On Wed, Jan 25, 2017 at 2:45 PM, Torsten Bergmann <astares@gmx.de> wrote:
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.
Let's separate the implementation from the semantics. Memorizing a function implies cacheing its results for some set of arguments and answering the results, avoiding evaluating the function again. This is the effectively same semantics as [expr] once, which says that expire will be evaluated exactly once. So they're both forms of memorization. I recognized this but was too stupid/tired to realize they weren't the same, since once applies to nullify blocks and memorize applies to Nary blocks. That started this whole discussion, apologies. Now, descending to the implementations, I understand that Ben's memorize answers a block that wraps a dictionary which caches the arguments -> results mappings. #once is implemented to use become to convert the block (which in VW must be a clean block) into a cacheingBlockClosure which has an extra inst var to hold its values. We can make this work in Squeak and Pharo because we now have a prototype for clean blocks. So, quite different implementations, but very similar semantics That brings me to mention that in VW there's another, rather elegant, use for the once style block tricks, and that is to speed up step into in the debugger. Currently the implementation of step into is to simulate election (that's Smalltalk executing the InstructionStream byte code execution code, byte code by byte code) until control either returns or enters a block in the current method. That's slooooooow. The alternative is for the debugger to find all the blocks in the method and change their classes to a subclass of BlockClosure that raises an exception on value, and then use the step over code to get the VM to execute the code (via perform:) until either control returns or the exception is raised. The debugger then changes all the classes back and sets the focus to the current method. This is fast. Of course things get hairy when one considers debugging the debugger, but its all about the particular debugger only halting execution if it sees the exception is raised by the current set of blocks it has changed the classes of, and uses #pass to ignore any others created by other debuggers.
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" <siguctua@gmail.com> An: "Pharo Development List" <pharo-dev@lists.pharo.org> 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.
-- _,,,^..^,,,_ best, Eliot
On Fri, Jan 27, 2017 at 4:32 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Now, descending to the implementations, I understand that Ben's memorize...
btw, I feel a bit of an impostor having it called "my" memorize. It was Torsten's initiative based on gist by John Cromartie. https://pharo.fogbugz.com/f/cases/14458/Add-BlockClosure-memoized cheers -ben
Le 27 janv. 2017 05:55, "Ben Coman" <btc@openinworld.com> a écrit : On Fri, Jan 27, 2017 at 4:32 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
Now, descending to the implementations, I understand that Ben's memorize...
btw, I feel a bit of an impostor having it called "my" memorize. It was Torsten's initiative based on gist by John Cromartie. https://pharo.fogbugz.com/f/cases/14458/Add-BlockClosure-memoized Thx for the link. So, multi arg blocks someone? Phil cheers -ben
If one is doing any dynamic programming, the memoization term is pretty natural. https://youtu.be/OQ5jsbhAv_M?t=3m11s Phil On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <siguctua@gmail.com> 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.
Underscore.js names it also #memoize. http://underscorejs.org/#memoize Cheers On Jan 26, 2017 00:15, "phil@highoctane.be" <phil@highoctane.be> wrote: If one is doing any dynamic programming, the memoization term is pretty natural. https://youtu.be/OQ5jsbhAv_M?t=3m11s Phil On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <siguctua@gmail.com> 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.
On 26 January 2017 at 01:14, phil@highoctane.be <phil@highoctane.be> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.
for that purpose, i naturally using 'caching' wording.
https://youtu.be/OQ5jsbhAv_M?t=3m11s
Phil
On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <siguctua@gmail.com> 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.
result := [ do something long or short or whatever] cached. On 26 January 2017 at 01:20, Igor Stasenko <siguctua@gmail.com> wrote:
On 26 January 2017 at 01:14, phil@highoctane.be <phil@highoctane.be> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.
for that purpose, i naturally using 'caching' wording.
https://youtu.be/OQ5jsbhAv_M?t=3m11s
Phil
On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <siguctua@gmail.com> 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.
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 <siguctua@gmail.com> wrote:
result := [ do something long or short or whatever] cached.
On 26 January 2017 at 01:20, Igor Stasenko <siguctua@gmail.com> wrote:
On 26 January 2017 at 01:14, phil@highoctane.be <phil@highoctane.be> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.
for that purpose, i naturally using 'caching' wording.
https://youtu.be/OQ5jsbhAv_M?t=3m11s
Phil
On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <siguctua@gmail.com> 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.
On 26 January 2017 at 01:33, phil@highoctane.be <phil@highoctane.be> 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.
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: http://wiki.tcl.tk/10981 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 <siguctua@gmail.com> wrote:
On 26 January 2017 at 01:14, phil@highoctane.be <phil@highoctane.be> wrote:
If one is doing any dynamic programming, the memoization term is pretty natural.
for that purpose, i naturally using 'caching' wording.
https://youtu.be/OQ5jsbhAv_M?t=3m11s
Phil
On Wed, Jan 25, 2017 at 10:30 PM, Igor Stasenko <siguctua@gmail.com> 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.
On 26 Jan 2017, at 00:30, phil@highoctane.be wrote:
SomeClass>>#initialize self memoize: #someMethod:andParms:.
and bingo, automatic method memoization keyed by the objects passed.
I had a prototype called âvigorous cachingâ. It worked for methods without parameters though (http://blog.yuriy.tymch.uk/2016/02/vigorous-caching-in-pharo-or-how-i-used.h... <http://blog.yuriy.tymch.uk/2016/02/vigorous-caching-in-pharo-or-how-i-used.h...>)
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. https://en.wikipedia.org/wiki/Memoization http://www.cas.mcmaster.ca/~deza/6_Dynamic++.pdf http://wiki.tcl.tk/10779 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 <siguctua@gmail.com> 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.
On 26 January 2017 at 01:23, phil@highoctane.be <phil@highoctane.be> 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.
https://en.wikipedia.org/wiki/Memoization
http://www.cas.mcmaster.ca/~deza/6_Dynamic++.pdf
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 <siguctua@gmail.com> 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.
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 <siguctua@gmail.com> wrote:
On 26 January 2017 at 01:23, phil@highoctane.be <phil@highoctane.be> 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.
https://en.wikipedia.org/wiki/Memoization
http://www.cas.mcmaster.ca/~deza/6_Dynamic++.pdf
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 <siguctua@gmail.com> 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.
On 26 January 2017 at 01:40, phil@highoctane.be <phil@highoctane.be> 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.
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.
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 <siguctua@gmail.com> 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.
On 26 January 2017 at 02:10, phil@highoctane.be <phil@highoctane.be> 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 <siguctua@gmail.com> 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.
On 26 January 2017 at 02:10, phil@highoctane.be <phil@highoctane.be> wrote:
Ah ah :-D
DynamicVariables are darker magic that this, right?
you mean like those that seaside using? it lives as long as session lives, and tied to session you are working in.. in early versions of seaside they were using exceptions to access session storage.. quite ineffective.. but it works. for that purpose it is much better to use process-specific variables, that live and die together with process that hosts them.. but has significantly better access timings. and since seaside allocates a separate process per session, that's perfect fit.
in any case, the concern about getting rid of volatile data is covered.. while with memoization, i don't see it. and that seems like a HUGE argument against using it, because it is more trouble in a long run than time saver when you just start using it everywhere.
Phil
-- Best regards, Igor Stasenko.
There is the memoized with the internally declared Dictionary new as the cache and memoized using: cache There cache is known and the result is a block that does the caching thing. ([ :cacheKey| self getIssueCreateMetaWithExpandKeys: true ] memoizedUsing: self cache) value: #issueCreateMeta BlockClosure>>#memoizedUsing: cache "Provide a memoization block using the given cache. So one can tune by passing a LRUCache for instance" ^[ :x | cache at: x ifAbsentPut: [ self value: x ] ] Basically a shorthand for your recommendation. But I would have put a cull: instead of value: because sometimes, like in my case, there is no parameter, the only useful thing is the cacheKey. And it would be nice to have the :v1 :v2 :vn version with the cache key being made out of the combination + cull:cull:cull: Really, this is just a shorthand. This is nicer IMHO than having cache at:ifAbsentPut: all over. | cache factorial result | cache := LRUCache new maximumWeight: 3. factorial := 0. "avoid not-initialised warning when saving method source" factorial := [ :n | n = 1 ifTrue: [1] ifFalse: [(factorial value: n - 1) * n] ] memoizedUsing: cache. result := (1 to: 5) collect: factorial. Phil On Thu, Jan 26, 2017 at 1:36 AM, Igor Stasenko <siguctua@gmail.com> wrote:
On 26 January 2017 at 02:10, phil@highoctane.be <phil@highoctane.be> wrote:
Ah ah :-D
DynamicVariables are darker magic that this, right?
you mean like those that seaside using? it lives as long as session lives, and tied to session you are working in.. in early versions of seaside they were using exceptions to access session storage.. quite ineffective.. but it works. for that purpose it is much better to use process-specific variables, that live and die together with process that hosts them.. but has significantly better access timings. and since seaside allocates a separate process per session, that's perfect fit.
in any case, the concern about getting rid of volatile data is covered.. while with memoization, i don't see it. and that seems like a HUGE argument against using it, because it is more trouble in a long run than time saver when you just start using it everywhere.
Phil
-- Best regards, Igor Stasenko.
Denis can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
Hi Eliot.
2017-01-25 19:56 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
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
-- Using Opera's mail client: http://www.opera.com/mail/
stepharong wrote:
can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
When you use "as {something}" then "something" depicts the result of the conversion message sent to an object. Like in #asNumber or #asString which shows to what the receiver will be converted. My understanding is that in the case discussed the receiver object is NOT converted to a constant unchangeable method, so #asConstantMethod would not fit as a selector. Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better. Finding good names is really hardest part in programming... Thanks T.
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de> wrote:
stepharong wrote:
can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
When you use "as {something}" then "something" depicts the result of the conversion message sent to an object.
Like in #asNumber or #asString which shows to what the receiver will be converted.
Yes I thought that it was doing that.
My understanding is that in the case discussed the receiver object is NOT converted to a constant unchangeable method, so #asConstantMethod would not fit as a selector.
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
Finding good names is really hardest part in programming...
Thanks T.
-- Using Opera's mail client: http://www.opera.com/mail/
On Thu, Jan 26, 2017 at 2:02 PM, stepharong <stepharong@free.fr> wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de> wrote:
...
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
In other words, this is creating a constant inside the method (#asMethodConstant) instead of making the method return a constant (which would be your #asConstantMethod). If I have that right. In any case, not having the contracted 'Const' would be nice.
-cbc
-- Using Opera's mail client: http://www.opera.com/mail/
On 27 January 2017 at 00:28, Chris Cunningham <cunningham.cb@gmail.com> wrote:
On Thu, Jan 26, 2017 at 2:02 PM, stepharong <stepharong@free.fr> wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de> wrote:
...
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
In other words, this is creating a constant inside the method (#asMethodConstant) instead of making the method return a constant (which would be your #asConstantMethod). If I have that right. In any case, not having the contracted 'Const' would be nice.
ah.. that sounds similar to what i proposed for computed literals, that has been computed at compilation time and placed in method's literal frame, a simple catch by reserving special selector for it, i.e..:
mymethod ^ (something that should be computed , and takes a loong time) asMethodLiteral but that, of course, won't work if you would want to cache results based on method's input parameters.
-cbc
-- Using Opera's mail client: http://www.opera.com/mail/
-- Best regards, Igor Stasenko.
2017-01-26 23:28 GMT+01:00 Chris Cunningham <cunningham.cb@gmail.com>:
On Thu, Jan 26, 2017 at 2:02 PM, stepharong <stepharong@free.fr> wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de> wrote:
...
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
In other words, this is creating a constant inside the method (#asMethodConstant) instead of making the method return a constant (which would be your #asConstantMethod). If I have that right. In any case, not having the contracted 'Const' would be nice.
Ok, this is done 19611 <https://pharo.fogbugz.com/f/cases/19611/rename-asMethodConst-into-asMethodCo...> . Interesting to mention that while #asMethodConstant is defined on Object it also works well when sent to block. In that case BlockNode is replaced by result as literal
2017-01-27 10:28 GMT+01:00 Denis Kudriashov <dionisiydk@gmail.com>:
Ok, this is done 19611 <https://pharo.fogbugz.com/f/cases/19611/rename-asMethodConst-into-asMethodCo...> .
In 60361
On Fri, Jan 27, 2017 at 6:02 AM, stepharong <stepharong@free.fr> wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de> wrote:
stepharong wrote:
can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
When you use "as {something}" then "something" depicts the result of the conversion message sent to an object.
Like in #asNumber or #asString which shows to what the receiver will be converted.
Yes I thought that it was doing that.
My understanding is that in the case discussed the receiver object is NOT converted to a constant unchangeable method, so #asConstantMethod would not fit as a selector.
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
method constant = constant of a method constant method = method that does not change HTH, cheers -ben
On 27 January 2017 at 01:30, Ben Coman <btc@openinworld.com> wrote:
On Fri, Jan 27, 2017 at 6:02 AM, stepharong <stepharong@free.fr> wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de> wrote:
stepharong wrote:
can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
When you use "as {something}" then "something" depicts the result of the conversion message sent to an object.
Like in #asNumber or #asString which shows to what the receiver will be converted.
Yes I thought that it was doing that.
My understanding is that in the case discussed the receiver object is NOT converted to a constant unchangeable method, so #asConstantMethod would not fit as a selector.
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
method constant = constant of a method constant method = method that does not change
are you sure? maybe it is constant method = method that returns constant?
apparently, that's why 'constant' term doesn't fits there, because there's so many confusion about it. what are the constant in dynamic system, after all? HTH, cheers -ben
-- Best regards, Igor Stasenko.
On Fri, Jan 27, 2017 at 7:35 AM, Igor Stasenko <siguctua@gmail.com> wrote:
On 27 January 2017 at 01:30, Ben Coman <btc@openinworld.com> wrote:
On Fri, Jan 27, 2017 at 6:02 AM, stepharong <stepharong@free.fr> wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de> wrote:
stepharong wrote:
can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
When you use "as {something}" then "something" depicts the result of the conversion message sent to an object.
Like in #asNumber or #asString which shows to what the receiver will be converted.
Yes I thought that it was doing that.
My understanding is that in the case discussed the receiver object is NOT converted to a constant unchangeable method, so #asConstantMethod would not fit as a selector.
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
method constant = constant of a method
constant method = method that does not change
are you sure?
pretty sure. 'method' is the subject. 'constant' is the adjective that modifies the subject. Its a bit hard to explain that intrinsic feeling of what is right, but maybe.... If the adjective follows the subject its usually separated by little joining words. http://www.grammar-monster.com/glossary/adjective_definition.htm
maybe it is constant method = method that returns constant?
For me this does not compute. But I understand rules differ in other languages and its hard to avoid subtle influences from your primary language. And still, it could just be my personal bias. So if you & Stef find it ambiguous, it may be for others and we should aim to avoid that. cheers -ben
apparently, that's why 'constant' term doesn't fits there, because there's so many confusion about it. what are the constant in dynamic system, after all?
On 27 January 2017 at 02:28, Ben Coman <btc@openinworld.com> wrote:
On Fri, Jan 27, 2017 at 7:35 AM, Igor Stasenko <siguctua@gmail.com> wrote:
On 27 January 2017 at 01:30, Ben Coman <btc@openinworld.com> wrote:
On Fri, Jan 27, 2017 at 6:02 AM, stepharong <stepharong@free.fr> wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de> wrote:
stepharong wrote:
can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
When you use "as {something}" then "something" depicts the result of the conversion message sent to an object.
Like in #asNumber or #asString which shows to what the receiver will
be
converted.
Yes I thought that it was doing that.
My understanding is that in the case discussed the receiver object is NOT converted to a constant unchangeable method, so #asConstantMethod would not fit as a selector.
Instead it is sent to an object that afterwards is a constant within
a
method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
method constant = constant of a method
constant method = method that does not change
are you sure?
pretty sure. 'method' is the subject. 'constant' is the adjective that modifies the subject. Its a bit hard to explain that intrinsic feeling of what is right, but maybe.... If the adjective follows the subject its usually separated by little joining words. http://www.grammar-monster.com/glossary/adjective_definition.htm
maybe it is constant method = method that returns constant?
For me this does not compute. But I understand rules differ in other languages and its hard to avoid subtle influences from your primary language.
heh.. you see my pain! right now i have to deal with C++ and seeing all these const Type & foo const.. and cannot parse it.. :) And still, it could just be my personal bias.
So if you & Stef find it ambiguous, it may be for others and we should aim to avoid that.
Well, we have more general term for objects that do not change over their lifetime - immutable. And it is moare precise, if we're talking in smalltalk context. So, why borrowing rather alien term into our ecosystem, because i barely heard that anyone were using it, and saying something like 'constant object' or something like this, when talking smalltalk context.
Because when you open this 'can' of constant method, what does it means being a constant? Is is that method's properties won't change, or all object(s) it is pointing to never change as well?
cheers -ben
apparently, that's why 'constant' term doesn't fits there, because
there's
so many confusion about it. what are the constant in dynamic system, after all?
-- Best regards, Igor Stasenko.
On 27 January 2017 at 03:45, Igor Stasenko <siguctua@gmail.com> wrote:
On 27 January 2017 at 02:28, Ben Coman <btc@openinworld.com> wrote:
On Fri, Jan 27, 2017 at 7:35 AM, Igor Stasenko <siguctua@gmail.com> wrote:
On 27 January 2017 at 01:30, Ben Coman <btc@openinworld.com> wrote:
On Fri, Jan 27, 2017 at 6:02 AM, stepharong <stepharong@free.fr>
wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de
wrote:
stepharong wrote:
can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
When you use "as {something}" then "something" depicts the result of the conversion message sent to an object.
Like in #asNumber or #asString which shows to what the receiver will be converted.
Yes I thought that it was doing that.
My understanding is that in the case discussed the receiver object
is
NOT converted to a constant unchangeable method, so #asConstantMethod would not fit as a selector.
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
method constant = constant of a method
constant method = method that does not change
are you sure?
pretty sure. 'method' is the subject. 'constant' is the adjective that modifies the subject. Its a bit hard to explain that intrinsic feeling of what is right, but maybe.... If the adjective follows the subject its usually separated by little joining words. http://www.grammar-monster.com/glossary/adjective_definition.htm
maybe it is constant method = method that returns constant?
For me this does not compute. But I understand rules differ in other languages and its hard to avoid subtle influences from your primary language.
heh.. you see my pain! right now i have to deal with C++ and seeing all these const Type & foo const.. and cannot parse it.. :)
And still, it could just be my personal bias.
So if you & Stef find it ambiguous, it may be for others and we should aim to avoid that.
Well, we have more general term for objects that do not change over their lifetime - immutable. And it is moare precise,
(or if not general, but well settled)
if we're talking in smalltalk context. So, why borrowing rather alien term into our ecosystem, because i barely heard that anyone were using it, and saying something like 'constant object' or something like this, when talking smalltalk context.
Because when you open this 'can' of constant method, what does it means being a constant? Is is that method's properties won't change, or all object(s) it is pointing to never change as well?
cheers -ben
apparently, that's why 'constant' term doesn't fits there, because
there's
so many confusion about it. what are the constant in dynamic system, after all?
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
Am 27.01.2017 um 02:45 schrieb Igor Stasenko <siguctua@gmail.com>:
On 27 January 2017 at 02:28, Ben Coman <btc@openinworld.com <mailto:btc@openinworld.com>> wrote: On Fri, Jan 27, 2017 at 7:35 AM, Igor Stasenko <siguctua@gmail.com <mailto:siguctua@gmail.com>> wrote:
On 27 January 2017 at 01:30, Ben Coman <btc@openinworld.com <mailto:btc@openinworld.com>> wrote:
On Fri, Jan 27, 2017 at 6:02 AM, stepharong <stepharong@free.fr <mailto:stepharong@free.fr>> wrote:
On Thu, 26 Jan 2017 20:38:49 +0100, Torsten Bergmann <astares@gmx.de <mailto:astares@gmx.de>> wrote:
stepharong wrote:
can we rename this selector? asMethodConst should be at least be renamed to asConstantMethod
When you use "as {something}" then "something" depicts the result of the conversion message sent to an object.
Like in #asNumber or #asString which shows to what the receiver will be converted.
Yes I thought that it was doing that.
My understanding is that in the case discussed the receiver object is NOT converted to a constant unchangeable method, so #asConstantMethod would not fit as a selector.
Instead it is sent to an object that afterwards is a constant within a method (so it will not be evaluated later at runtime again) so IMHO #asMethodConstant instead of #asMethodConst would be better.
I do not understand any of them.
method constant = constant of a method
constant method = method that does not change
are you sure?
pretty sure. 'method' is the subject. 'constant' is the adjective that modifies the subject. Its a bit hard to explain that intrinsic feeling of what is right, but maybe.... If the adjective follows the subject its usually separated by little joining words. http://www.grammar-monster.com/glossary/adjective_definition.htm <http://www.grammar-monster.com/glossary/adjective_definition.htm>
maybe it is constant method = method that returns constant?
For me this does not compute. But I understand rules differ in other languages and its hard to avoid subtle influences from your primary language.
heh.. you see my pain! right now i have to deal with C++ and seeing all these const Type & foo const.. and cannot parse it.. :)
And still, it could just be my personal bias. So if you & Stef find it ambiguous, it may be for others and we should aim to avoid that.
Well, we have more general term for objects that do not change over their lifetime - immutable. And it is moare precise, if we're talking in smalltalk context. So, why borrowing rather alien term into our ecosystem, because i barely heard that anyone were using it, and saying something like 'constant object' or something like this, when talking smalltalk context.
We use the term immutable for an object that _can not_ be changed and not for objects that _do not_ change. Norbert
Because when you open this 'can' of constant method, what does it means being a constant? Is is that method's properties won't change, or all object(s) it is pointing to never change as well?
cheers -ben
apparently, that's why 'constant' term doesn't fits there, because there's so many confusion about it. what are the constant in dynamic system, after all?
-- Best regards, Igor Stasenko.
heh.. you see my pain! right now i have to deal with C++
and seeing all these const Type & foo const.. and cannot parse it.. :)
I think that C++ tries to avoid this confusion by not using "method" for the members of a method, so for example it does not define variables inside a method as "method variables" but rather "local variables" so AFAIK C++ has "constant method" as a method that is not allowed to change but it does not have or at least I have not seen "method constant' as a variable inside a method that does not change but rather refers to it as "method's local constant variable" while "constant" alone is implying "global constant variable". In case C++ did define as you said the confusion would extend even more to what you mention because "method constant" would imply a method local constant variable and not a return type. As Python zen's states "its better to be explicit than implicit" . Sure long names take more time to type(unless you use auto completion) but they avoid such confusions and the need to take a look at the documentation.
On Fri, Jan 27, 2017 at 7:12 AM, Dimitris Chloupis <kilon.alios@gmail.com> wrote:
heh.. you see my pain! right now i have to deal with C++
and seeing all these const Type & foo const.. and cannot parse it.. :)
I think that C++ tries to avoid this confusion by not using "method" for the members of a method, so for example it does not define variables inside a method as "method variables" but rather "local variables" so AFAIK C++ has "constant method" as a method that is not allowed to change but it does not have or at least I have not seen "method constant' as a variable inside a method that does not change but rather refers to it as "method's local constant variable" while "constant" alone is implying "global constant variable".
In case C++ did define as you said the confusion would extend even more to what you mention because "method constant" would imply a method local constant variable and not a return type.
As Python zen's states "its better to be explicit than implicit" . Sure long names take more time to type(unless you use auto completion) but they avoid such confusions and the need to take a look at the documentation.
Hmm. Our language doesn't have method variables, either - class variables, instance variables, and temp variables (among others). Maybe this should be called 'asTempConstant' ? (although a 'temporary constant' sound really, really weird...) -cbc
Hmm. Our language doesn't have method variables, either - class variables, instance variables, and temp variables (among others).
Maybe this should be called 'asTempConstant' ? (although a 'temporary constant' sound really, really weird...)
-cbc
Indeed , "temp variables" is what is named. I do not think we have to include "constant". There are other ways to express something that does not change. maybe "asReadOnlyTempVariable" or "asImmutableTempVariable" ?
Oops, forgive me Ben. I'm wrong. once is only equivalent to memoized for nullary blocks. It is not the same as memoized:[value:] for N-ary blocks. Forgive the noise. _,,,^..^,,,_ (phone)
On Jan 25, 2017, at 10:56 AM, Eliot Miranda <eliot.miranda@gmail.com> wrote:
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
participants (14)
-
Aliaksei Syrel -
Ben Coman -
Chris Cunningham -
Denis Kudriashov -
Dimitris Chloupis -
Eliot Miranda -
Igor Stasenko -
Nicolas Cellier -
Norbert Hartl -
phil@highoctane.be -
philippe.back@highoctane.be -
stepharong -
Torsten Bergmann -
Yuriy Tymchuk