Closed metagn closed 3 years ago
The idiom is (a = b; a)
and works well. Better than Python's new ugly C-isms that never made much sense.
It does work well, but I have seen people request that operator for easier migration from Python (don't know if it's because they actually used it in the code they were migrating). Implicitly discardable calls only applying to procedures would just be odd to the people that were using discardable already. That applies to templates which are just procs but as AST replacements, and also to emulators of what would be language-level syntax in another language but are trivial to implement as user code in Nim like :=
.
Basically this change would only help people using discardable, it wouldn't really benefit others. While it would be kind of weird to think of discardable as a feature you "grow out of" before you learn how to really use Nim, I do think it is understandable to think it will eventually be removed, but if it's not going to be removed any time soon then this is the next obvious step to the feature IMO. I just found out that the manual actually specifically points this case out, implying someone using discardable is likely to encounter this.
Perhaps discardable needs a significant overhaul to make this work, in which case it might not be worth bothering, if so then a minor improvement would be {.discardable.}
on template giving a proper error like "discardable is not supported on templates" as it currently gives "cannot attach a custom pragma".
Maybe we can make discardable more useful by attaching it to an expression and not just to a proc:
({.discardable.} 3)
This seems easy to implement and naturally allows for usage in a template:
template foo: int = ({.discardable.} 3)
foo()
(I don't know whether I like to enhance the support for .discardable, but if we do it, we should do it right. ;-) )
I don't know how I missed it, this is actually possible in current Nim:
proc discardable[T](x: T): T {.discardable, inline.} = x
template `:=`(a, b): untyped =
let a = b
discardable a
foo := 1
if bar := false:
doAssert bar
This is good enough to close the issue, it would be perfect if it's possible to completely elide the discardable
proc but it's not worth the effort for such a small reward. One thing is the signature needs to be proc discardable[T](x: lent T): lent T
for no copies I believe? but you can't lent
ints so you would have to specialize it. I don't think the discussion of "the most optimal identity proc" is relevant to this issue so I'll just close
You should use proc discardable[T](x: sink T): T
. :-)
Don't know if it should be supported for
untyped
. Instead of checking the return type at the declaration site it would have to instantiate the template every time its called, get its type, then check if it is discardable at that callsite. If this is possible, then it could probably be extended to macros as well.Could be useful for something like this:
Just to get it out, this proposal is void if it's decided that discardable in general is not worth supporting, but if it is worth supporting then this would help the feature have more of a universal availability.