The following code is a very preliminary attempt at developing an autodiff 
library in Nim (at least for now, mainly to learn about Nim's powerful template 
and also possibly macro constructs).
    
    
    type AddOp = object
    type SubOp = object
    type MulOp = object
    type DivOp = object
    
    type
      
      DualExpr = concept x
        isDual(x)
      
      Operator = concept x
        isOp(x)
      
      Dual[T] = object
        val: T
        grad: T
      
      DualUnaryExpr[Op: Operator, X: DualExpr] = object
        x: X
      
      DualBinaryExpr[Op: Operator, L, R: DualExpr] = object
        l: L
        r: R
    
    type dual = Dual[float]
    
    template isDual[T](x: T): bool = false
    template isDual[T](x: Dual[T]): bool = true
    template isDual[Op, X](x: DualUnaryExpr[Op, X]): bool = true
    template isDual[Op, L, R](x: DualBinaryExpr[Op, L, R]): bool = true
    
    template isOp[T](x: T): bool = false
    template isOp(x: AddOp): bool = true
    template isOp(x: SubOp): bool = true
    template isOp(x: MulOp): bool = true
    template isOp(x: DivOp): bool = true
    
    
    template `+`[L, R](l: L, r: R) =
      DualBinaryExpr[AddOp, L, R](l: l, r: r)
    
    
    var x = dual(val: 1.0, grad: 1.0)
    var y = dual(val: 2.0, grad: 0.0)
    var z = x + y
    
    echo isDual(1.0)
    echo isDual(x)
    echo isDual(y)
    echo isDual(z)
    
    
    
    Run

I get the following output 
([https://play.nim-lang.org/#ix=1TVX)](https://play.nim-lang.org/#ix=1TVX\)):
    
    
    Hint: used config file '/nim/config/nim.cfg' [Conf]
    Hint: system [Processing]
    Hint: widestrs [Processing]
    Hint: io [Processing]
    Hint: in [Processing]
    /usercode/in.nim(45, 11) template/generic instantiation of `+` from here
    /usercode/in.nim(40, 32) Error: undeclared field: 'x'
    
    
    Run

What am I missing here?

I want eventually to be able to make autodiff computations such that an 
expression tree is created at compile time, and the assignment operator 
consumes this expression tree in an optimal way (e.g., avoiding temporaries, 
optimizing the mathematical operations, etc.).

Reply via email to