Hey! Currently in Nim the "command" syntax is one of the only cases in which trailing commas are not allowed.
foo 10,
20,
30,
# Error: invalid indentation
I was wondering if this could be lifted in the future, or if there's a reason for it (difficult to parse, introduces ambiguity, etc.)
IMHO, commas are the semicolons of Nim/Python. If statements can be separated with a line break, why not other things? It's annoying in situations like this:
const nested = {
"things": [
"foo",
"bar",
],
"stuff": [
"baz",
"quux",
],
}
How about a commas macro:
commas:
a
b
c
Then you can just leave out the commas entirely.
Probably something like
commas:
{
a
b
c
}
or
{
commas:
a
b
c
}
Makes a lot of sense, right
i'll bite:
import macros,strutils,tables
macro `~`(op:typed,body:untyped):untyped =
echo op.treeRepr
#can't use colons inside, so for a : b in tables, named tuples, object constructors instead use a = b
var mappings:Table[NimNodeKind,NimNodeKind] = {nnkAsgn:nnkExprColonExpr}.toTable
case op.kind
of nnkCurly:#Table or set
if body[0].kind == nnkAsgn:
result = nnkTableConstr.newNimNode
else:#set
result = op.copyNimTree()
of nnkCall:#assumes varargs
result = op.copyNimTree
result.del(result.len - 1)#remove empty varargs.
of nnkSym:#function call
result = newCall(ident(op.strval))
else:
result = op.copyNimTree()
var dest = result
#special case seq constructor
if op.kind == nnkPrefix and op[0].strval == "@":
result = nnkPrefix.newTree(ident"@",nnkBracket.newNimNode)
dest = result[1]
for stmt in body:
dest.add if stmt.kind in mappings:
let res = mappings[stmt.kind].newNimNode
stmt.copyChildrenTo(res)
res
else:
stmt
type Foo = object
a: int
b: set[char]
proc `$`(f:Foo):string = "Foo" & system.`$`(f)
proc weighted_avg(weight:float,data:varargs[float]):float =
for d in data:
result += d
result = result * weight / data.len.float
proc foo(x,y,z:int):int = x + y * z
let nested = toTable: ~{}:
"thing" = ~():
"foo"
~[]:
~Foo():
a = int: ~weighted_avg(0.5):
11.0
13.5
19.3
b = {'x'}
~ @[]:
3.0
3.1
3.2
"wrong" = ~():
"bar"
~[]:
~Foo():
a = ~foo:
3
4
2
b = ~{}:
'y'
'z'
@[]
echo nested