Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling nullary templates without () doesn't work inside calls inside other templates #13515

Closed
metagn opened this issue Feb 27, 2020 · 9 comments · Fixed by #20315
Closed

Calling nullary templates without () doesn't work inside calls inside other templates #13515

metagn opened this issue Feb 27, 2020 · 9 comments · Fixed by #20315

Comments

@metagn
Copy link
Collaborator

metagn commented Feb 27, 2020

Example

template test: bool = true

# compiles:
if not test:
  echo "wtf"

# does not compile:
template x =
  if not test:
    echo "wtf"

x

Current Output

got template(): bool, expected ...

Expected Output

compiles

Workaround

template test: bool = true

template x =
  if not test():
    echo "wtf"

x

Additional Information

$ nim -v
Nim Compiler Version 1.0.6
@timotheecour
Copy link
Member

timotheecour commented Feb 29, 2020

I think https://forum.nim-lang.org/t/5992 offers the key explanation:

Calling nullary templates without () doesn't work well. Unfortunately we didn't sort this out for version 1. IMO The spec should say that it is only supported for non-overloaded templates. That means your code should compile.

so I think the title should be re-worded to reflect that

#13508 uses this feature, partially blocks it for this reason

sorry can you elaborate?

proposal (EDIT: timotheecour#183)

  • templates should require explicit call test() unless declared with a pragma: {.implicitCall.}
template test: bool {.implicitCall.} = true
doAssert test == true
doAssert not compiles(test())

template test2: bool = true
doAssert test2() == true
test2 == true  # this should not compile
  • warnings would be issued for violations of those rules for a transition periods

@metagn
Copy link
Collaborator Author

metagn commented Mar 1, 2020

I think https://forum.nim-lang.org/t/5992 offers the key explanation:

Calling nullary templates without () doesn't work well. Unfortunately we didn't sort this out for version 1. IMO The spec should say that it is only supported for non-overloaded templates. That means your code should compile.

so I think the title should be re-worded to reflect that

I wouldn't say that's a key explanation, more of a non sequitur. The case in #13209 (overloaded templates) is mentioned, which is unrelated to this. You can add a low priority tag if you deem it fit even though this issue doesn't seem to be that hard of a problem.

#13508 uses this feature, partially blocks it for this reason

sorry can you elaborate?

Sorry, that PR doesn't have anything to do with this, it's just that it uses the affected feature of this bug, meaning codebases that use it will have to deal with this. It doesn't block the PR, my mistake.

@timotheecour
Copy link
Member

i think a title like Calling nullary templates without () doesn't work inside templates would make it more searchable, and reflects what this is about.
(unless Identifier template calls is the same thing but i didn't know the terminology)

I still think that quote is 100% related; the issue you've opened is valid, the code should compile (because test is not overloaded), and I don't think this should be low priority, it's a real bug :) and probably not too hard to fix as you mentioned (YMMV)

meaning codebases that use it will have to deal with this.

you're absolutely right :) so we need to fix this...

@metagn metagn changed the title Identifier template calls aren't transformed inside calls inside templates Calling nullary templates without () doesn't work inside calls inside templates Mar 1, 2020
@timotheecour
Copy link
Member

also note the {.dirty.} workaround, but obviously it's just a workaround and changes semantics #14332 (comment)

@metagn metagn changed the title Calling nullary templates without () doesn't work inside calls inside templates Calling nullary templates without () doesn't work inside calls inside other templates Jul 5, 2020
@jibal
Copy link

jibal commented Jul 5, 2020

This is a rather blatant and basic bug, and has nothing to do with overloading or {.implicitCall.} (which would be a pointless misfeature; just fix the compiler).

This innocuous code doesn't work:

template t1: int = 0
template t2 = echo t1
t2

Whereas this does:

template t1: int = 0
echo t1

This is alpha quality stuff and makes the language look bad. Of course, the compiler is free and no one owes me anything, so having made that statement I should go fix this. It will be a while, as I have no familiarity with the compiler code.

@timotheecour
Copy link
Member

timotheecour commented Jul 5, 2020

Most bugs seem blatant and basic until you delve into it and submit a fix. nim has more features than your average language and yes, they interact badly sometimes.

{.implicitCall.} (which would be a pointless misfeature; just fix the compiler)

or maybe it's the other way around? implicit calls, just like implicit conversions (converter, ptr char=>cstring #13790, implicit deref, procvar => pointer (nim-lang/RFCs#229)) all sound good ideas at first until you realize they complicate the type system. eg related to this implicit call, you can't reliably do:
template myecho(something...): untyped = echo(something...) and expect myecho to work like echo.

so having made that statement I should go fix this

yes, PR's welcome.

@jibal
Copy link

jibal commented Jul 5, 2020

Most bugs seem blatant and basic until you delve into it and submit a fix.

This is obviously not true. And in this case, what's blatant and basic has nothing to do with how hard it is to fix it; I'm talking about fundamental features of the language. If say, 1+1 produced 93, and it turned out to be due to some deep and complicated problem in the compiler that took months to fix, it would still be blatant and basic.

nim has more features than your average language and yes, they interact badly sometimes.

Features interacting badly means poor design. I don't think that's the case here ... it's just a bug. And yes, more features makes it harder to code the compiler correctly, but that's the cost one takes on when they design a feature-rich language. Templates are a great feature, but only if they work, and currently they are quite buggy. I encounter these bugs frequently ... I've submitted two, noticed dups of some others, and have a backlog of yet more that I need to investigate.

As for "implicit calls", there's no such thing here; no implicit anything, and no "call". Templates are always expanded; unlike with procs, there is zero semantic difference between t and t() if t is a template. (In fact Araq makes this point at #13209 mentioned above: "There is no rule in the spec that says "for a choice of symbols, pick the template because templates can be called without ()". And such a rule would be terrible. ")

template() as a type should never make it into an error message. Please don't drag in a lot of irrelevant stuff -- it's just sophistry, it doesn't help, and it's not appreciated. If you want to tell me where to look in the code to try to fix this, that would be helpful. Making excuses for bugs isn't.

P.S. It's not only nullary templates ... the problem is with the parenthesis-free invocation, not with the definition. Templates with optional parameters have the same issue.

@jibal
Copy link

jibal commented Jul 5, 2020

also note the {.dirty.} workaround, but obviously it's just a workaround and changes semantics #14332 (comment)

That's not a workaround for this ... {.dirty.} and #14332 aren't relevant here.

@metagn
Copy link
Collaborator Author

metagn commented Jul 11, 2022

Funnily enough method call syntax works.

template test: bool = true

template x =
  if test.not:
    echo "wtf"

x

metagn added a commit to metagn/Nim that referenced this issue Sep 7, 2022
metagn added a commit to metagn/Nim that referenced this issue Sep 10, 2022
Araq pushed a commit that referenced this issue Sep 11, 2022
* fix #13515

* only compile test

* no idea why this PR is unlocking this

* don't rope in symchoices

* even more restrictive
narimiran pushed a commit that referenced this issue Sep 19, 2022
(cherry picked from commit 58e6d43)
capocasa pushed a commit to capocasa/Nim that referenced this issue Mar 31, 2023
* fix nim-lang#13515

* only compile test

* no idea why this PR is unlocking this

* don't rope in symchoices

* even more restrictive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants