Python でいろいろな階乗


個人的に好きだったのは、

reduce(int.__mul__, xrange(1,11))


Squeak Smalltalk で無理矢理書くと、メソッドオブジェクト(の属するクラス、CompiledMethod)に #value:value: を

CompiledMethod >> value: arg1 value: arg2
   ^self valueWithReceiver: arg1 arguments: arg2

のように定義しておいて、

(1 to: 10) inject: 1 into: (Integer >> #*)

ということになりましょうか。


ところでメソッドオブジェクト「Integer >> #*」はシンボル「#*」さえ与えられれば他から決まるので、シンボルにしかるべく #value:value: を定義しておけば、

Symbol >> value: arg1 value: arg2 
   ^(arg1 class lookupSelector: self) value: arg1 value: arg2

これで済ませることも可能です。

(1 to: 10) inject: 1 into: #*


さらに、Smalltalk の文法の制約から引数の省略ができない #inject:into: に代えて、Ruby の #inject 初期値省略時動作を模した #inject: を別に定義しておくことで、

SequenceableCollection >> inject: binaryBlock 
   | nextValue |
   nextValue := self first.
   self allButFirst do: [:each | nextValue := binaryBlock value: nextValue value: each].
   ^nextValue


めでたく(?) Ruby 1.9 版が完成。w

(1 to: 10) inject: #*