I understand that in Nim, you can call a proc without using brackets. Indeed, the following works fine:
write stdout, "a" #== write(stdout, "a")
#=>a
However, the followings fail.
import strutils
discard split "A,B,C" ',' #=> Error: in expression '"A,B,C" ','': identifier expected, but found '"A,B,C"'
proc add(x,y:int):int = x+y
discard add 1, 2 #=> Error: type mismatch: got <int literal(1)>
discard `+` 1, 2 #=> Error: invalid indentation
Is this a bug, or am I missing something?
Because discard expects a single statement but in the line there were several tokens space-separated.
Apart from that, it's preferable to use it only for single argument function or other obvious function call.
EDIT: it I meant was calling without brackets/parenthesis
Sorry for not replying so soon and thanks for the responces. However, this doesn't seem to be a problem with discard since I can replace the discard to echo to generate the same error.
proc add(x,y:int):int= x+y
echo add 1, 2 #=> Error: type mismatch: got <int literal(1)>
echo (add 1, 2) #=> Error: type mismatch: got <int literal(1)>
From a noob's point of view, this appears like a kind of inappropriate lexical analysis; the echo add 1, 2 or echo (add 1,2) should be analized as echo (add(1,2)) since add takes two arguments. In reality, it seems to be analized as echo (add(1),2).
@Araq Do you mean to say here we are dealing with CIS (command invocation syntax) ? To me this felt under UFCS since it's about function call and about giving more choices: it's "Universal". Now if UFCS means only a.f()/f(a) then that's not very universal. But the thing that makes me hate UFCS (which to me is the combo CIS+UFCS) is that it becomes so powerful, that in templates exploiting this combo, they become unrecognizable.
And what part in "discard add 1, 2" being surprising is not about parsing ? or maybe is not vexing ? or maybe you just don't find it surprising at all. Which wouldn't bear any weight in the discussion since you're not a human anymore, you're a compiler.
@Allosteric, calling function without parenthesis is only for single argument type. echo works because it expects varargs
Limiting it only single argument is good to avoid confusion, it's convenience that we don't have to write parenthesis when it's only a simple value variable to supply.
But if you need to call another functions which return a value that will be supplied, you still in the end use parenthesis, to avoid confusion.
Here is the practical thing you can hold: if in doubt, use parenthesis ;)
@lightness1024, U in UFCS is uniform, not universal. It's nothing about powerful or not, it's nice to have uniform syntax so we wouldn't have to wonder whether it's a function or a method .
Remember/know len in Python? Is it a function? Or is it a method that works on list type? Which is it?
No matter, we got len as UFCS so whether it's function or method doesn't matter. As long it returns the length of iterable things, that's it. Don't overly think it ;)
calling function without parenthesis is only for single argument type. echo works because it expects varargs
Multiple arguments are allowed when the call is a statement, but not when it's an expression. E.g add 1, 2 would work if it was a statement (only possible if doesn't return anything). IMO expression-calls without parenthesis should be avoided except for some specific cases like await.
@mashingan
No, it's not about number of arguments. See that:
proc fun(x,y: int) = echo x+y
proc gun(x,y: int): int = x+y
fun 1, 2 # works fine
let x = gun 1, 2 # doesn't compile
let x = gun 1: 2 # compiles (!), although it looks weird
Just like GULPF said, it's possible to use multiple arguments but only for statements. So yes, in practice it's probably better to use it in single-argument cases as Nim is becoming more and more expression-oriented (luckily!).