プログラム断片(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
01
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
02-1
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
03
加算の場合を調べてみると…
小さな整数+小さな整数                    →小さな整数
小さな整数+分数                       →分数
小さな整数+固定小数点数                   →固定小数点数
小さな整数+単精度浮動小数点数                →単精度浮動小数点数
小さな整数+倍精度浮動小数点数                →倍精度浮動小数点数
小さな整数+座標(小さな整数@小さな整数)          →座標(小さな整数@小さな整数)

分数+小さな整数                       →分数
分数+分数                          →分数
分数+固定小数点数                      →固定小数点数
分数+単精度浮動小数点数                   →単精度浮動小数点数
分数+倍精度浮動小数点数                   →倍精度浮動小数点数
分数+座標(小さな整数@小さな整数)             →座標(分数@分数)

固定小数点数+小さな整数                   →固定小数点数
固定小数点数+分数                      →固定小数点数
固定小数点数+固定小数点数                  →固定小数点数
固定小数点数+単精度浮動小数点数               →単精度浮動小数点数
固定小数点数+倍精度浮動小数点数               →倍精度浮動小数点数
固定小数点数+座標(小さな整数@小さな整数)         →座標(固定小数点数@固定小数点数)

単精度浮動小数点数+小さな整数                →単精度浮動小数点数
単精度浮動小数点数+分数                   →単精度浮動小数点数
単精度浮動小数点数+固定小数点数               →単精度浮動小数点数
単精度浮動小数点数+単精度浮動小数点数            →単精度浮動小数点数
単精度浮動小数点数+倍精度浮動小数点数            →倍精度浮動小数点数
単精度浮動小数点数+座標(小さな整数@小さな整数)      →座標(単精度浮動小数点数@単精度浮動小数点数)

倍精度浮動小数点数+小さな整数                →倍精度浮動小数点数
倍精度浮動小数点数+分数                   →倍精度浮動小数点数
倍精度浮動小数点数+固定小数点数               →倍精度浮動小数点数
倍精度浮動小数点数+単精度浮動小数点数            →倍精度浮動小数点数
倍精度浮動小数点数+倍精度浮動小数点数            →倍精度浮動小数点数
倍精度浮動小数点数+座標(小さな整数@小さな整数)      →座標(倍精度浮動小数点数@倍精度浮動小数点数)

座標(小さな整数@小さな整数)+小さな整数          →座標(小さな整数@小さな整数)
座標(小さな整数@小さな整数)+分数             →座標(分数@分数)
座標(小さな整数@小さな整数)+固定小数点数         →座標(固定小数点数@固定小数点数)
座標(小さな整数@小さな整数)+単精度浮動小数点数      →座標(単精度浮動小数点数@単精度浮動小数点数)
座標(小さな整数@小さな整数)+倍精度浮動小数点数      →座標(倍精度浮動小数点数@倍精度浮動小数点数)
座標(小さな整数@小さな整数)+座標(小さな整数@小さな整数)→座標(小さな整数@小さな整数)

重送信(なぜ型を気にしないで済むのだろう)

| messageSelector methodDefinitions |
messageSelector := #+.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
Refactory.Browser.RefactoringBrowser
    openListBrowserOn: methodDefinitions
    label: 'Implementors of ' , messageSelector printString
    initialSelection: messageSelector.
^methodDefinitions
07
レシーバと引数の型が合わずにプリミティブメソッドが失敗すると…
| messageSelector methodDefinitions |
messageSelector := #sumFromInteger:.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
Refactory.Browser.RefactoringBrowser
    openListBrowserOn: methodDefinitions
    label: 'Implementors of ' , messageSelector printString
    initialSelection: messageSelector.
^methodDefinitions
08
ダブルディスパッチングで型強制して再試行を…
| messageSelector methodDefinitions |
messageSelector := #retry:coercing:.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
Refactory.Browser.RefactoringBrowser
    openListBrowserOn: methodDefinitions
    label: 'Implementors of ' , messageSelector printString
    initialSelection: messageSelector.
^methodDefinitions
09
generalityがキーポイント!
数オブジェクトとして一般性が大きい方へと型強制を行い…

一般性(generality)

| messageSelector methodDefinitions |
messageSelector := #generality.
methodDefinitions := MethodCollector new allImplementorsOf: messageSelector.
Refactory.Browser.RefactoringBrowser
    openListBrowserOn: methodDefinitions
    label: 'Implementors of ' , messageSelector printString
    initialSelection: messageSelector.
^methodDefinitions
04
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
05
一般性の正体は数値(整数)…
大きくなるほど一般性が高い…
あれ!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
06
構文解析をして一般性の値(整数)を取り出して…
ちゃんとSmallDoubleの89も出ました!

for VisualWorks 7.6 with Jun776


Updated: 2015/11/08 (Created: 2009/03/29) KSU AokiHanko