Lazy.st
author Claus Gittinger <cg@exept.de>
Sat, 18 May 1996 17:49:46 +0200
changeset 351 c7c0c33286b8
parent 67 6d8a403eff0a
child 457 c862c91716b6
permissions -rw-r--r--
showCr: -> showCR:
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
     1
"       NAME            Parallelism
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
     2
	AUTHOR          tph@cs.man.ac.uk
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
     3
	FUNCTION throttled Futures; lazy eval; explicit pa'l'l procs 
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
     4
	ST-VERSIONS     stx
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
     5
	PREREQUISITES    
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
     6
	CONFLICTS       
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
     7
	DISTRIBUTION    world
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
     8
	VERSION         1.1
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
     9
	DATE    22 Jan 1989
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    10
	SUMMARY 
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    11
Parallelism contains a number of explicitly parallel constructs,
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    12
including a new version of Future, Lazy evaluation, and explicit
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    13
parallel processes.  Lots of code in here.  Contains an early
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    14
version (read: doesn't work) of a ""throttled"" future mechanism.
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    15
New version RSN.(2.2).TPH
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    16
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    17
claus: I have separated the original Parallelism package into
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    18
       individual ones: Lazy, Future, ThrottledFuture and ParallelEvaluation
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    19
"!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    20
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    21
'From Smalltalk-80, version 2, of April 1, 1983 on 29 March 1987 at 5:13:27 pm'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    22
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    23
!Object methodsFor: 'parallel evaluation'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    24
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    25
touch
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    26
	"Simply returns self.  If the receiver is an uncompleted
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    27
	 Future or Lazy, this forces complete evaluation."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    28
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    29
	^self
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    30
! !
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    31
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    32
'From Smalltalk-80, version 2, of April 1, 1983 on 29 March 1987 at 5:09:10 pm'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    33
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    34
Object subclass: #Lazy
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    35
	instanceVariableNames: 'result startSemaphore endSemaphore '
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    36
	classVariableNames: ''
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    37
	poolDictionaries: ''
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    38
	category: 'Kernel-Processes'!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    39
Lazy comment:
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    40
'I represent an execution which may not be required.  I will
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    41
not start execution until at least one message has been
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    42
received.  The messages sent to me are delayed until execution
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    43
has completed.'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    44
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    45
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    46
!Lazy methodsFor: 'synchronising'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    47
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    48
doesNotUnderstand: aMessage
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    49
	"Any message to a Lazy will end up here."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    50
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    51
	startSemaphore signal.          "Start the evaluation."
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    52
	endSemaphore wait.              "Wait until evaluation completed."
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    53
	endSemaphore signal.            "Wake up anything else."
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    54
	^result perform: aMessage selector withArguments: aMessage arguments
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    55
		"Perform the message, having re-synchronised."! !
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    56
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    57
!Lazy methodsFor: 'evaluating'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    58
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    59
block: aBlock
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    60
	"Execute aBlock in parallel, but ensure that any messages sent
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    61
	 to me before execution of the block has terminated are
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    62
	 suspended until it has terminated. Do not start the evaluation
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    63
	 until at least one message has been sent to the receiver."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    64
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    65
	startSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    66
	endSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    67
	[startSemaphore wait.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    68
	 result := aBlock value.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    69
	 endSemaphore signal] fork!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    70
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    71
block: aBlock value: aValue
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    72
	"Execute aBlock in parallel, but ensure that any messages sent
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    73
	 to me before execution of the block has terminated are
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    74
	 suspended until it has terminated. Do not start the evaluation
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    75
	 until at least one message has been sent to the receiver."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    76
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    77
	startSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    78
	endSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    79
	[startSemaphore wait.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    80
	 result := aBlock value: aValue.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    81
	 endSemaphore signal] fork!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    82
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    83
block: aBlock value: value1 value: value2
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    84
	"Execute aBlock in parallel, but ensure that any messages sent
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    85
	 to me before execution of the block has terminated are
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    86
	 suspended until it has terminated. Do not start the evaluation
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    87
	 until at least one message has been sent to the receiver."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    88
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    89
	startSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    90
	endSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    91
	[startSemaphore wait.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    92
	 result := aBlock value: value1 value: value2.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    93
	 endSemaphore signal] fork!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    94
a759b5c72c98 Initial revision
claus
parents:
diff changeset
    95
block: aBlock value: value1 value: value2 value: value3
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    96
	"Execute aBlock in parallel, but ensure that any messages sent
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    97
	 to me before execution of the block has terminated are
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    98
	 suspended until it has terminated. Do not start the evaluation
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
    99
	 until at least one message has been sent to the receiver."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   100
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   101
	startSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   102
	endSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   103
	[startSemaphore wait.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   104
	 result := aBlock value: value1 value: value2 value: value3.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   105
	 endSemaphore signal] fork!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   106
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   107
block: aBlock valueWithArguments: anArray
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   108
	"Execute aBlock in parallel, but ensure that any messages sent
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   109
	 to me before execution of the block has terminated are
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   110
	 suspended until it has terminated. Do not start the evaluation
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   111
	 until at least one message has been sent to the receiver."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   112
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   113
	startSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   114
	endSemaphore := Semaphore new.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   115
	[startSemaphore wait.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   116
	 result := aBlock valueWithArguments: anArray.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   117
	 endSemaphore signal] fork! !
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   118
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   119
!Lazy class methodsFor: 'class initialization'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   120
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   121
initialize
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   122
	"must avoid the checks"
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   123
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   124
	superclass := nil
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   125
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   126
	"Lazy initialize."! !
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   127
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   128
!Lazy class methodsFor: 'examples'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   129
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   130
example1
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   131
	"Evaluates the factorial, starting only when the
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   132
	 result is actually required (when printString is sent)."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   133
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   134
	| fac |
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   135
	fac := [100 factorial] futureValue.
351
c7c0c33286b8 showCr: -> showCR:
Claus Gittinger <cg@exept.de>
parents: 67
diff changeset
   136
	Transcript showCR: 'Doing nothing. '.
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   137
	(Delay forSeconds: 2) wait.
351
c7c0c33286b8 showCr: -> showCR:
Claus Gittinger <cg@exept.de>
parents: 67
diff changeset
   138
	Transcript showCR: fac printString
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   139
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   140
	"Lazy example1"!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   141
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   142
example2
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   143
	"Starts evaluating both factorials only when required (by the touch),
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   144
	 and waits until both blocks have finished before continuing."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   145
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   146
	| fac1 fac2 |
351
c7c0c33286b8 showCr: -> showCR:
Claus Gittinger <cg@exept.de>
parents: 67
diff changeset
   147
	fac1 := [Transcript showCR: 'Starting fac1.. '. 100 factorial] lazyValue.
c7c0c33286b8 showCr: -> showCR:
Claus Gittinger <cg@exept.de>
parents: 67
diff changeset
   148
	fac2 := [Transcript showCR: 'Starting fac2.. '. 120 factorial] lazyValue.
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   149
	fac2 touch.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   150
	fac1 touch.
351
c7c0c33286b8 showCr: -> showCR:
Claus Gittinger <cg@exept.de>
parents: 67
diff changeset
   151
	Transcript showCR: 'both completed.'.
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   152
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   153
	"Lazy example2"!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   154
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   155
example3
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   156
	"Demonstrates how to pass arguments to a lazy evaluation block."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   157
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   158
	| temp |
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   159
	temp := [:x :y :z | x * y * z] lazyValueWithArguments: #(2 3 4).
351
c7c0c33286b8 showCr: -> showCR:
Claus Gittinger <cg@exept.de>
parents: 67
diff changeset
   160
	Transcript  showCR: temp printString.
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   161
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   162
	"Lazy example3"! !
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   163
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   164
Lazy initialize!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   165
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   166
!Block methodsFor: 'parallel evaluation'!
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   167
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   168
lazyValue
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   169
	"Fork a synchronised evaluation of myself. Only starts
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   170
	 the evaluation when the result is requested."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   171
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   172
	^Lazy new block: self!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   173
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   174
lazyValue: aValue
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   175
	"Fork a synchronised evaluation of myself. Only starts
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   176
	 the evaluation when the result is requested."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   177
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   178
	^Lazy new block: self value: aValue!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   179
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   180
lazyValue: aValue value: anotherValue
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   181
	"Fork a synchronised evaluation of myself. Only starts
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   182
	 the evaluation when the result is requested."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   183
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   184
	^Lazy new block: self value: aValue value: anotherValue!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   185
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   186
lazyValue: aValue value: anotherValue value: bValue
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   187
	"Fork a synchronised evaluation of myself. Only starts
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   188
	 the evaluation when the result is requested."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   189
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   190
	^Lazy new block: self value: aValue value: anotherValue value: bValue!
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   191
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   192
lazyValueWithArguments: anArray
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   193
	"Fork a synchronised evaluation of myself. Only starts
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   194
	 the evaluation when the result is requested."
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   195
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   196
	^Lazy new block: self valueWithArguments: anArray
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   197
! !
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   198
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   199
"COPYRIGHT.
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   200
 The above file is a Manchester Goodie protected by copyright.
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   201
 These conditions are imposed on the whole Goodie, and on any significant
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   202
 part of it which is separately transmitted or stored:
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   203
	* You must ensure that every copy includes this notice, and that
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   204
	  source and author(s) of the material are acknowledged.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   205
	* These conditions must be imposed on anyone who receives a copy.
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   206
	* The material shall not be used for commercial gain without the prior
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   207
	  written consent of the author(s).
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   208
 Further information on the copyright conditions may be obtained by
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   209
 sending electronic mail:
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   210
	To: goodies-lib@cs.man.ac.uk
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   211
	Subject: copyright
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   212
 or by writing to The Smalltalk Goodies Library Manager, Dept of
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   213
 Computer Science, The University, Manchester M13 9PL, UK
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   214
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   215
 (C) Copyright 1992 University of Manchester
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   216
 For more information about the Manchester Goodies Library (from which 
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   217
 this file was distributed) send e-mail:
67
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   218
	To: goodies-lib@cs.man.ac.uk
6d8a403eff0a *** empty log message ***
claus
parents: 62
diff changeset
   219
	Subject: help 
62
a759b5c72c98 Initial revision
claus
parents:
diff changeset
   220
"!