Hi,
I'm still working on how the seqUtils library could be improved, and currently wondering about toSeq. I'm missing an operator, which binds as strongly as $. Please see the examples below. Shall I use ^ for this type of map? If not, then what else is available? Would you like to have a feature like this?
(If you like this, then we could have this for iterators as well.)
var first = @[1,2,3]
var second = @[10,20,30,40]
assert toSeq(100 + ^first) == @[101, 102, 103]
assert toSeq(^first * 2 + 1000) == @[1002, 1004, 1006]
assert toSeq(^first + ^second) == @[11, 22, 33]
assert toSeq("number: " & $^first) == @["number: 1", "number: 2", "number: 3"]
assert toSeq( (^(first & second)).f ) == @[f(1), f(2), f(3), f(10), f(20), f(30), f(40)]
Is it a good idea to consume operator for rarely used operation? If everyone did that soon it would be like c++/rust with gazillion of magic !@#$%^&* that does god knows what in different contexts. IMO proc with appropriate name would work much better.
EDIT: What you are proposing is essentially iterating over seq and doing a change. something like var new_s = map(s, proc (v: int): int = v * 2 + 2) looks much more explicit and obvious. magical ^ on the other hand once again makes one dig docs. less doc digging == better.
I see. I understand that an extra operator might cause confusion. And how about Vec? For example
assert toSeq(100 + Vec(first)) == @[101, 102, 103]
Let's see the example where we want to add the elements of two list, like: @[1,2,3] + @[10,20,30,40] -> @[11,22,33], and we want to do this without a for cycle. Which of the following four forms do you think might be the best?
map2(first, `+`, second) # 2 refers to the number of lists
zip(first, second).mapIt(it[0] + it[1])
zip(first, second).mapKV(k + v)
toSeq( Vec(first) + Vec(second) )
(None of these works right now.)
Motivation: very short code is required to implement the examples above in Matlab, R and Julia.
I think one should distinguish operations that make sense from a mathematical point of view (or any other domain) from arbitrary sequence operations.
To sum two vectors I'd rather just write v+w, and in fact this is exactly what I do in my library linalg.
On the other hand, I would not really want to have shortcuts for any possible operation. My favorite way to sum 1 to every element of a vector would be
v.map(proc (a: float): float = a + 1)
This is because the sum of a vector and a scalar does not have a standard interpretation. If anything, my only complaint would be that the way to write a proc is slightly verbose, and my favorite solution would be
v.map(proc(x) = x+1)
This requires auto generics (which I think are being deprecated) and the absence of a return type to mean auto type (currently it means void)