I work in HPC myself (mostly using Fortran). I liked your slides very much. 
However I have a few a few questions. For now, I'll focus on the one that 
puzzles me the most.

Am I misunderstanding the purpose of your ArrayObj type? It seems to me your 
implementation of macro indexArray*(x: ArrayObj{call}, y: ArrayIndex): untyped 
is little inflexible. After all, not every function returning an ArrayObj will 
be just doing element-wise calculations (or should it?)... I guess that's a 
good time for using procedure-modifying macros which would add them to some 
compile-time collection and then indexArray will choose the right 
transformation based on data in the collection (also at compile-time). Also, 
some special cases could be done easier this way. For example, let's consider 
the difference between element-wise addition and multiplication and circular 
shifting:
    
    
    proc `+`*(x: ArrayObj, y: ArrayObj): ArrayObj {.elemental.}
    proc `*`*(x: ArrayObj, y: ArrayObj): ArrayObj {.elemental.}
    
    # (x + y * z)[i]  -->  x[i] + y[i] * z[i]
    
    
    replace:
      proc rshift*(x: ArrayObj, shift: int): ArrayObj = ...
      
      proc opt(x: ArrayObj, shift: int, i: SomeInteger) =
       if shift + i < x.len:
         x[shift + i - x.len]
       else:
         x[shift + i]
      
      proc opt(x: ArrayObj, shift: static[int], i: static[SomeInteger]) =
        when shift + i < x.len:
          x[shift + i - x.len]
        else:
          x[shift + i]
      
      ...
    
    # if x.len == 10:
    #   x.cshift(2)[5]  -->  x[6]
    #   x.cshift(2)[9]  -->  x[1]
    
    

Actually, macro elemental is quite simple. Unless we would like it to use 
vectorization or other additional optimizations, of course.

Reply via email to