command call misinterprets "(" after space as normal function call #3898

Open
shaunc opened this Issue Feb 23, 2016 · 9 comments

Projects

None yet

4 participants

@shaunc
shaunc commented Feb 23, 2016

For example,

var a = false
assert a != true

works, but the following causes a compiler error:

var a, b, c: bool
a = false
b = true
c = true
assert (a != b) == c

Error:

test.nim(5, 17) Error: type mismatch: got (empty, bool)
but expected one of: 
system.==(x: array[I, T], y: array[I, T])
system.==(x: ref T, y: ref T)
system.==(x: float, y: float)
system.==(x: int8, y: int8)
system.==(x: char, y: char)
system.==(x: T, y: T)
system.==(x: int64, y: int64)
system.==(x: pointer, y: pointer)
system.==(x: set[T], y: set[T])
system.==(x: T, y: T)
system.==(x: int32, y: int32)
system.==(x: cstring, y: cstring)
system.==(x: Enum, y: Enum)
system.==(x: float32, y: float32)
system.==(x: int, y: int)
system.==(x: int16, y: int16)
system.==(x: T, y: T)
system.==(x: seq[T], y: seq[T])
system.==(x: string, y: string)
system.==(x: ptr T, y: ptr T)
system.==(x: bool, y: bool)
@def-
Member
def- commented Feb 23, 2016

That looks more like an issue with the command invocation. Using brackets it works:

assert((a != b) == c)

Whereas your code is interpreted as:

(assert(a != b)) == c

Edit: Ah, because of the bracket around a!=b it's actually not interpreted as command invocation syntax, but a regular proc call syntax with brackets assert(a != b)

Maybe the compiler should note the space and assume this to be command invocation syntax instead.

@scriptum
Contributor

I got undeclared identifier recently for != operator inside templates. Had to replace with not (a == b).

@def-
Member
def- commented Feb 23, 2016

@RPG sounds like a bug because != is implemented as a template itself. No idea what it has to do with this issue though.

@scriptum
Contributor

@def- that explains a lot. But I cannot reproduce this:)

@shaunc
shaunc commented Feb 23, 2016

I was thinking it might have something to do with the order in which types are inferred in the two templates in question when they are composed. ... e.g. (for instance) AST resulting from != doesn't yet have types and then is forced to by assert. Exactly how this works (and should work) is still a little bit black magic for me. I can also get the error using "echo" instead of "assert".

Edit: @def -- reading your msg more carefully I guess you are probably on the right track.

BTW (@scriptum -- for you to compare):

Nim Compiler Version 0.13.0 (2016-01-19) [MacOSX: amd64]
Copyright (c) 2006-2015 by Andreas Rumpf

git hash: a121c3f
active boot switches: -d:release

@shaunc shaunc changed the title from expression w/ "!=" does not have boolean type to command call to template misinterprets "(" after space as normal function call Feb 24, 2016
@shaunc
shaunc commented Feb 24, 2016

Ok @def -- you were on the right track. The following fails too:

var a, b, c: int

a = 1
b = 2
c = 3
assert (a + b) == c

but if you reverse

assert c == (a + b)

it works.

Seems that space before paren isn't being counted in this context. Hmm... doesn't even have to do with the fact that assert is a template. For instance replacing the assert by:

proc foo(i: bool) : void
foo (a + b) == c

also fails. Hmm... I guess manual is unclear. I certainly want command invocation syntax to be invoked if and only if a space follows function (and no dot before to imply method call syntax).

@shaunc shaunc changed the title from command call to template misinterprets "(" after space as normal function call to command call misinterprets "(" after space as normal function call Feb 24, 2016
@Araq
Member
Araq commented Feb 24, 2016

@shaunc That was intended to be dealt with #? strongSpaces but people voted against it.

@shaunc
shaunc commented Feb 25, 2016

@Araq ... where do I vote? :) ... it could be that strong spaces goes too far, though. My preference would be to enable command invocation syntax iff space follows ident at start of expression ("prefix" position) but not affect infix evaluation.

Also currently the following fails:

proc foo(a: openArray[int]): void
foo [1, 2]

Perhaps if precedence of command invocation syntax is changed in parse the example invocations here could be solved without complete "strong spaces" implementation?

EDIT -- so if I could I would vote for parts 2 & 3 of strongSpaces in the documentation, but not part 1.

@Araq
Member
Araq commented Feb 25, 2016

Perhaps if precedence of command invocation syntax is changed in parse the example invocations here could be solved without complete "strong spaces" implementation?

Definitely a reasonable thing to do.

@Araq Araq added the RFC label Feb 29, 2016
@Araq Araq added a commit that referenced this issue Jul 16, 2016
@Araq Araq prepare for #3898 11b499f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment