Hi, i'm trying to assign the result of a template, but apparently the compiler gets confused unless I surround the template with (block: ...)
template foo(p: untyped): auto =
1
let x = (block:
foo:
discard)
let y =
foo:
discard
is this a bug ?
thanks!
if I understand correcly what you mean I'd expect it to compile with:
template foo(p: untyped): auto = (block:
1
)
but it won't
Hmm, that's true. I don't know the reason but judging from error, it's said wrong number of argument so need to change to varargs to accommodate zero arity.
If it's like below, is it ok?
template foo(_: untyped): auto =
echo "foo"
1
template foo2(_: varargs[untyped]): auto =
echo "foo2"
block:
discard
2
let x = (block:
foo:
discard)
let y = foo2()
echo x
echo y
By passing nil (ok, by setting the default to nil), you can get foo3() behaving as follows
template foo(_: untyped): auto =
echo "foo"
1
template foo2(_: varargs[untyped]): auto =
echo "foo2"
block:
discard
2
template foo3(_: untyped = nil): auto =
echo "foo3"
3
let x = (block:
foo:
discard)
let y = foo2()
let z = foo3()
let x2 = foo(nil)
echo x
echo y
echo z
echo x2
maybe I was not clear to begin with. the point of having an untyped argument is not to discard it :-) I am actually writing a template where a new proc is returned. In particular, I'll return a {.thread.} proc along with (a struct containing) a ptr channel, so something like:
template foo(blk: untyped): typed
# do stuff
let ch = # create ch ptr
let task = proc() [.thread.} =
# do smth w/ ch
blk
(ch, task)
so that I can do:
let (ch, task) = foo:
# body of my task
this was just a minimal reproducible example of the issue, which is "can't assign the result of a template having a block parameter".
All of these seems to me like workarounds, I don't think the language is expected to work the way it does, and if, it is, then I'd just like to know the rationale for such a behavior :-)
thanks!
Is it possible to return value from template which the last of argument is untyped? :?
If possible, maybe some example would be nice :)
I used template with last argument untyped for executing that argument (which consists of statements) but never use so that it would return something.
Is it possible to return value from template which the last of argument is untyped?
pretty sure you can:
that is correct. yet
template foo(p: untyped): auto = (block:
1
)
let x = foo:
discard
won't compile, while this will
let x = (block:
1
)
in fact, this compiles as well:
template foo(p: untyped): auto = (block:
1
)
let x = foo(3)
that's why I feel like it might a parsing problem (it doesn't compile only when the arg is a block)