In this code
let a = 2
let b = 3
let good = a + b #clean
let yesbut = a+b #acceptable
let bad = a +b #ugly but... Nim compiler refuse it -> Error: attempting to call routine 'a', found 'a'
I concede that the last assignment is "ugly", but while some other programming languages accept it, for Nim is just wrong. What is the reason? Is it wrong in terms of syntax or in terms of semantics? What the compiler is figuring out there?
Thank you
Thank you @Morturo
With some little help from ChatGPT I guess that most likely is related to seeing +b as a unary operator. I was misled by the fact that '+' unary operator has no practical impact... but '-' has, and the parsing rules should be consistent across all possible unary operators. Still the error code "call routine" is not very clear to me.
No, it makes sense. Once the unary operator is consumed, it just sees the assignment like this:
let bad = a b
and it complains I'm trying to run "a" func or proc, i.e. a(b)There is a small part of me that wishes that a future version of Nim demanded spaces for operators.
So, x = a+b would say Error: undeclared identifier: 'a+b'.
Why would this be good:
And even make way for library support of enclosures. For example, if an operator macro is declared that starts with (, {, or [, then its reverse pairing would activate. Like this silly example:
template `[#`(ablock: untyped) =
echo "'''text"
ablock
echo "'''"
# and here I use it. Notice that there is a space after the # starting this comment.
[#
echo "foo"
echo "bar"
#]
This would take Nim's DSL support to whole new levels.
For example, if an operator macro is declared that starts with (, {, or [, then its reverse pairing would activate. Like this silly example: ...
Interesting but that could be added to the language without your "spaces around operators" requirement.
The downside, of supporting enclusures (or anything which would require spaces around ops), is that the spacing is hard on the eyes sometimes. For example:
var a = (1+2)*((3+2)+4)
is pretty but
var a = ( 1 + 2 ) * ( ( 3 + 2 ) + 4 )
is less pretty.
For example, if an operator macro is declared that starts with (, {, or [, then its reverse pairing would activate. Like this silly example: ...
Interesting but that could be added to the language without your "spaces around operators" requirement.
I've not been in the nim parser for a long while. So perhaps I am wrong about that.
If it was added, a question to ponder: should < and > also be allowed to be in enclosures; or would that create too much visual confusion? So, allowing <!% %!> pairing for example? Or <<<< >>>>.
It would also probably be best to forbid any closures in the opening operator. So, {{{$ $}}} is okay, but {{{$} {$}}} would be a big no-no.
The rule I used in nim/bigints is spacing around operators but not around enclosures.
I would thus write JohnAD's example as:
var a = (1 + 2) * ((3 + 2) + 4)
This middleground between the two options is far more readable to me than the "pretty" proposal that I would not call pretty at all.
I do not understand: supporting enclosures in template do not require spaces around them. We shall remove from supported enclosures all the delimiters already used by the language just like there is a set of reserved keywords for identifiers.
I would thus write JohnAD's example as:
var a = (1 + 2) * ((3 + 2) + 4)
That seems reasonable. The only catch is for multi-character enclusures, the (( would require extra spacing as a (( )) enclosure pair could be defined.
So:
var a = (1 + 2) * ( (3 + 2) + 4)