Scala 공식 문서에 따르면 함수의 파라미터가 0인 함수일경우 괄호를 넣을 수도 있고 괄호를 생략할 수도 있습니다.
이러한 언어적 규칙은 프로그래머에게 자유도를 제공하지만 규칙없는 개발은 사용자 입장에서 큰 혼란을 불러일으킬 수 있습니다.
Scala는 괄호의 유무를 언어적으로 강제하지는 않고, 권장사항을 작성해서 Scala 개발자가 이를 따르도록 유도하고 있습니다.
괄호를 사용해야 할 경우
공식 문서에서는 괄호를 사용해야 할 경우를 아래처럼 설명하고 있습니다.
However, this syntax should only be used when the method in question has no side-effects (purely-functional). In other words, it would be acceptable to omit parentheses when calling queue.size, but not when calling println().
그러나, 이러한 구문은 문제의 메서드에 side effect가 없을 때만 사용되어야 합니다(순수 함수). 즉, queue.size를 호출할 때는 괄호를 생략하는 것이 허용되지만, println()을 호출할 때는 허용되지 않습니다.
programming-in-scala에서는 아래처럼 설명하고 있습니다.
you should never define a method that has side-effects without parentheses, because then invocations of that method would look like a field selection. So your clients might be surprised to see the side effects
side-effect가 존재하는 함수는 반드시 괄호를 넣어야 합니다. 괄호가 없는 호출은 마치 필드를 선택하는 것처럼 보여서 코드의 사용자는 side-effect가 존재함을 안 순간 놀라게 될 것입니다.
결론적으로 함수의 내부적으로 side effect가 발생할 때는 괄호를 사용하라는 것입니다.
괄호를 사용할 필요가 없을 경우
programming-in-scala에서는 괄호를 사용할 필요가 없을 경우를 아래처럼 설명하고 있습니다.
The recommended convention is to use a parameterless method whenever there are no parameters and the method accesses mutable state only by reading fields of the containing object (in particular, it does not change mutable state).
추천하는 규칙은 파라미터가 없고 객체의 필드를 읽는 형식으로만 변경 가능한 필드에 접근이 가능할경우 항상 괄호 없는 함수를 사용하는 것입니다 (이러한 방식은 변경 가능한 상태를 변경시키지 않음)
it is encouraged style in Scala to define methods that take no parameters and have no side effects as parameterless methods, i.e., leaving off the empty parentheses.
...
whenever you invoke a function that has side effects, be sure to include the empty parentheses when you write the invocation.
Scala가 추천하는 스타일은 파라미터가 존재하지 않고 side-effect가 존재하지 않는 함수는 괄호 없는 함수로 만드는 것입니다.
...
당신이 언제라도 side-effect가 존재하는 함수를 호출한다면 호출 코드에 항상 괄호를 넣어야 합니다.
결론적으로 함수의 내부적으로 side effect가 발생하지 않을 때는 괄호를 사용할 필요가 없다는 것입니다.
함수에 괄호를 없애도 되게 만든 이유
Scala는 괄호가 없는 함수인 def를 val로 대체할 수 있습니다.
이러한 전제 하에서 programming-in-scala 책에서 그 이유를 자세하게 설명하고 있는데 제법 흥미롭습니다.
필요하시다면 전문을 읽어보길 추천합니다.
첫번째로 괄호가 없는 함수를 만들 수 있으면 uniform-access-principle를 만족시킬 수 있습니다.
client code는 속성을 필드로 만들지 함수로 만들지 내부적인 결정에 어떤 영향도 받지 않게 됩니다.
개발자는 필요하다면 함수를 def로 만들수도 있고, val로도 만들 수 있습니다.
두번째로 def와 val을 개발자의 필요에 따라 바꾸어 효율을 추구할 수 있다는 것입니다.
사용자 입장에서 def와 val은 완전히 동일합니다. 유일한 차이점은 val은 메모리에 미리 계산한 값을 저장하고 있어서 속도가 빠른 대신 추가적인 메모리가 필요하다는 것이고, def는 호출한 순간에 값을 계산하여 속도는 느린 대신 메모리를 차지하지 않는다는 것입니다.
개발자의 요구사항에 따라 두 선언은 지속적으로 바뀔 수 있고, client code는 이에 영향받지 않고 개발할 수 있게 됩니다.
괄호없는 함수의 선언이 가능한 덕분에 def와 val을 서로 대체할 수 있게 되었고, 이 덕분에 요구사항에 따라 속도를 선택할지 메모리를 선택할지 개발자가 결정할 수 있게 되었으며, 코드의 사용자는 이러한 규칙을 알 필요 없이 코드를 작성할 수 있게 되어 효율적으로 개발할 수 있게 된 것입니다.
결론
side-effect가 있다면 반드시 괄호를 포함하여 넣어주고, side-effect가 없다면 괄호를 없애서 def와 val 사이에서 선택할 수 있게 만들면 됩니다.