Hi,
Let me suggest small modifications about map and mapIt. My plan is to modify and extend the current functional programming arsenal. I opened several topics about this project on this forum. I don't have the final proposal yet, I'm still investigating and playing (making benchmarks, working on the type system). However, there are some steps which takes time to change and I believe that they would be good to have. Please find them below.
The PR request is here: https://github.com/nim-lang/Nim/pull/3372
Summary:
There are three motivation for this change:
Point 1. in details:
There are two mapIt templates. One of them returning a sequence (taking parameters: sequence, type, operation), the other is replacing values in the sequence given as parameter (taking parameters: sequence, operation). I propose to rename the "replacing" version to applyIt. Therefore in a future PR we could remove the extra (and not necessary) type parameter from the "returning" version.
To be consistent with the proc map versions, I renamed the "replacing" version of map to apply. Additionally, I introduced a new version of apply. Previously the "replacing" version took a proc with type proc (x: var T). With this PR there will be a new version which takes proc (x: T): T. Therefore the following two calls will work:
var x = @[1, 2, 3]
x.apply(proc(x: var int) = x = x+10)
x.apply(proc(x: int): int = x+100)
assert x = @[111, 112, 113]
Point 2. in details:
The current version of mapIt uses items to get the next item of the given object (which can be anything, not only seq). This PR introduces a compile time check whether the len is available for the object given as parameter, and if it is, then preallocates the result to the right size.
@andrea: There are plans to continue the work on sequtils. I'm trying to do it in small steps in which everybody can agree.
@vega: I'm open to any ideas. The mapInplace sounds a little bit long for me (although very clear what it does). The template version mapInplaceIt would be even longer. Somebody said that we needed a verb, so verb+It makes sense, that's why I chose apply.
Sidenote: You are right in that apply usually has different meaning. The apply is a function call in Clojure, so instead of (f a b) you could write (apply f [a,b]). We could have something similar for tuples (not for seq, because everything has to be known at compile time): apply(f, x) could unwrap the vales in the tuple x and call f with that. For example: apply(f, x) would be f(x[0], x[1], x[2]) if x has 3 elements. I think that we could have call for this "apply", so it would be call(f, x).
Peter