improve docs for sugar.collect (#17188)

This commit is contained in:
Timothee Cour 2021-02-25 23:43:32 -08:00 • committed by GitHub
commit 4a31088ac2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -58,7 +58,7 @@ macro `=>`*(p, b: untyped): untyped =
runnableExamples: runnableExamples:
proc passTwoAndTwo(f: (int, int) -> int): int = f(2, 2) proc passTwoAndTwo(f: (int, int) -> int): int = f(2, 2)
doAssert passTwoAndTwo((x, y) => x + y) == 4 assert passTwoAndTwo((x, y) => x + y) == 4
type type
Bot = object Bot = object
@ -67,7 +67,7 @@ macro `=>`*(p, b: untyped): untyped =
var myBot = Bot() var myBot = Bot()
myBot.call = (name: string) {.noSideEffect.} => "Hello " & name & ", I'm a bot." myBot.call = (name: string) {.noSideEffect.} => "Hello " & name & ", I'm a bot."
doAssert myBot.call("John") == "Hello John, I'm a bot." assert myBot.call("John") == "Hello John, I'm a bot."
# let f = () => (discard) # simplest proc that returns void # let f = () => (discard) # simplest proc that returns void
# f() # f()
@ -149,13 +149,13 @@ macro `->`*(p, b: untyped): untyped =
# is the same as: # is the same as:
# proc passTwoAndTwo(f: proc (x, y: int): int): int = f(2, 2) # proc passTwoAndTwo(f: proc (x, y: int): int): int = f(2, 2)
doAssert passTwoAndTwo((x, y) => x + y) == 4 assert passTwoAndTwo((x, y) => x + y) == 4
proc passOne(f: (int {.noSideEffect.} -> int)): int = f(1) proc passOne(f: (int {.noSideEffect.} -> int)): int = f(1)
# is the same as: # is the same as:
# proc passOne(f: proc (x: int): int {.noSideEffect.}): int = f(1) # proc passOne(f: proc (x: int): int {.noSideEffect.}): int = f(1)
doAssert passOne(x {.noSideEffect.} => x + 1) == 2 assert passOne(x {.noSideEffect.} => x + 1) == 2
result = createProcType(p, b) result = createProcType(p, b)
@ -193,13 +193,13 @@ macro dumpToString*(x: untyped): string =
runnableExamples: runnableExamples:
const a = 1 const a = 1
let x = 10 let x = 10
doAssert dumpToString(a + 2) == "a + 2: 3 = 3" assert dumpToString(a + 2) == "a + 2: 3 = 3"
doAssert dumpToString(a + x) == "a + x: 1 + x = 11" assert dumpToString(a + x) == "a + x: 1 + x = 11"
template square(x): untyped = x * x template square(x): untyped = x * x
doAssert dumpToString(square(x)) == "square(x): x * x = 100" assert dumpToString(square(x)) == "square(x): x * x = 100"
doAssert not compiles dumpToString(1 + nonexistant) assert not compiles dumpToString(1 + nonexistant)
import std/strutils import std/strutils
doAssert "failedAssertImpl" in dumpToString(doAssert true) # example with a statement assert "failedAssertImpl" in dumpToString(assert true) # example with a statement
result = newCall(bindSym"dumpToStringImpl") result = newCall(bindSym"dumpToStringImpl")
result.add newLit repr(x) result.add newLit repr(x)
result.add x result.add x
@ -232,7 +232,7 @@ macro capture*(locals: varargs[typed], body: untyped): untyped {.since: (1, 1).}
if i * j == 42: if i * j == 42:
capture i, j: capture i, j:
myClosure = () => fmt"{i} * {j} = 42" myClosure = () => fmt"{i} * {j} = 42"
doAssert myClosure() == "6 * 7 = 42" assert myClosure() == "6 * 7 = 42"
var params = @[newIdentNode("auto")] var params = @[newIdentNode("auto")]
let locals = if locals.len == 1 and locals[0].kind == nnkBracket: locals[0] let locals = if locals.len == 1 and locals[0].kind == nnkBracket: locals[0]
@ -259,21 +259,21 @@ since (1, 1):
import std/algorithm import std/algorithm
let a = @[1, 2, 3, 4, 5, 6, 7, 8, 9] let a = @[1, 2, 3, 4, 5, 6, 7, 8, 9]
doAssert a.dup(sort) == sorted(a) assert a.dup(sort) == sorted(a)
# Chaining: # Chaining:
var aCopy = a var aCopy = a
aCopy.insert(10) aCopy.insert(10)
doAssert a.dup(insert(10), sort) == sorted(aCopy) assert a.dup(insert(10), sort) == sorted(aCopy)
let s1 = "abc" let s1 = "abc"
let s2 = "xyz" let s2 = "xyz"
doAssert s1 & s2 == s1.dup(&= s2) assert s1 & s2 == s1.dup(&= s2)
# An underscore (_) can be used to denote the place of the argument you're passing: # An underscore (_) can be used to denote the place of the argument you're passing:
doAssert "".dup(addQuoted(_, "foo")) == "\"foo\"" assert "".dup(addQuoted(_, "foo")) == "\"foo\""
# but `_` is optional here since the substitution is in 1st position: # but `_` is optional here since the substitution is in 1st position:
doAssert "".dup(addQuoted("foo")) == "\"foo\"" assert "".dup(addQuoted("foo")) == "\"foo\""
proc makePalindrome(s: var string) = proc makePalindrome(s: var string) =
for i in countdown(s.len-2, 0): for i in countdown(s.len-2, 0):
@ -286,7 +286,7 @@ since (1, 1):
makePalindrome # xyzyx makePalindrome # xyzyx
sort(_, SortOrder.Descending) # zyyxx sort(_, SortOrder.Descending) # zyyxx
makePalindrome # zyyxxxyyz makePalindrome # zyyxxxyyz
doAssert d == "zyyxxxyyz" assert d == "zyyxxxyyz"
result = newNimNode(nnkStmtListExpr, arg) result = newNimNode(nnkStmtListExpr, arg)
let tmp = genSym(nskVar, "dupResult") let tmp = genSym(nskVar, "dupResult")
@ -376,23 +376,23 @@ macro collect*(init, body: untyped): untyped {.since: (1, 1).} =
let k = collect(newSeq): let k = collect(newSeq):
for i, d in data.pairs: for i, d in data.pairs:
if i mod 2 == 0: d if i mod 2 == 0: d
doAssert k == @["bird"] assert k == @["bird"]
## seq with initialSize: ## seq with initialSize:
let x = collect(newSeqOfCap(4)): let x = collect(newSeqOfCap(4)):
for i, d in data.pairs: for i, d in data.pairs:
if i mod 2 == 0: d if i mod 2 == 0: d
doAssert x == @["bird"] assert x == @["bird"]
## HashSet: ## HashSet:
let y = collect(initHashSet()): let y = collect(initHashSet()):
for d in data.items: {d} for d in data.items: {d}
doAssert y == data.toHashSet assert y == data.toHashSet
## Table: ## Table:
let z = collect(initTable(2)): let z = collect(initTable(2)):
for i, d in data.pairs: {i: d} for i, d in data.pairs: {i: d}
doAssert z == {0: "bird", 1: "word"}.toTable assert z == {0: "bird", 1: "word"}.toTable
result = collectImpl(init, body) result = collectImpl(init, body)
@ -400,23 +400,28 @@ macro collect*(body: untyped): untyped {.since: (1, 5).} =
## Same as `collect` but without an `init` parameter. ## Same as `collect` but without an `init` parameter.
runnableExamples: runnableExamples:
import std/[sets, tables] import std/[sets, tables]
let data = @["bird", "word"] let data = @["bird", "word"]
# seq: # seq:
let k = collect: let k = collect:
for i, d in data.pairs: for i, d in data.pairs:
if i mod 2 == 0: d if i mod 2 == 0: d
doAssert k == @["bird"] assert k == @["bird"]
## HashSet: ## HashSet:
let n = collect: let n = collect:
for d in data.items: {d} for d in data.items: {d}
doAssert n == data.toHashSet assert n == data.toHashSet
## Table: ## Table:
let m = collect: let m = collect:
for i, d in data.pairs: {i: d} for i, d in data.pairs: {i: d}
doAssert m == {0: "bird", 1: "word"}.toTable assert m == {0: "bird", 1: "word"}.toTable
# avoid `collect` when `sequtils.toSeq` suffices:
assert collect(for i in 1..3: i*i) == @[1, 4, 9] # ok in this case
assert collect(for i in 1..3: i) == @[1, 2, 3] # overkill in this case
from std/sequtils import toSeq
assert toSeq(1..3) == @[1, 2, 3] # simpler
result = collectImpl(nil, body) result = collectImpl(nil, body)