プログラム断片(2009/03/29)
for VisualWorks 7.6 with Jun776
| anInteger aFraction aFixedPoint aFloat aDouble aPoint aCollection |
anInteger := 123.
aFraction := 4 / 5.
aFixedPoint := 4.5s.
aFloat := 6.7.
aDouble := 8.9d.
aPoint := 10 @ 20.
aCollection := (OrderedCollection new)
add: anInteger;
add: aFraction;
add: aFixedPoint;
add: aFloat;
add: aDouble;
add: aPoint;
yourself.
aCollection inspect.
^aCollection
 |
1: 整数
2: 分数
3: 固定小数点数
4: 単精度浮動小数点数
5: 倍精度浮動小数点数
6: 座標
|
|
| anInteger aFraction aFixedPoint aFloat aDouble aPoint aCollection aStream aModel |
anInteger := 123.
aFraction := 4 / 5.
aFixedPoint := 4.5s.
aFloat := 6.7.
aDouble := 8.9d.
aPoint := 10 @ 20.
aCollection := (OrderedCollection new)
add: anInteger;
add: aFraction;
add: aFixedPoint;
add: aFloat;
add: aDouble;
add: aPoint;
yourself.
aStream := String new writeStream.
[aCollection
do:
[:x |
| aValue aPosition |
aValue := x.
aPosition := aStream position.
aStream nextPutAll: x printString.
8 - (aStream position - aPosition) timesRepeat: [aStream space].
aStream
nextPutAll: ': ';
nextPutAll: aValue class printString.
(aValue isKindOf: Point)
ifTrue:
[aStream
nextPutAll: '(';
nextPutAll: aValue x class printString;
nextPutAll: '@';
nextPutAll: aValue y class printString;
nextPutAll: ')'].
aStream cr]]
ensure:
[aModel := ValueHolder with: aStream contents.
aStream close].
TextEditorView
open: aModel
label: 'Numerical Objects using Smalltalk'
icon: (Icon constantNamed: #workspace)
extent: 400 @ 150.
(aModel dependents detect: [:each | each isKindOf: TextEditorView])
controller
selectFrom: 1
to: aModel value size.
^aModel
 |
SmallInteger : 小さな整数
Fraction : 分数
FixedPoint : 固定小数点数
Float : 単精度浮動小数点数
Double : 倍精度浮動小数点数
Point : 座標(小さな整数@小さな整数)
|
|
数値計算(型を気にしないで総当たりで計算してみよう)
| anInteger aFraction aFixedPoint aFloat aDouble aPoint aCollection aSelector aStream aModel |
anInteger := 123.
aFraction := 4 / 5.
aFixedPoint := 4.5s.
aFloat := 6.7.
aDouble := 8.9d.
aPoint := 10 @ 20.
aCollection := (OrderedCollection new)
add: anInteger;
add: aFraction;
add: aFixedPoint;
add: aFloat;
add: aDouble;
add: aPoint;
yourself.
aSelector := #+.
aStream := String new writeStream.
[aCollection
do:
[:x |
aCollection
do:
[:y |
| aValue aPosition |
aValue := x perform: aSelector with: y.
aPosition := aStream position.
aStream
nextPutAll: '(';
nextPutAll: x printString;
nextPutAll: ')'.
8 - (aStream position - aPosition) timesRepeat: [aStream space].
aStream
nextPutAll: aSelector asString;
nextPutAll: ' (';
nextPutAll: y printString;
nextPutAll: ')'.
20 - (aStream position - aPosition) timesRepeat: [aStream space].
aStream
nextPutAll: '==> (';
nextPutAll: aValue printString;
nextPutAll: ')'.
45 - (aStream position - aPosition) timesRepeat: [aStream space].
aStream
nextPutAll: ': ';
nextPutAll: aValue class printString.
(aValue isKindOf: Point)
ifTrue:
[aStream
nextPutAll: '(';
nextPutAll: aValue x class printString;
nextPutAll: '@';
nextPutAll: aValue y class printString;
nextPutAll: ')'].
aStream cr]]
separatedBy: [aStream cr]]
ensure:
[aModel := ValueHolder with: aStream contents.
aStream close].
TextEditorView
open: aModel
label: 'Numerical Computations using Smalltalk'
icon: (Icon constantNamed: #workspace)
extent: 650 @ 600.
(aModel dependents detect: [:each | each isKindOf: TextEditorView])
controller
selectFrom: 1
to: aModel value size.
^aModel
 |
加算の場合を調べてみると…
|
小さな整数+小さな整数 →小さな整数
小さな整数+分数 →分数
小さな整数+固定小数点数 →固定小数点数
小さな整数+単精度浮動小数点数 →単精度浮動小数点数
小さな整数+倍精度浮動小数点数 →倍精度浮動小数点数
小さな整数+座標(小さな整数@小さな整数) →座標(小さな整数@小さな整数)
分数+小さな整数 →分数
分数+分数 →分数
分数+固定小数点数 →固定小数点数
分数+単精度浮動小数点数 →単精度浮動小数点数
分数+倍精度浮動小数点数 →倍精度浮動小数点数
分数+座標(小さな整数@小さな整数) →座標(分数@分数)
固定小数点数+小さな整数 →固定小数点数
固定小数点数+分数 →固定小数点数
固定小数点数+固定小数点数 →固定小数点数
固定小数点数+単精度浮動小数点数 →単精度浮動小数点数
固定小数点数+倍精度浮動小数点数 →倍精度浮動小数点数
固定小数点数+座標(小さな整数@小さな整数) →座標(固定小数点数@固定小数点数)
単精度浮動小数点数+小さな整数 →単精度浮動小数点数
単精度浮動小数点数+分数 →単精度浮動小数点数
単精度浮動小数点数+固定小数点数 →単精度浮動小数点数
単精度浮動小数点数+単精度浮動小数点数 →単精度浮動小数点数
単精度浮動小数点数+倍精度浮動小数点数 →倍精度浮動小数点数
単精度浮動小数点数+座標(小さな整数@小さな整数) →座標(単精度浮動小数点数@単精度浮動小数点数)
倍精度浮動小数点数+小さな整数 →倍精度浮動小数点数
倍精度浮動小数点数+分数 →倍精度浮動小数点数
倍精度浮動小数点数+固定小数点数 →倍精度浮動小数点数
倍精度浮動小数点数+単精度浮動小数点数 →倍精度浮動小数点数
倍精度浮動小数点数+倍精度浮動小数点数 →倍精度浮動小数点数
倍精度浮動小数点数+座標(小さな整数@小さな整数) →座標(倍精度浮動小数点数@倍精度浮動小数点数)
座標(小さな整数@小さな整数)+小さな整数 →座標(小さな整数@小さな整数)
座標(小さな整数@小さな整数)+分数 →座標(分数@分数)
座標(小さな整数@小さな整数)+固定小数点数 →座標(固定小数点数@固定小数点数)
座標(小さな整数@小さな整数)+単精度浮動小数点数 →座標(単精度浮動小数点数@単精度浮動小数点数)
座標(小さな整数@小さな整数)+倍精度浮動小数点数 →座標(倍精度浮動小数点数@倍精度浮動小数点数)
座標(小さな整数@小さな整数)+座標(小さな整数@小さな整数)→座標(小さな整数@小さな整数)
|
|
| messageSelector methodDefinitions |
messageSelector := #+.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
Refactory.Browser.RefactoringBrowser
openListBrowserOn: methodDefinitions
label: 'Implementors of ' , messageSelector printString
initialSelection: messageSelector.
^methodDefinitions
 |
レシーバと引数の型が合わずにプリミティブメソッドが失敗すると…
|
|
| messageSelector methodDefinitions |
messageSelector := #sumFromInteger:.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
Refactory.Browser.RefactoringBrowser
openListBrowserOn: methodDefinitions
label: 'Implementors of ' , messageSelector printString
initialSelection: messageSelector.
^methodDefinitions
 |
ダブルディスパッチングで型強制して再試行を…
|
|
| messageSelector methodDefinitions |
messageSelector := #retry:coercing:.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
Refactory.Browser.RefactoringBrowser
openListBrowserOn: methodDefinitions
label: 'Implementors of ' , messageSelector printString
initialSelection: messageSelector.
^methodDefinitions
 |
generalityがキーポイント!
数オブジェクトとして一般性が大きい方へと型強制を行い…
|
|
| messageSelector methodDefinitions |
messageSelector := #generality.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
Refactory.Browser.RefactoringBrowser
openListBrowserOn: methodDefinitions
label: 'Implementors of ' , messageSelector printString
initialSelection: messageSelector.
^methodDefinitions
 |
generalityを実装しているのは誰だろう…
なんだか妙な数値(整数)を答えている…
|
|
| messageSelector methodDefinitions generalityTable aStream aModel |
messageSelector := #generality.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
generalityTable := Dictionary new.
methodDefinitions
do:
[:methodDefinition |
| aClass |
aClass := methodDefinition implementingClass.
aClass isMeta
ifFalse:
[[| aValue |
aValue := aClass perform: messageSelector.
generalityTable
at: aValue
ifAbsentPut: [OrderedCollection new].
(generalityTable at: aValue) add: aClass]
on: Object errorSignal
do: [:exception | exception return]]].
aStream := String new writeStream.
[generalityTable associations asSortedCollection
do:
[:association |
aStream
nextPutAll: association key printString;
nextPutAll: ' ('.
association value
do: [:aClass | aStream nextPutAll: aClass printString]
separatedBy: [aStream space].
aStream
nextPutAll: ')';
cr;
flush]]
ensure:
[aModel := ValueHolder with: aStream contents.
aStream close].
TextEditorView
open: aModel
label: 'Implementors of ' , messageSelector printString
icon: (Icon constantNamed: #workspace)
extent: 350 @ 220.
(aModel dependents detect: [:each | each isKindOf: TextEditorView])
controller
selectFrom: 1
to: aModel value size.
^generalityTable
 |
一般性の正体は数値(整数)…
大きくなるほど一般性が高い…
あれ!SmallDoubleの89が出ていない…
|
|
| messageSelector methodDefinitions generalityTable aStream aModel |
messageSelector := #generality.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
generalityTable := Dictionary new.
methodDefinitions
do:
[:methodDefinition |
| aClass |
aClass := methodDefinition implementingClass.
aClass isMeta
ifFalse:
[[| aMethod aValue |
aMethod := aClass compiledMethodAt: messageSelector.
aValue := ((JunProgramScanner method: aMethod) literalNodes
detect: [:each | each value isKindOf: Integer]) value.
generalityTable
at: aValue
ifAbsentPut: [OrderedCollection new].
(generalityTable at: aValue) add: aClass]
on: Object errorSignal
do: [:exception | exception return]]].
aStream := String new writeStream.
[generalityTable associations asSortedCollection
do:
[:association |
aStream
nextPutAll: association key printString;
nextPutAll: ' ('.
association value
do: [:aClass | aStream nextPutAll: aClass printString]
separatedBy: [aStream space].
aStream
nextPutAll: ')';
cr;
flush]]
ensure:
[aModel := ValueHolder with: aStream contents.
aStream close].
TextEditorView
open: aModel
label: 'Implementors of ' , messageSelector printString
icon: (Icon constantNamed: #workspace)
extent: 350 @ 220.
(aModel dependents detect: [:each | each isKindOf: TextEditorView])
controller
selectFrom: 1
to: aModel value size.
^generalityTable
 |
構文解析をして一般性の値(整数)を取り出して…
ちゃんとSmallDoubleの89も出ました!
|
|
for VisualWorks 7.6 with Jun776
Updated: 2015/11/08 (Created: 2009/03/29)
