Well your solution does work I think. It feels a bit like what Scala is doing 
in their collection library. But on the other hand Scala is on the JVM and the 
JVM is as badass that it can incline virtual methods. I think in the real world 
it really is a lot of overhead, that you do not want in your approach. I tried 
once to implement the same with just iterators, but sadly I was limited by the 
language:
    
    
    iterator filter[T](arg: iterator(): T; cond: proc(arg: T): bool): T =
      for x in arg:
        if cond(x):
          yield arg
    
    
    iterator map[T,U](arg: iterator(): T; fun: proc(arg: T): U): U =
      for x in arg:
        yield fun(x)
    
    let data = [1,2,3,4,5,6,7,8,9]
    
    for x in filter(data.items(), proc(arg: int): bool = arg mod 2 == 1)  ## 
undeclared field items, meh...
    

The language should just have some automatic feature to raise any iterator type 
to a closure iterator bundled with their arguments. Otherwise it is just meh to 
use, and I will avoid to design an API that is based on it, because it just 
feels not thought through to the end.

Something that might actually work very well, is when you write macros to 
define your own language within Nim.
    
    
    macro dataLanguage(arg: untyped): untyped =
      [...]
    
    
    dataLanguage:
      var result = myData.filter(_.name.len < 7).filter(_.age > 
30).map(_.birthday)
    

Then you would have total control on how these expressions get compiled. They 
can be reduced to a single loop. You could inject commands for memory mapping, 
and even inject commands for managing a cloud of computers over a network. It 
is certainly the most powerful solution, but also very hard to do the right 
thing. I could totally understand, when you do not want to do that. I used 
scala notation here for the macro, and that would be possible. The _ is where 
the argument is inserted.

Reply via email to