Off Topic: I hate that VisualWorks uses arbitrary .ws extensions for
something that would be an otherwise perfect .txt file. I mention this because Outlook specifically treats .ws as insecure and blocks the attachment. -Boris -----Original Message----- From: [hidden email] [mailto:[hidden email]] On Behalf Of Reinout Heeck Sent: Thursday, March 22, 2012 1:13 PM To: [hidden email] Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of BlockClosure>>once (in Assets) Trying to atone for that foot in my mouth, I concocted a sketch for fixing #once. Please find attached a workspace snippet that will alter the system without immediately crashing it. When evaluating the script it will complain about undeclared names, simply hit 'leave undeclared'. This implementation delegates the caching and becoming to the CompiledBlock instances instead of the BlockClosure instances that the original used. It should now work for both clean and copying blocks. The simple test Steven Kelly supplied below should now yield true in both cases. This code has hardly been tested, its just a sketch and needs some cleanup (and it is developed on 771 FTW). In both the original and new versions I miss the flushing of the VM (JIT) caches, could someone here with knowledge about the JIT review this apparent omission? > On 3/21/2012 1:32 PM, Steven Kelly wrote: >> Object class>>onceClean >> "self onceClean == self onceClean" "true" >> ^[Object new] once >> >> Object class>>onceUnclean >> "self onceUnclean == self onceUnclean" "false" >> ^[self new] once Enjoy, Reinout _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Reinout Heeck-2
On Thu, Mar 22, 2012 at 10:13 AM, Reinout Heeck <[hidden email]> wrote: Trying to atone for that foot in my mouth, I concocted a sketch for fixing #once. Clever! And that suggests a simple implementation for Squeak. Methods can maintain a map in a their properties/pragmas/method tags to map closure initial pc to cached value. Thanks!!
Please find attached a workspace snippet that will alter the system without immediately crashing it. best, Eliot _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
It sounds similar to a technique I use in GS/S code to turn ComplexBlocks into SimpleBlocks (different terminology from VW, but same idea). The "Efficient GemStone
Enumeration" framework has been enhanced and simplified (http://techsupport.gemstone.com/entries/175923-efficient-gemstone-enumeration-2-1-002-0). Sorry I haven't shared the updated version yet. One of the neat things about the new version is that it is extended
to optimize blocks for enumeration. It effectively recompiles blocks to pass context into simpler blocks through extended arguments rather than having a block closure reference external context. The optimized blocks are cached for reuse. Amazing gains are
achieved in GS by using SimpleBlocks instead of ComplexBlocks. The framework I mentioned makes it possible to write application code to use simple blocks but it is still up to a developer to revise code to use the simple blocks. Developers get it wrong. They
sometimes go through a lot of effort to refactor code but make a mistake in the optimization that makes all that work moot. This automatic optimization eliminates those mistakes and existing code can become much faster without having to tune application code. Collection>>including: including1 including: including2 collect: threeArgBlock "Extension of GS_CollectionPerformanceBase. plb 2011.06.27" | results optimizedBlock | optimizedBlock := threeArgBlock forEnumerating:
self. results := self _newCollectResultForBlock: optimizedBlock. self
_into: results
elective: including1
elective: including2
elective: nil
elective: nil keyedCollect: optimizedBlock. self _finishedCollect: optimizedBlock
started: 0
results: results. ^results This framework is for GS/S; however, the same performance gains can be obtained in other dialects.
Paul Baumann From: [hidden email] [mailto:[hidden email]]
On Behalf Of Eliot Miranda On Thu, Mar 22, 2012 at 10:13 AM, Reinout Heeck <[hidden email]> wrote: Trying to atone for that foot in my mouth, I concocted a sketch for fixing #once. Clever! And that suggests a simple implementation for Squeak. Methods can maintain a map in a their properties/pragmas/method tags to map closure initial pc to cached value. Thanks!!
-- Eliot This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
Hi paul
I'm reading your slide and I do not understand The cost if an OrderedCollectoin contains 1000 items #includes: anObject can have the cost of creating 1001 block closure objects Can you explain what you mean? Stef On Mar 23, 2012, at 3:12 PM, Paul Baumann wrote: > It sounds similar to a technique I use in GS/S code to turn ComplexBlocks into SimpleBlocks (different terminology from VW, but same idea). The "Efficient GemStone Enumeration" framework has been enhanced and simplified (http://techsupport.gemstone.com/entries/175923-efficient-gemstone-enumeration-2-1-002-0). Sorry I haven't shared the updated version yet. One of the neat things about the new version is that it is extended to optimize blocks for enumeration. It effectively recompiles blocks to pass context into simpler blocks through extended arguments rather than having a block closure reference external context. The optimized blocks are cached for reuse. Amazing gains are achieved in GS by using SimpleBlocks instead of ComplexBlocks. The framework I mentioned makes it possible to write application code to use simple blocks but it is still up to a developer to revise code to use the simple blocks. Developers get it wrong. They sometimes go through a lot of effort to refac! tor code but make a mistake in the optimization that makes all that work moot. This automatic optimization eliminates those mistakes and existing code can become much faster without having to tune application code. > > Collection>>including: including1 including: including2 > collect: threeArgBlock > "Extension of GS_CollectionPerformanceBase. plb 2011.06.27" > > | results optimizedBlock | > optimizedBlock := threeArgBlock forEnumerating: self. > results := self _newCollectResultForBlock: optimizedBlock. > self > _into: results > elective: including1 > elective: including2 > elective: nil > elective: nil > keyedCollect: optimizedBlock. > self _finishedCollect: optimizedBlock > started: 0 > results: results. > ^results > > This framework is for GS/S; however, the same performance gains can be obtained in other dialects. > > Paul Baumann > > > > From: [hidden email] [mailto:[hidden email]] On Behalf Of Eliot Miranda > Sent: Thursday, March 22, 2012 18:02 > To: Reinout Heeck > Cc: [hidden email] > Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of BlockClosure>>once (in Assets) > > > > On Thu, Mar 22, 2012 at 10:13 AM, Reinout Heeck <[hidden email]> wrote: > Trying to atone for that foot in my mouth, I concocted a sketch for fixing #once. > > Clever! And that suggests a simple implementation for Squeak. Methods can maintain a map in a their properties/pragmas/method tags to map closure initial pc to cached value. Thanks!! > > Please find attached a workspace snippet that will alter the system without immediately crashing it. > When evaluating the script it will complain about undeclared names, simply hit 'leave undeclared'. > > > This implementation delegates the caching and becoming to the CompiledBlock instances instead of the BlockClosure instances that the original used. It should now work for both clean and copying blocks. > The simple test Steven Kelly supplied below should now yield true in both cases. > > This code has hardly been tested, its just a sketch and needs some cleanup (and it is developed on 771 FTW). > > In both the original and new versions I miss the flushing of the VM (JIT) caches, > could someone here with knowledge about the JIT review this apparent omission? > > > > On 3/21/2012 1:32 PM, Steven Kelly wrote: > Object class>>onceClean > "self onceClean == self onceClean" "true" > ^[Object new] once > > Object class>>onceUnclean > "self onceUnclean == self onceUnclean" "false" > ^[self new] once > > Enjoy, Reinout > > > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc > > > > > -- > best, > Eliot > > > This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
The return from within the closure to #do: of Collection>>includes: makes it complex. The reference to anObject also prevents the closure from being a SimpleBlock. #includes: enumerates all the values until it finds a match. Each time the closure is used it will have a cost related to noting context.
Use GS/S profiling tools to see the instance creation cost. You have to use (or configure) the tool to see the object creation costs. I use "AdvancedProfMonitor spyOnWithObjCreation: ..." but ProfMonitor can likely be configured to do the same. Here is a comparison of the original #includes: (renamed #overridden_includes:) and the tuned one: | oc | oc := (1 to: 1000) asOrderedCollection. AdvancedProfMonitor spyOnWithObjCreation: [oc overridden_includes: 5000]. ... OBJECT CREATION REPORT tally class of created object ------ -------------------------------------- 1002 ComplexBlock 1000 instances created by ComplexBlock >> value: ----------------------------- 2 Array 2 instances created by Collection >> do: ----------------------------- 1 VariableContext ----------------------------- | oc | oc := (1 to: 1000) asOrderedCollection. AdvancedProfMonitor spyOnWithObjCreation: [oc includes: 5000]. OBJECT CREATION REPORT tally class of created object ------ -------------------------------------- 2 GsMethodDictionary 2 instances created by Collection >> includes: ----------------------------- 1 ComplexBlock ----------------------------- This shows relative performance: | oc t1 t2 | oc := (1 to: 1000) asOrderedCollection. t1 := System _timeGmtFloat. 5000 timesRepeat: [oc overridden_includes: 5000]. t1 := (t2 := System _timeGmtFloat) - t1. 5000 timesRepeat: [oc includes: 5000]. t2 := System _timeGmtFloat - t2. Array with: t1 with: t2 with: (1 - (t2 / t1) * -100.0) anArray( 2.2144579887390137E+00, 1.1899878978729248E+00, -4.6262791891999555E+01) anArray( 2.1812989711761475E+00, 1.1948599815368652E+00, -4.5222548704884701E+01) anArray( 2.0989649295806885E+00, 1.1740782260894775E+00, -4.4063942682261782E+01) The execution time for the new #includes: is 44-46% less than the original #includes:. The difference is due to the original #including: creating 1000 instances of ComplexBlock for each execution. Paul Baumann -----Original Message----- From: stephane ducasse [mailto:[hidden email]] Sent: Friday, March 23, 2012 10:54 To: Paul Baumann Cc: Eliot Miranda; Reinout Heeck; [hidden email] Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of BlockClosure>>once (in Assets) Hi paul I'm reading your slide and I do not understand The cost if an OrderedCollectoin contains 1000 items #includes: anObject can have the cost of creating 1001 block closure objects Can you explain what you mean? Stef On Mar 23, 2012, at 3:12 PM, Paul Baumann wrote: > It sounds similar to a technique I use in GS/S code to turn ComplexBlocks into SimpleBlocks (different terminology from VW, but same idea). The "Efficient GemStone Enumeration" framework has been enhanced and simplified (http://techsupport.gemstone.com/entries/175923-efficient-gemstone-enumeration-2-1-002-0). Sorry I haven't shared the updated version yet. One of the neat things about the new version is that it is extended to optimize blocks for enumeration. It effectively recompiles blocks to pass context into simpler blocks through extended arguments rather than having a block closure reference external context. The optimized blocks are cached for reuse. Amazing gains are achieved in GS by using SimpleBlocks instead of ComplexBlocks. The framework I mentioned makes it possible to write application code to use simple blocks but it is still up to a developer to revise code to use the simple blocks. Developers get it wrong. They sometimes go through a lot of effort to refac! tor code but make a mistake in the optimization that makes all that work moot. This automatic optimization eliminates those mistakes and existing code can become much faster without having to tune application code. > > Collection>>including: including1 including: including2 > collect: threeArgBlock > "Extension of GS_CollectionPerformanceBase. plb 2011.06.27" > > | results optimizedBlock | > optimizedBlock := threeArgBlock forEnumerating: self. > results := self _newCollectResultForBlock: optimizedBlock. > self > _into: results > elective: including1 > elective: including2 > elective: nil > elective: nil > keyedCollect: optimizedBlock. > self _finishedCollect: optimizedBlock > started: 0 > results: results. > ^results > > This framework is for GS/S; however, the same performance gains can be obtained in other dialects. > > Paul Baumann > > > > From: [hidden email] [mailto:[hidden email]] On Behalf Of Eliot Miranda > Sent: Thursday, March 22, 2012 18:02 > To: Reinout Heeck > Cc: [hidden email] > Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of BlockClosure>>once (in Assets) > > > > On Thu, Mar 22, 2012 at 10:13 AM, Reinout Heeck <[hidden email]> wrote: > Trying to atone for that foot in my mouth, I concocted a sketch for fixing #once. > > Clever! And that suggests a simple implementation for Squeak. Methods can maintain a map in a their properties/pragmas/method tags to map closure initial pc to cached value. Thanks!! > > Please find attached a workspace snippet that will alter the system without immediately crashing it. > When evaluating the script it will complain about undeclared names, simply hit 'leave undeclared'. > > > This implementation delegates the caching and becoming to the CompiledBlock instances instead of the BlockClosure instances that the original used. It should now work for both clean and copying blocks. > The simple test Steven Kelly supplied below should now yield true in both cases. > > This code has hardly been tested, its just a sketch and needs some cleanup (and it is developed on 771 FTW). > > In both the original and new versions I miss the flushing of the VM (JIT) caches, > could someone here with knowledge about the JIT review this apparent omission? > > > > On 3/21/2012 1:32 PM, Steven Kelly wrote: > Object class>>onceClean > "self onceClean == self onceClean" "true" > ^[Object new] once > > Object class>>onceUnclean > "self onceUnclean == self onceUnclean" "false" > ^[self new] once > > Enjoy, Reinout > > > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc > > > > > -- > best, > Eliot > > > This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
Paul
coming from lisp where closures are objects, I wonder if the answer to my question is due to the fact that in Smalltalk are not objects so the byte code interpretation as to create a block objects out of a sequence of byte code in addition to its activation. Stef On Mar 23, 2012, at 4:40 PM, Paul Baumann wrote: > The return from within the closure to #do: of Collection>>includes: makes it complex. The reference to anObject also prevents the closure from being a SimpleBlock. #includes: enumerates all the values until it finds a match. Each time the closure is used it will have a cost related to noting context. > > Use GS/S profiling tools to see the instance creation cost. You have to use (or configure) the tool to see the object creation costs. I use "AdvancedProfMonitor spyOnWithObjCreation: ..." but ProfMonitor can likely be configured to do the same. Here is a comparison of the original #includes: (renamed #overridden_includes:) and the tuned one: > > | oc | > oc := (1 to: 1000) asOrderedCollection. > AdvancedProfMonitor spyOnWithObjCreation: [oc overridden_includes: 5000]. > > ... > OBJECT CREATION REPORT > > tally class of created object > ------ -------------------------------------- > > 1002 ComplexBlock > 1000 instances created by ComplexBlock >> value: > ----------------------------- > > 2 Array > 2 instances created by Collection >> do: > ----------------------------- > > 1 VariableContext > ----------------------------- > > > | oc | > oc := (1 to: 1000) asOrderedCollection. > AdvancedProfMonitor spyOnWithObjCreation: [oc includes: 5000]. > > OBJECT CREATION REPORT > > tally class of created object > ------ -------------------------------------- > > 2 GsMethodDictionary > 2 instances created by Collection >> includes: > ----------------------------- > > 1 ComplexBlock > ----------------------------- > > This shows relative performance: > > | oc t1 t2 | > oc := (1 to: 1000) asOrderedCollection. > t1 := System _timeGmtFloat. > 5000 timesRepeat: [oc overridden_includes: 5000]. > t1 := (t2 := System _timeGmtFloat) - t1. > 5000 timesRepeat: [oc includes: 5000]. > t2 := System _timeGmtFloat - t2. > Array with: t1 with: t2 with: (1 - (t2 / t1) * -100.0) > > anArray( 2.2144579887390137E+00, 1.1899878978729248E+00, -4.6262791891999555E+01) > anArray( 2.1812989711761475E+00, 1.1948599815368652E+00, -4.5222548704884701E+01) > anArray( 2.0989649295806885E+00, 1.1740782260894775E+00, -4.4063942682261782E+01) > > The execution time for the new #includes: is 44-46% less than the original #includes:. The difference is due to the original #including: creating 1000 instances of ComplexBlock for each execution. > > Paul Baumann > > > > > -----Original Message----- > From: stephane ducasse [mailto:[hidden email]] > Sent: Friday, March 23, 2012 10:54 > To: Paul Baumann > Cc: Eliot Miranda; Reinout Heeck; [hidden email] > Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of BlockClosure>>once (in Assets) > > Hi paul > > I'm reading your slide and I do not understand > > The cost > > if an OrderedCollectoin contains 1000 items #includes: anObject can have the cost of creating 1001 block closure objects > > Can you explain what you mean? > > Stef > > > > On Mar 23, 2012, at 3:12 PM, Paul Baumann wrote: > >> It sounds similar to a technique I use in GS/S code to turn ComplexBlocks into SimpleBlocks (different terminology from VW, but same idea). The "Efficient GemStone Enumeration" framework has been enhanced and simplified (http://techsupport.gemstone.com/entries/175923-efficient-gemstone-enumeration-2-1-002-0). Sorry I haven't shared the updated version yet. One of the neat things about the new version is that it is extended to optimize blocks for enumeration. It effectively recompiles blocks to pass context into simpler blocks through extended arguments rather than having a block closure reference external context. The optimized blocks are cached for reuse. Amazing gains are achieved in GS by using SimpleBlocks instead of ComplexBlocks. The framework I mentioned makes it possible to write application code to use simple blocks but it is still up to a developer to revise code to use the simple blocks. Developers get it wrong. They sometimes go through a lot of effort to refa! >> >> Collection>>including: including1 including: including2 >> collect: threeArgBlock >> "Extension of GS_CollectionPerformanceBase. plb 2011.06.27" >> >> | results optimizedBlock | >> optimizedBlock := threeArgBlock forEnumerating: self. >> results := self _newCollectResultForBlock: optimizedBlock. >> self >> _into: results >> elective: including1 >> elective: including2 >> elective: nil >> elective: nil >> keyedCollect: optimizedBlock. >> self _finishedCollect: optimizedBlock >> started: 0 >> results: results. >> ^results >> >> This framework is for GS/S; however, the same performance gains can be obtained in other dialects. >> >> Paul Baumann >> >> >> >> From: [hidden email] [mailto:[hidden email]] On Behalf Of Eliot Miranda >> Sent: Thursday, March 22, 2012 18:02 >> To: Reinout Heeck >> Cc: [hidden email] >> Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of BlockClosure>>once (in Assets) >> >> >> >> On Thu, Mar 22, 2012 at 10:13 AM, Reinout Heeck <[hidden email]> wrote: >> Trying to atone for that foot in my mouth, I concocted a sketch for fixing #once. >> >> Clever! And that suggests a simple implementation for Squeak. Methods can maintain a map in a their properties/pragmas/method tags to map closure initial pc to cached value. Thanks!! >> >> Please find attached a workspace snippet that will alter the system without immediately crashing it. >> When evaluating the script it will complain about undeclared names, simply hit 'leave undeclared'. >> >> >> This implementation delegates the caching and becoming to the CompiledBlock instances instead of the BlockClosure instances that the original used. It should now work for both clean and copying blocks. >> The simple test Steven Kelly supplied below should now yield true in both cases. >> >> This code has hardly been tested, its just a sketch and needs some cleanup (and it is developed on 771 FTW). >> >> In both the original and new versions I miss the flushing of the VM (JIT) caches, >> could someone here with knowledge about the JIT review this apparent omission? >> >> >> >> On 3/21/2012 1:32 PM, Steven Kelly wrote: >> Object class>>onceClean >> "self onceClean == self onceClean" "true" >> ^[Object new] once >> >> Object class>>onceUnclean >> "self onceUnclean == self onceUnclean" "false" >> ^[self new] once >> >> Enjoy, Reinout >> >> >> _______________________________________________ >> vwnc mailing list >> [hidden email] >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc >> >> >> >> >> -- >> best, >> Eliot >> >> >> This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. >> _______________________________________________ >> vwnc mailing list >> [hidden email] >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc > > > > This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. > _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
On Fri, Mar 23, 2012 at 8:53 AM, stephane ducasse <[hidden email]> wrote: Paul Why are closures in Lisp objects and closures in Smalltalk not objects? (IMO they are objects in Smalltalk and presumably only objects in CLOS or another OO Lisp, not in pure lisp. In fact, Travis' once implementation is extremely OO, using a subclass of BlockCLosure (CachedBlockClosure?)). The issue is not whether a closure is an object or not, the issue is what constitutes the closure. If the closure closes-over things that are available at compile-time (i.e. has no free variables) then the implementation is free to create the closure at run-time. If the closure closes-over things that are available only when the closure is mentioned then the closure must be created when it is mentioned, and hence the closure must be created by combining closed-over variables and code into a newly created closure. So I don't understand your point. Is it that the closure's method isn't a separate object or what?
cheers, Eliot
best, Eliot _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
I can't speak to the lisp oriented questions; however... Eliot is correct that these are objects that are [revised] code and closed-over context. The original block was an object too, so no problem in a language like
Smalltalk so long as messages are understood. Tricks like these are not worth the cost unless used where there is repetition to eliminate (like when enumerating a collection). The implementation I created
for GS/S last year had both EnumerationBlock and EnumerationSimplifiedBlock. They are subclasses of EnumerationOptimization, which is not a subclass of BlockClosure due to GS/S subclass restrictions. EnumerationBlock is the closure proxy with "as mentioned"
variables and EnumerationSimplifiedBlock is the reuseable optimized form. Both refer to the recompiled 'simplifiedBlock' with bytecode and more arguments than the original. Passed context is extendable. EnumerationBlock instances are held in an EnumerationBlockPool
indexed by the constant part of the original closure. Execution statistics are also tracked for automatic optimization of pre-allocated collections. It works very well. Debugging through these blocks is very natural too. Paul Baumann From: Eliot Miranda [mailto:[hidden email]]
On Fri, Mar 23, 2012 at 8:53 AM, stephane ducasse <[hidden email]> wrote: Paul Why are closures in Lisp objects and closures in Smalltalk not objects? (IMO they are objects in Smalltalk and presumably only objects in CLOS or another OO Lisp, not in pure lisp. In fact, Travis' once implementation is extremely OO,
using a subclass of BlockCLosure (CachedBlockClosure?)). The issue is not whether a closure is an object or not, the issue is what constitutes the closure. If the closure closes-over things that are available at compile-time (i.e. has no free variables)
then the implementation is free to create the closure at run-time. If the closure closes-over things that are available only when the closure is mentioned then the closure must be created when it is mentioned, and hence the closure must be created by combining
closed-over variables and code into a newly created closure. So I don't understand your point. Is it that the closure's method isn't a separate object or what? cheers, Eliot
-- Eliot This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Eliot Miranda-2
I know what is a free variable and closing over. I explained it in lecture (fun args and all the rest). No need to explain that to me.
My point is why does the system creates 1000 instance of closures when iterating on a 1000 element collection? why there is not one closure associated to the method and applied with different arguments? Where the semantics says that each iteration step should create a new one? This was my original question and the answer of paul did not make that clear. Stef > > > On Fri, Mar 23, 2012 at 8:53 AM, stephane ducasse <[hidden email]> wrote: > Paul > > coming from lisp where closures are objects, I wonder if the answer to my question is due to the fact that in Smalltalk are not objects > so the byte code interpretation as to create a block objects out of a sequence of byte code in addition to its activation. > > Why are closures in Lisp objects and closures in Smalltalk not objects? (IMO they are objects in Smalltalk and presumably only objects in CLOS or another OO Lisp, not in pure lisp. In fact, Travis' once implementation is extremely OO, using a subclass of BlockCLosure (CachedBlockClosure?)). The issue is not whether a closure is an object or not, the issue is what constitutes the closure. If the closure closes-over things that are available at compile-time (i.e. has no free variables) then the implementation is free to create the closure at run-time. If the closure closes-over things that are available only when the closure is mentioned then the closure must be created when it is mentioned, and hence the closure must be created by combining closed-over variables and code into a newly created closure. So I don't understand your point. Is it that the closure's method isn't a separate object or what? > > > cheers, > Eliot > > > Stef > > On Mar 23, 2012, at 4:40 PM, Paul Baumann wrote: > > > The return from within the closure to #do: of Collection>>includes: makes it complex. The reference to anObject also prevents the closure from being a SimpleBlock. #includes: enumerates all the values until it finds a match. Each time the closure is used it will have a cost related to noting context. > > > > Use GS/S profiling tools to see the instance creation cost. You have to use (or configure) the tool to see the object creation costs. I use "AdvancedProfMonitor spyOnWithObjCreation: ..." but ProfMonitor can likely be configured to do the same. Here is a comparison of the original #includes: (renamed #overridden_includes:) and the tuned one: > > > > | oc | > > oc := (1 to: 1000) asOrderedCollection. > > AdvancedProfMonitor spyOnWithObjCreation: [oc overridden_includes: 5000]. > > > > ... > > OBJECT CREATION REPORT > > > > tally class of created object > > ------ -------------------------------------- > > > > 1002 ComplexBlock > > 1000 instances created by ComplexBlock >> value: > > ----------------------------- > > > > 2 Array > > 2 instances created by Collection >> do: > > ----------------------------- > > > > 1 VariableContext > > ----------------------------- > > > > > > | oc | > > oc := (1 to: 1000) asOrderedCollection. > > AdvancedProfMonitor spyOnWithObjCreation: [oc includes: 5000]. > > > > OBJECT CREATION REPORT > > > > tally class of created object > > ------ -------------------------------------- > > > > 2 GsMethodDictionary > > 2 instances created by Collection >> includes: > > ----------------------------- > > > > 1 ComplexBlock > > ----------------------------- > > > > This shows relative performance: > > > > | oc t1 t2 | > > oc := (1 to: 1000) asOrderedCollection. > > t1 := System _timeGmtFloat. > > 5000 timesRepeat: [oc overridden_includes: 5000]. > > t1 := (t2 := System _timeGmtFloat) - t1. > > 5000 timesRepeat: [oc includes: 5000]. > > t2 := System _timeGmtFloat - t2. > > Array with: t1 with: t2 with: (1 - (t2 / t1) * -100.0) > > > > anArray( 2.2144579887390137E+00, 1.1899878978729248E+00, -4.6262791891999555E+01) > > anArray( 2.1812989711761475E+00, 1.1948599815368652E+00, -4.5222548704884701E+01) > > anArray( 2.0989649295806885E+00, 1.1740782260894775E+00, -4.4063942682261782E+01) > > > > The execution time for the new #includes: is 44-46% less than the original #includes:. The difference is due to the original #including: creating 1000 instances of ComplexBlock for each execution. > > > > Paul Baumann > > > > > > > > > > -----Original Message----- > > From: stephane ducasse [mailto:[hidden email]] > > Sent: Friday, March 23, 2012 10:54 > > To: Paul Baumann > > Cc: Eliot Miranda; Reinout Heeck; [hidden email] > > Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of BlockClosure>>once (in Assets) > > > > Hi paul > > > > I'm reading your slide and I do not understand > > > > The cost > > > > if an OrderedCollectoin contains 1000 items #includes: anObject can have the cost of creating 1001 block closure objects > > > > Can you explain what you mean? > > > > Stef > > > > > > > > On Mar 23, 2012, at 3:12 PM, Paul Baumann wrote: > > > >> It sounds similar to a technique I use in GS/S code to turn ComplexBlocks into SimpleBlocks (different terminology from VW, but same idea). The "Efficient GemStone Enumeration" framework has been enhanced and simplified (http://techsupport.gemstone.com/entries/175923-efficient-gemstone-enumeration-2-1-002-0). Sorry I haven't shared the updated version yet. One of the neat things about the new version is that it is extended to optimize blocks for enumeration. It effectively recompiles blocks to pass context into simpler blocks through extended arguments rather than having a block closure reference external context. The optimized blocks are cached for reuse. Amazing gains are achieved in GS by using SimpleBlocks instead of ComplexBlocks. The framework I mentioned makes it possible to write application code to use simple blocks but it is still up to a developer to revise code to use the simple blocks. Developers get it wrong. They sometimes go through a lot of effort to re! > >> > >> Collection>>including: including1 including: including2 > >> collect: threeArgBlock > >> "Extension of GS_CollectionPerformanceBase. plb 2011.06.27" > >> > >> | results optimizedBlock | > >> optimizedBlock := threeArgBlock forEnumerating: self. > >> results := self _newCollectResultForBlock: optimizedBlock. > >> self > >> _into: results > >> elective: including1 > >> elective: including2 > >> elective: nil > >> elective: nil > >> keyedCollect: optimizedBlock. > >> self _finishedCollect: optimizedBlock > >> started: 0 > >> results: results. > >> ^results > >> > >> This framework is for GS/S; however, the same performance gains can be obtained in other dialects. > >> > >> Paul Baumann > >> > >> > >> > >> From: [hidden email] [mailto:[hidden email]] On Behalf Of Eliot Miranda > >> Sent: Thursday, March 22, 2012 18:02 > >> To: Reinout Heeck > >> Cc: [hidden email] > >> Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of BlockClosure>>once (in Assets) > >> > >> > >> > >> On Thu, Mar 22, 2012 at 10:13 AM, Reinout Heeck <[hidden email]> wrote: > >> Trying to atone for that foot in my mouth, I concocted a sketch for fixing #once. > >> > >> Clever! And that suggests a simple implementation for Squeak. Methods can maintain a map in a their properties/pragmas/method tags to map closure initial pc to cached value. Thanks!! > >> > >> Please find attached a workspace snippet that will alter the system without immediately crashing it. > >> When evaluating the script it will complain about undeclared names, simply hit 'leave undeclared'. > >> > >> > >> This implementation delegates the caching and becoming to the CompiledBlock instances instead of the BlockClosure instances that the original used. It should now work for both clean and copying blocks. > >> The simple test Steven Kelly supplied below should now yield true in both cases. > >> > >> This code has hardly been tested, its just a sketch and needs some cleanup (and it is developed on 771 FTW). > >> > >> In both the original and new versions I miss the flushing of the VM (JIT) caches, > >> could someone here with knowledge about the JIT review this apparent omission? > >> > >> > >> > >> On 3/21/2012 1:32 PM, Steven Kelly wrote: > >> Object class>>onceClean > >> "self onceClean == self onceClean" "true" > >> ^[Object new] once > >> > >> Object class>>onceUnclean > >> "self onceUnclean == self onceUnclean" "false" > >> ^[self new] once > >> > >> Enjoy, Reinout > >> > >> > >> _______________________________________________ > >> vwnc mailing list > >> [hidden email] > >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc > >> > >> > >> > >> > >> -- > >> best, > >> Eliot > >> > >> > >> This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. > >> _______________________________________________ > >> vwnc mailing list > >> [hidden email] > >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc > > > > > > > > This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. > > > > > > > -- > best, > Eliot > _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
As you rightly say, just having an argument doesn't make a block
unclean. But in these cases there is more extra information than just an argument. [1 yourself] "clean block" [:a | a yourself] "clean block" [self yourself] "unclean block" Steve > -----Original Message----- > From: [hidden email] [mailto:[hidden email]] On > Behalf Of stephane ducasse > Sent: 23. maaliskuuta 2012 23:47 > To: Eliot Miranda > Cc: [hidden email] > Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of > BlockClosure>>once(in Assets) > > I know what is a free variable and closing over. I explained it in > lecture (fun args and all the rest). No need to explain that to me. > > My point is why does the system creates 1000 instance of closures when > iterating on a 1000 element collection? > why there is not one closure associated to the method and applied with > different arguments? Where the semantics says that each iteration step > should > create a new one? > > This was my original question and the answer of paul did not make that > clear. > > Stef > > > > > > > > On Fri, Mar 23, 2012 at 8:53 AM, stephane ducasse > <[hidden email]> wrote: > > Paul > > > > coming from lisp where closures are objects, I wonder if the answer > to my question is due to the fact that in Smalltalk are not objects > > so the byte code interpretation as to create a block objects out of > sequence of byte code in addition to its activation. > > > > Why are closures in Lisp objects and closures in Smalltalk not > objects? (IMO they are objects in Smalltalk and presumably only > objects in CLOS or another OO Lisp, not in pure lisp. In fact, Travis' > once implementation is extremely OO, using a subclass of BlockCLosure > (CachedBlockClosure?)). The issue is not whether a closure is an > object or not, the issue is what constitutes the closure. If the > closure closes-over things that are available at compile-time (i.e. has > no free variables) then the implementation is free to create the > closure at run-time. If the closure closes-over things that are > available only when the closure is mentioned then the closure must be > created when it is mentioned, and hence the closure must be created by > combining closed-over variables and code into a newly created closure. > So I don't understand your point. Is it that the closure's method > isn't a separate object or what? > > > > > > cheers, > > Eliot > > > > > > Stef > > > > On Mar 23, 2012, at 4:40 PM, Paul Baumann wrote: > > > > > The return from within the closure to #do: of > makes it complex. The reference to anObject also prevents the closure > from being a SimpleBlock. #includes: enumerates all the values until it > finds a match. Each time the closure is used it will have a cost > related to noting context. > > > > > > Use GS/S profiling tools to see the instance creation cost. You > have to use (or configure) the tool to see the object creation costs. I > use "AdvancedProfMonitor spyOnWithObjCreation: ..." but ProfMonitor can > likely be configured to do the same. Here is a comparison of the > original #includes: (renamed #overridden_includes:) and the tuned one: > > > > > > | oc | > > > oc := (1 to: 1000) asOrderedCollection. > > > AdvancedProfMonitor spyOnWithObjCreation: [oc overridden_includes: > 5000]. > > > > > > ... > > > OBJECT CREATION REPORT > > > > > > tally class of created object > > > ------ -------------------------------------- > > > > > > 1002 ComplexBlock > > > 1000 instances created by ComplexBlock >> value: > > > ----------------------------- > > > > > > 2 Array > > > 2 instances created by Collection >> do: > > > ----------------------------- > > > > > > 1 VariableContext > > > ----------------------------- > > > > > > > > > | oc | > > > oc := (1 to: 1000) asOrderedCollection. > > > AdvancedProfMonitor spyOnWithObjCreation: [oc includes: 5000]. > > > > > > OBJECT CREATION REPORT > > > > > > tally class of created object > > > ------ -------------------------------------- > > > > > > 2 GsMethodDictionary > > > 2 instances created by Collection >> includes: > > > ----------------------------- > > > > > > 1 ComplexBlock > > > ----------------------------- > > > > > > This shows relative performance: > > > > > > | oc t1 t2 | > > > oc := (1 to: 1000) asOrderedCollection. > > > t1 := System _timeGmtFloat. > > > 5000 timesRepeat: [oc overridden_includes: 5000]. > > > t1 := (t2 := System _timeGmtFloat) - t1. > > > 5000 timesRepeat: [oc includes: 5000]. > > > t2 := System _timeGmtFloat - t2. > > > Array with: t1 with: t2 with: (1 - (t2 / t1) * -100.0) > > > > > > anArray( 2.2144579887390137E+00, 1.1899878978729248E+00, - > 4.6262791891999555E+01) > > > anArray( 2.1812989711761475E+00, 1.1948599815368652E+00, - > 4.5222548704884701E+01) > > > anArray( 2.0989649295806885E+00, 1.1740782260894775E+00, - > 4.4063942682261782E+01) > > > > > > The execution time for the new #includes: is 44-46% less than the > original #includes:. The difference is due to the original #including: > creating 1000 instances of ComplexBlock for each execution. > > > > > > Paul Baumann > > > > > > > > > > > > > > > -----Original Message----- > > > From: stephane ducasse [mailto:[hidden email]] > > > Sent: Friday, March 23, 2012 10:54 > > > To: Paul Baumann > > > Cc: Eliot Miranda; Reinout Heeck; [hidden email] > > > Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of > BlockClosure>>once (in Assets) > > > > > > Hi paul > > > > > > I'm reading your slide and I do not understand > > > > > > The cost > > > > > > if an OrderedCollectoin contains 1000 items #includes: anObject > have the cost of creating 1001 block closure objects > > > > > > Can you explain what you mean? > > > > > > Stef > > > > > > > > > > > > On Mar 23, 2012, at 3:12 PM, Paul Baumann wrote: > > > > > >> It sounds similar to a technique I use in GS/S code to turn > ComplexBlocks into SimpleBlocks (different terminology from VW, but > same idea). The "Efficient GemStone Enumeration" framework has been > enhanced and simplified > (http://techsupport.gemstone.com/entries/175923-efficient-gemstone- > enumeration-2-1-002-0). Sorry I haven't shared the updated version > One of the neat things about the new version is that it is extended to > optimize blocks for enumeration. It effectively recompiles blocks to > pass context into simpler blocks through extended arguments rather than > having a block closure reference external context. The optimized blocks > are cached for reuse. Amazing gains are achieved in GS by using > SimpleBlocks instead of ComplexBlocks. The framework I mentioned makes > it possible to write application code to use simple blocks but it is > still up to a developer to revise code to use the simple blocks. > Developers get it wrong. They sometimes go through a lot of effort to > re! > factor code but make a mistake in the optimization that makes all that > work moot. This automatic optimization eliminates those mistakes and > existing code can become much faster without having to tune application > code. > > >> > > >> Collection>>including: including1 including: including2 > > >> collect: threeArgBlock > > >> "Extension of GS_CollectionPerformanceBase. plb > 2011.06.27" > > >> > > >> | results optimizedBlock | > > >> optimizedBlock := threeArgBlock forEnumerating: > self. > > >> results := self _newCollectResultForBlock: > optimizedBlock. > > >> self > > >> _into: results > > >> elective: including1 > > >> elective: including2 > > >> elective: nil > > >> elective: nil > > >> keyedCollect: optimizedBlock. > > >> self _finishedCollect: optimizedBlock > > >> started: 0 > > >> results: results. > > >> ^results > > >> > > >> This framework is for GS/S; however, the same performance gains > can be obtained in other dialects. > > >> > > >> Paul Baumann > > >> > > >> > > >> > > >> From: [hidden email] [mailto:[hidden email]] > On Behalf Of Eliot Miranda > > >> Sent: Thursday, March 22, 2012 18:02 > > >> To: Reinout Heeck > > >> Cc: [hidden email] > > >> Subject: Re: [vwnc] [vw7.7] Perhaps unknown limitation of > BlockClosure>>once (in Assets) > > >> > > >> > > >> > > >> On Thu, Mar 22, 2012 at 10:13 AM, Reinout Heeck > <[hidden email]> wrote: > > >> Trying to atone for that foot in my mouth, I concocted a sketch > for fixing #once. > > >> > > >> Clever! And that suggests a simple implementation for Squeak. > Methods can maintain a map in a their properties/pragmas/method tags > map closure initial pc to cached value. Thanks!! > > >> > > >> Please find attached a workspace snippet that will alter the > system without immediately crashing it. > > >> When evaluating the script it will complain about undeclared names, > simply hit 'leave undeclared'. > > >> > > >> > > >> This implementation delegates the caching and becoming to the > CompiledBlock instances instead of the BlockClosure instances that the > original used. It should now work for both clean and copying blocks. > > >> The simple test Steven Kelly supplied below should now yield true > in both cases. > > >> > > >> This code has hardly been tested, its just a sketch and needs > cleanup (and it is developed on 771 FTW). > > >> > > >> In both the original and new versions I miss the flushing of the > VM (JIT) caches, > > >> could someone here with knowledge about the JIT review this > apparent omission? > > >> > > >> > > >> > > >> On 3/21/2012 1:32 PM, Steven Kelly wrote: > > >> Object class>>onceClean > > >> "self onceClean == self onceClean" "true" > > >> ^[Object new] once > > >> > > >> Object class>>onceUnclean > > >> "self onceUnclean == self onceUnclean" "false" > > >> ^[self new] once > > >> > > >> Enjoy, Reinout > > >> > > >> > > >> _______________________________________________ > > >> vwnc mailing list > > >> [hidden email] > > >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc > > >> > > >> > > >> > > >> > > >> -- > > >> best, > > >> Eliot > > >> > > >> > > >> This message may contain confidential information and is intended > for specific recipients unless explicitly noted otherwise. If you have > reason to believe you are not an intended recipient of this message, > please delete it and notify the sender. This message may not represent > the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries > or affiliates, and does not constitute a contract or guarantee. > Unencrypted electronic mail is not secure and the recipient of this > message is expected to provide safeguards from viruses and pursue > alternate means of communication where privacy or a binding message is > desired. > > >> _______________________________________________ > > >> vwnc mailing list > > >> [hidden email] > > >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc > > > > > > > > > > > > This message may contain confidential information and is intended > for specific recipients unless explicitly noted otherwise. If you have > reason to believe you are not an intended recipient of this message, > please delete it and notify the sender. This message may not represent > the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries > or affiliates, and does not constitute a contract or guarantee. > Unencrypted electronic mail is not secure and the recipient of this > message is expected to provide safeguards from viruses and pursue > alternate means of communication where privacy or a binding message is > desired. > > > > > > > > > > > > > -- > > best, > > Eliot > > > > > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by stephane ducasse-2
On Fri, Mar 23, 2012 at 2:46 PM, stephane ducasse <[hidden email]> wrote: I know what is a free variable and closing over. I explained it in lecture (fun args and all the rest). No need to explain that to me. It doesn't necessarily. In (1 to: n) do: [:i| ...]
there is only one closure. If the question is why in (1 to: n) do: [:i| (1 to: m) do: [:j| ...] ] where the inner block doesn't close over i is another closure created, the answer is because the compiler is simple (both the VW compiler and the Squeak compiler).
why there is not one closure associated to the method and applied with different arguments? Where the semantics says that each iteration step should The above answer applies here too.
best, Eliot _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
>>On Fri, Mar 23, 2012 at 2:46 PM, stephane ducasse <[hidden email]> wrote: > My point is why does the system creates 1000 instance of closures when
> iterating on a 1000 element collection? > why there is not one closure associated to the method and applied with
> different arguments? Where the semantics says that each iteration step
> should create a new one? That is a question for a VM guy, preferably a GS one. You'll find the costs I showed in GS/S are also in VW. VW performance changed by the same percentage as
GS/S had. The GS/S profiling tools simply didn't hide the cost. I think the block determines/closes context at the method it is being evaluated. Most blocks that are passed as message arguments are not evaluated; therefore,
it could be a design choice (for general efficiency) to determine context as necessary (at the last moment). The trick I used was to pro-actively determine context before a block is used to enumerate a collection so that context doesn't need to be determined
many times during the enumeration. I created an object that holds context that is passed through modified code. A variation of that trick would be to use a block that would do the "last moment" resolution but caches and reuses the context until execution
leaves where the block originated. The approach I implemented was easiest because it didn't have to mess with the VM, block, or process implementation. It is possible to use an implementation that relies contextual caching/flushing. Such an approach would
save some of the costs that my implementation has, but the other approach would be trickier and the performance advantage is not certain. > No need to explain that to me. Good. We are talking about tuning at a level that most do not know about. The explanation was hopefully for the benefit of others that may be following this discussion. I'm explaining my understanding from personal experience; that means
that I need to be clear in explanation to offset any of my misuse to commonly accepted lingo. If I don't give a good explanation then someone comes along with a "that is just the ephemeralJitterbugSnuffAndPuff approach" and people go away thinking this is
nothing to get interested in (sometimes while they're busy trying to turn the idea into the next new buzz word). Paul Baumann This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired. _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
Free forum by Nabble | Edit this page |