* fix mapIt issues #12625 & #12639: 1. fallback to call `map` when the result of `op` is a closure; 2. use `items(s)` in the for loop. * fix test errors. * add comments and InType is moved. * fix ident.
This commit is contained in:
parent
1a44b7e3ce
commit
04c326569b
2 changed files with 39 additions and 14 deletions
|
|
@ -924,6 +924,9 @@ template mapIt*(s: typed, op: untyped): untyped =
|
||||||
block:
|
block:
|
||||||
var it{.inject.}: type(items(s));
|
var it{.inject.}: type(items(s));
|
||||||
op))
|
op))
|
||||||
|
when OutType is not (proc):
|
||||||
|
# Here, we avoid to create closures in loops.
|
||||||
|
# This avoids https://github.com/nim-lang/Nim/issues/12625
|
||||||
when compiles(s.len):
|
when compiles(s.len):
|
||||||
block: # using a block avoids https://github.com/nim-lang/Nim/issues/8580
|
block: # using a block avoids https://github.com/nim-lang/Nim/issues/8580
|
||||||
|
|
||||||
|
|
@ -939,9 +942,28 @@ template mapIt*(s: typed, op: untyped): untyped =
|
||||||
result
|
result
|
||||||
else:
|
else:
|
||||||
var result: seq[OutType] = @[]
|
var result: seq[OutType] = @[]
|
||||||
for it {.inject.} in s:
|
# use `items` to avoid https://github.com/nim-lang/Nim/issues/12639
|
||||||
|
for it {.inject.} in items(s):
|
||||||
result.add(op)
|
result.add(op)
|
||||||
result
|
result
|
||||||
|
else:
|
||||||
|
# `op` is going to create closures in loops, let's fallback to `map`.
|
||||||
|
# NOTE: Without this fallback, developers have to define a helper function and
|
||||||
|
# call `map`:
|
||||||
|
# [1, 2].map((it) => ((x: int) => it + x))
|
||||||
|
# With this fallback, above code can be simplified to:
|
||||||
|
# [1, 2].mapIt((x: int) => it + x)
|
||||||
|
# In this case, `mapIt` is just syntax sugar for `map`.
|
||||||
|
|
||||||
|
when defined(nimHasTypeof):
|
||||||
|
type InType = typeof(items(s), typeOfIter)
|
||||||
|
else:
|
||||||
|
type InType = type(items(s))
|
||||||
|
# Use a help proc `f` to create closures for each element in `s`
|
||||||
|
let f = proc (x: InType): OutType =
|
||||||
|
let it {.inject.} = x
|
||||||
|
op
|
||||||
|
map(s, f)
|
||||||
|
|
||||||
template applyIt*(varSeq, op: untyped) =
|
template applyIt*(varSeq, op: untyped) =
|
||||||
## Convenience template around the mutable ``apply`` proc to reduce typing.
|
## Convenience template around the mutable ``apply`` proc to reduce typing.
|
||||||
|
|
|
||||||
|
|
@ -204,3 +204,6 @@ block ttoseq:
|
||||||
var y: type("a b c".split)
|
var y: type("a b c".split)
|
||||||
y = "xzy"
|
y = "xzy"
|
||||||
stdout.write("\n")
|
stdout.write("\n")
|
||||||
|
|
||||||
|
block tseqmapitchain:
|
||||||
|
doAssert @[101, 102] == [1, 2].mapIt(func (x: int): int = it + x).mapIt(it(100))
|
||||||
Loading…
Add table
Add a link
Reference in a new issue