--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LazyValue.st Fri Jun 07 17:23:46 2002 +0200
@@ -0,0 +1,329 @@
+"
+ COPYRIGHT (c) 2002 by eXept Software AG
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+
+"{ Package: 'stx:libbasic2' }"
+
+nil subclass:#LazyValue
+ instanceVariableNames:'result block'
+ classVariableNames:'AccessLock'
+ poolDictionaries:''
+ category:'Kernel-Processes'
+!
+
+!LazyValue class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2002 by eXept Software AG
+ All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice. This software may not
+ be provided or otherwise made available to, or used by, any
+ other person. No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+documentation
+"
+ I represent an expression which might not be needed.
+ Any messages sent to me will force the evaluation (once).
+ The value is remembered.
+
+ Can be used to simulate non-strict programming languages.
+
+ [see also:]
+ Block Future
+
+ [author:]
+ Claus Gittinger
+"
+!
+
+examples
+"
+ listFrom:n - an infinite list of integers starting with n
+ [exBegin]
+ |gen infiniteList|
+
+ gen := [:n |
+ Cons
+ car:n
+ cdr:( LazyValue block:[gen value:n+1] )
+ ].
+
+ infiniteList := gen value:1.
+ 1 to:10 do:[:i |
+ Transcript showCR:infiniteList car.
+ infiniteList := infiniteList cdr.
+ ].
+ [exEnd]
+
+ filterOdd:l - an infinite list filtering odd numbers from another list
+ [exBegin]
+ |gen infiniteList genOdd infiniteOdd|
+
+ gen := [:n |
+ Cons
+ car:n
+ cdr:( LazyValue block:[gen value:n+1] )
+ ].
+
+ infiniteList := gen value:1.
+
+ genOdd := [:l |
+ |lR el|
+
+ lR := l.
+ [ el := lR car. lR := lR cdr. el odd ] whileFalse:[].
+ Cons
+ car:el
+ cdr:( LazyValue block:[genOdd value:lR] )
+ ].
+
+ infiniteOdd := genOdd value:infiniteList.
+
+ 1 to:10 do:[:i |
+ Transcript showCR:infiniteOdd car.
+ infiniteOdd := infiniteOdd cdr.
+ ].
+ [exEnd]
+
+ powersOf:n - an infinite list of powers of n
+ [exBegin]
+ |genPowersOf infiniteListOfPowers|
+
+ genPowersOf := [:base |
+ |powersOfBase|
+
+ powersOfBase :=
+ [:n |
+ Cons
+ car:n
+ cdr:( LazyValue block:[powersOfBase value:n*base] )
+ ].
+ powersOfBase value:1.
+ ].
+
+ infiniteListOfPowers := genPowersOf value:2.
+ 1 to:10 do:[:i |
+ Transcript showCR:infiniteListOfPowers car.
+ infiniteListOfPowers := infiniteListOfPowers cdr.
+ ].
+ [exEnd]
+
+ merge2:a _:b - merge 2 lists.
+ [exBegin]
+ |genMerge2 l gen infiniteList genOdd infiniteOdd genEven infiniteEven genMerge|
+
+ gen := [:n |
+ Cons
+ car:n
+ cdr:( LazyValue block:[gen value:n+1] )
+ ].
+
+ infiniteList := gen value:1.
+
+ genOdd := [:l |
+ |lR el|
+
+ lR := l.
+ [ el := lR car. lR := lR cdr. el odd ] whileFalse:[].
+ Cons
+ car:el
+ cdr:( LazyValue block:[genOdd value:lR] )
+ ].
+
+ infiniteOdd := genOdd value:infiniteList.
+
+ genEven := [:l |
+ |lR el|
+
+ lR := l.
+ [ el := lR car. lR := lR cdr. el even ] whileFalse:[].
+ Cons
+ car:el
+ cdr:( LazyValue block:[genEven value:lR] )
+ ].
+
+ infiniteEven := genEven value:infiniteList.
+
+ genMerge2 := [:a :b |
+ |nextA nextB|
+
+ nextA := a car.
+ nextB := b car.
+
+ nextA < nextB ifTrue:[
+ Cons
+ car:nextA
+ cdr:( LazyValue block:[genMerge2 value:(a cdr) value:b] )
+ ] ifFalse:[
+ Cons
+ car:nextB
+ cdr:( LazyValue block:[genMerge2 value:a value:(b cdr)] )
+ ].
+ ].
+
+ l := genMerge2 value:infiniteOdd value:infiniteEven.
+ 1 to:10 do:[:i |
+ Transcript showCR:l car.
+ l := l cdr.
+ ].
+ [exEnd]
+
+ genPoly - generate 2^i + 3^j + 5^k for all i,j,k
+ not finished.
+ [exBegin]
+ |genMerge2 l gen genPowersOf infiniteList powersOf2 powersOf3 powersOf5|
+
+ gen := [:n |
+ Cons
+ car:n
+ cdr:( LazyValue block:[gen value:n+1] )
+ ].
+
+ infiniteList := gen value:1.
+
+ genPowersOf := [:base |
+ |powersOfBase|
+
+ powersOfBase :=
+ [:n |
+ Cons
+ car:n
+ cdr:( LazyValue block:[powersOfBase value:n*base] )
+ ].
+ powersOfBase value:1.
+ ].
+
+ powersOf2 := genPowersOf value:2.
+ powersOf3 := genPowersOf value:3.
+ powersOf5 := genPowersOf value:5.
+
+ genAdd := [:n :l |
+ |gen|
+
+ gen := [:l |
+ Cons
+ car:(car l) * n
+ cdr:( LazyValue block:[gen value:(l cdr)] )
+ ].
+ gen value:l
+ ].
+
+ genMerge2 := [:a :b |
+ |min nextA nextB rA rB|
+
+ rA := a.
+ rB := b.
+ nextA := rA car.
+ [ (nextB := rB car) = nextA ] whileTrue:[ rB := rB cdr ].
+
+ nextA < nextB ifTrue:[
+ 'a is smallest'.
+ min := nextA.
+ rA := rA cdr.
+ ] ifFalse:[
+ 'b is smallest'.
+ min := nextB.
+ rB := rB cdr.
+ ].
+
+ Cons
+ car:min
+ cdr:( LazyValue block:[genMerge2 value:rA value:rB] )
+ ].
+
+ l := genMerge2 value:powersOf2 value:powersOf3 value:powersOf5.
+ 1 to:10 do:[:i |
+ Transcript showCR:l car.
+ l := l cdr.
+ ].
+ [exEnd]
+
+"
+! !
+
+!LazyValue class methodsFor:'initialization'!
+
+initialize
+ AccessLock := RecursionLock forMutualExclusion
+! !
+
+!LazyValue class methodsFor:'instance creation'!
+
+block:aBlock
+ ^ self new block:aBlock
+! !
+
+!LazyValue methodsFor:'error handling'!
+
+doesNotUnderstand:aMessage
+ block notNil ifTrue:[
+ self _evaluate_
+ ].
+ ^ aMessage sendTo:result
+! !
+
+!LazyValue methodsFor:'evaluation'!
+
+_evaluate_
+ block notNil ifTrue:[
+ AccessLock critical:[
+ |b|
+
+ (b := block notNil) ifTrue:[
+ block := nil.
+ result := b value.
+ ].
+ ].
+ ].
+ ^ result
+! !
+
+!LazyValue methodsFor:'printing'!
+
+printOn:aStream
+ aStream nextPutAll:'(lazy)'
+! !
+
+!LazyValue methodsFor:'private access'!
+
+block:aBlock
+ block := aBlock.
+! !
+
+!LazyValue methodsFor:'queries'!
+
+class
+ ^ self _evaluate_ class
+!
+
+isLazyValue
+ ^ block notNil
+! !
+
+!LazyValue methodsFor:'testing'!
+
+isBehavior
+ ^ self _evaluate_ isBehavior
+! !
+
+!LazyValue class methodsFor:'documentation'!
+
+version
+ ^ '$Header: /cvs/stx/stx/libbasic2/LazyValue.st,v 1.1 2002-06-07 15:23:46 cg Exp $'
+! !
+LazyValue initialize!