E言語でカウンタ

新しい言語を見つけたらカウンタを書く習性のある僕なのでカウンタ書いてみました。
つらつらと面白かった部分とか。

Eのオブジェクトと関数の関係

Eのオブジェクト(!=class)はdefで作ります。関数もdefです。。っておい、、、というか面白いのが関数が以下のようにオブジェクトに等価だったりします

def foo(val) {return val*val;}
     ||
def foo_obj {
   to run(val) {return val*val;}
}

to というのがメソッド定義です。つまりEにおける関数と言うのはrunというメソッドを持ったオブジェクトだったりする訳ですね。

? foo(10)
# value: 100

? foo_obj(10)
# value: 100

まー。

オブジェクトの構築

まあ上の方法でオブジェクトを作れるのはわかったんだけど、じゃあどうやってクラスやプロトタイプに相当するものを?? というとこれがmaker関数、つまりはコンストラクタ関数を作ってやる訳ですね。

def makeFoo() {
   # misc things...
   # other things...
   # sometimes he sings ....

   def obj {
     to method1 {...}
     to method2 {...}
   }
   return obj
}

さっきの関数=オブジェクト、という方法を使うとコンストラクタのオーバーロードができたりとか。

継承は?

extends を使ってmaker関数を呼び出します。結果は暗黙の変数superに入るのでそれを使いますとな。これはdelegateパターンですね。

def makeParent() {
  def obj {
    to greeting() {
      println("hello world!!")
    }
  }
  return obj
}

def makeChild() {
  def obj extends makeParent() {
    to introduce_myself() {
      println("I'm child")
      super.greeting()
    }
  }
  return obj
}

def parent := makeParent()
def child  := makeChild()

parent.greeting()
println("---")
child.greeting()
println("---")
child.introduce_myself()
Manta:edist tkuro$ ./rune foo.e 
hello world!!
---
hello world!!
---
I'm child
hello world!!

ちなみにあくまでもメソッドレベルのdelegateです。つことは、子に合わせてなんかするとかいう多態ができない。。。そういう場合は親のmaker関数で子のオブジェクトを引数で取る設計にすれば良いようです。

でカウンタ

てな感じでわかった事から作ってみるとこんな感じ。

def commonBehaviour(self, var init) {
    def counter {
        to next() {init+=self.step(); return self.value()}
        to value() {return init}
    }
    return counter
}

def makeCounter(init) {
    def counter extends commonBehaviour(counter, init) {
        to step() {return 1}
    }
    return counter
}

def makeStepCounter(init,step) {
    def counter extends commonBehaviour(counter, init) {
        to step() {return step}
    }
    return counter
}


def normal := makeCounter(10)

println(normal.next())
println(normal.next())
println(`${normal.next()}, ${normal.next()}`)
println(normal.value())

def step := makeStepCounter(10, 10)

println(step.next())
println(step.next())
println(`${step.next()}, ${step.next()}`)
println(step.value())
Manta:edist tkuro$ ./rune counter.e 
11
12
13, 14
14
20
30
40, 50
50

おーあっけない。

結論

まだまだ肝心な部分に到達できてません。
うーん、家事サボりたい(こら