구문 디자인-인수가 전달되지 않을 때 왜 괄호를 사용합니까?


66

많은 언어에서 구문 function_name(arg1, arg2, ...)은 함수를 호출하는 데 사용됩니다. 인수없이 함수를 호출하려면을 수행해야합니다 function_name().

컴파일러 또는 스크립트 인터프리터가 ()이를 함수 호출로 성공적으로 감지 해야하는 것이 이상합니다 . 변수가 호출 가능한 것으로 알려진 경우 왜 function_name;충분하지 않습니까?

반면에 일부 언어에서는 다음 function_name 'test';과 같이 할 수 있습니다 : 또는 function_name 'first' 'second';함수 나 명령을 호출 할 수도 있습니다 .

괄호는 우선 순위를 선언하는 데 필요하고 다른 곳에서는 선택 사항이 낫다면 더 좋을 것이라고 생각합니다. 예를 들어,하는 if expression == true function_name;것만 큼 ​​유효해야합니다 if (expression == true) function_name();.

내 생각에 가장 성가신 것은 'SOME_STRING'.toLowerCase()프로토 타입 함수에 인수가 필요하지 않은 경우에하는 것입니다. 왜 디자이너들은 더 단순한 것에 대해 결정하지 'SOME_STRING'.lower않았는가?

면책 조항 : 틀리지 말고 C와 같은 구문을 좋아합니다! ;) 나는 그것이 더 나을 수 있는지 묻고 있습니다. 필요합니까 ()어떤 성능의 장점을 가지고, 또는 쉽게 코드를 이해하게 하는가? 나는 그 이유가 무엇인지 정말로 궁금합니다.


103
함수를 다른 함수의 인수로 전달하려면 어떻게 하시겠습니까?
Vincent Savard

30
인간이 코드를 읽을 필요가있는 한, 가독성이 가장 중요합니다.
Tulains Córdova

75
그것은 가독성이있는 것입니다.에 대해 묻지 만 ()게시물에서 눈에 띄는 것은 if (expression == true)진술입니다. 당신은 불필요한 것에 대해 걱정하고 ()나서 불필요한 것을 사용합니다 == true:)
David Arno

15
Visual Basic에서 허용
edc65

14
파스칼에서는 필수였으며 인수를 취하는 함수와 프로 시저에만 파 렌스를 사용했습니다.
RemcoGerlich

답변:


251

일급 함수 를 사용하는 언어의 경우 함수참조 하는 구문 은 다음과 같습니다.

a = object.functionName

그 함수 를 호출 하는 행위 는 다음과 같습니다.

b = object.functionName()

a위의 예에서 위의 함수를 참조하고 (함수를 호출하여 호출 할 수 있음 a()) b함수의 반환 값을 포함합니다.

기능을 할 수있는 언어가 괄호없이 호출하는 동안 그들이 여부, 그것은 혼란을 얻을 수 호출 기능을, 또는 단순히 참조 함수에.


9
이 차이는 부작용이있을 때에 만 흥미로울 수 있습니다. 순수한 기능은 중요하지 않습니다.
Bergi

73
@ Bergi : 순수한 기능에는 많은 것이 중요합니다! make_list인수를 목록으로 묶는 함수 가 있으면 f(make_list)함수를 f전달하거나 빈 목록 을 전달하는 것과 큰 차이가 있습니다.
user2357112 2016 년

12
@ Bergi : 그럼에도 불구하고, 나는 SATInstance.solve즉시 실행하려고 시도하지 않고 다른 함수에 엄청나게 비싼 순수한 함수를 전달할 수 있기를 원합니다 . 또한 순수한 것으로 선언 someFunction되었는지 여부에 따라 다른 것이 있으면 정말 어색합니다 someFunction. 나는 (의사)가 예를 들어 func f() {return g}, func g() {doSomethingImpure}func apply(x) {x()}다음 apply(f)호출 f. 나는 그 선언하면 f순수, 갑자기 apply(f)통과 gapply, 그리고 apply전화 g와 뭔가 불순한 않습니다.
user2357112

6
@ user2357112 평가 전략은 순도와 무관합니다. 가능하지만 어색한 것을 평가할 때 호출 구문을 주석으로 사용하지만 결과 나 정확성을 변경하지는 않습니다. 당신의 예와 관련하여 apply(f), g불공평하고 (그리고 apply또한?) 그렇다면 모든 것이 불완전하며 물론 무너집니다.
Bergi

14
이것의 예로는 파이썬과 ECMAScript가 있습니다. 둘 다 "메서드"라는 핵심 개념을 가지고 있지 않습니다. 대신 익명의 1 급 함수 객체를 반환하는 명명 된 속성이 있고 그 이름을 익명의 1 급 함수라고합니다. 특히, 파이썬과 ECMAScript를 모두 말은 foo.bar()아닌 하나의 작업을 "호출 방법 bar개체의 foo"가 아니라 두 개의 작업 "필드 역 참조 bar객체의 foo 다음 객체가 해당 필드에서 반환 전화". 그래서,이 .는 IS 필드 선택 연산자()는 IS 호출 연산자 그리고 그들은 독립적입니다.
Jörg W Mittag

63

실제로 스칼라는이를 준수 할 수있는 규칙을 따르지만이를 허용합니다. 방법에 부작용이있는 경우 어쨌든 괄호를 사용해야합니다.

컴파일러 라이터로서, 나는 괄호의 보장 된 존재가 매우 편리하다는 것을 알았습니다. 나는 항상 그것이 메소드 호출이라는 것을 알고 있었고, 이상한 경우를 위해 분기점을 만들 필요는 없습니다.

프로그래머 및 코드 리더로서, 괄호가 있으면 매개 변수가 전달되지 않더라도 메소드 호출인지 의심 할 여지가 없습니다.

매개 변수 전달은 메소드 호출의 특성을 정의하는 유일한 것이 아닙니다. 매개 변수가없는 메서드를 매개 변수가있는 메서드와 다른 것으로 취급하는 이유는 무엇입니까?


감사합니다. 중요한 이유에 대한 유효한 이유를 알려 주셨습니다. 언어 설계자가 프로토 타입에서 함수를 사용해야하는 이유에 대한 몇 가지 예도 제시해 주시겠습니까?
David Refoua

괄호가 있으면 그것이 완전히 동의 하는 메소드 호출이라는 데는 의심의 여지가 없습니다 . 내 프로그래밍 언어보다 암시적인 프로그래밍 언어를 선호합니다.
Corey Ogburn

20
스칼라는 실제로 그보다 조금 미묘합니다. 다른 언어는 하나 이상의 매개 변수가있는 하나의 매개 변수 목록 만 허용하지만 Scala는 0 개 이상의 매개 변수가있는 0 개 이상의 매개 변수 목록을 허용합니다. 따라서 def foo()하나의 빈 매개 변수 목록 def foo이있는 방법이며 매개 변수 목록이없는 방법이며 두 가지가 다릅니다 ! 일반적으로 매개 변수 목록이없는 메소드는 인수 목록없이 호출해야하며 빈 매개 변수 목록이있는 메소드는 빈 인수 목록으로 호출해야합니다. 빈 인수로 어떤 매개 변수 목록과 메소드를 호출하면 ... 실제로
요 르그 W MITTAG

19
… 빈 인수 목록으로 메소드 호출에 의해 리턴apply오브젝트 의 메소드 를 호출하는 것으로 해석되는 반면, 인수 목록없이 빈 매개 변수리스트를 가진 메소드를 호출하는 것은 컨텍스트에 따라 빈 인수 목록으로 메소드를 호출하는 것으로 다양하게 해석 될 수 있습니다. η 부분적으로 적용되는 메소드 (즉, "메소드 참조")로 확장되거나 전혀 컴파일되지 않을 수 있습니다. 또한 스칼라는 인수 목록없이 메소드를 호출하는 것과 필드를 참조하는 것을 (구문 적으로) 구별하지 않음으로써 Uniform Access Principle을 따릅니다.
Jörg W Mittag

3
필자가 필요로하는 "의식"이없는 루비를 인식하게 되더라도 (괄호, 중괄호, 명시 적 유형) 나는 메소드 괄호가 더 빨리 읽히는 것을 말할 수있다 . 그러나 일단 친숙한 관용적 루비는 읽기 쉽고 확실히 쓰기가 더 빠릅니다.
radarbob

19

이것은 실제로 구문 선택의 미묘한 차이입니다. 형식화 된 람다 미적분학을 기반으로하는 기능적 언어에 대해 이야기하겠습니다.

상기 언어에서 모든 함수는 정확히 하나의 인수를 갖습니다 . 우리가 종종 "다중 인수"로 생각하는 것은 실제로 제품 유형의 단일 매개 변수입니다. 예를 들어 두 정수를 비교하는 함수는 다음과 같습니다.

leq : int * int -> bool
leq (a, b) = a <= b

단일 쌍의 정수를 사용합니다. 괄호는 기능 매개 변수를 나타내지 않습니다 . 인수 와 패턴을 일치 시키는 데 사용됩니다 . 이것이 실제로 하나의 주장임을 확신하기 위해 패턴 일치 대신 투영 함수를 사용하여 쌍을 해체 할 수 있습니다.

leq some_pair = some_pair.1 <= some_pair.2

따라서 괄호는 실제로 패턴 일치를 입력하고 일부 타이핑을 저장할 수있는 편의성입니다. 필요하지 않습니다.

표면 상으로 인수가없는 함수는 어떻습니까? 이러한 함수에는 실제로 domain이 있습니다 Unit. 의 단일 멤버 Unit는 일반적으로로 작성 ()되므로 괄호가 표시됩니다.

say_hi : Unit -> string
say_hi a = "Hi buddy!"

이 함수를 호출하려면 type 값에 적용 Unit해야 ()하므로 결국 작성 해야합니다 say_hi ().

따라서 인수 목록과 같은 것은 실제로 없습니다!


3
그렇기 때문에 빈 괄호가 ()숟가락을 뺀 손잡이와 비슷합니다.
Mindwin

3
상당히 혼란스럽지 않고 leq사용 하는 함수를 정의하는 <<=!
KRyan

5
이 답변은 "제품 유형"과 같은 문구 외에 "tuple"이라는 단어를 사용하면 이해하기가 더 쉬울 수 있습니다.
Kevin

대부분의 형식주의는 int f (int x, int y)를 I ^ 2에서 I까지의 함수로 취급합니다. Lambda 미적분이 다르기 때문에이 방법을 사용하여 다른 형식주의의 고품격과 일치하지 않습니다. 대신 람다 미적분은 카레를 사용합니다. 비교는 x-> (y-> (x <= y))입니다. (x-> (y-> (x <= y)) 2는 (y-> 2 <= y)로 평가되고 (x-> (y-> (x <= y)) 2 3은 ( y-> 2 <= y) 3 차례로 2 <= 3으로 평가
Taemyr

1
@PeriataBreatta 나는 ()단위를 표현하는 데 사용한 역사에 익숙하지 않습니다 . 이유의 적어도 일부가 "매개 변수없는 기능"과 비슷하다면 놀라지 않을 것입니다. 그러나 구문에 대한 다른 가능한 설명이 있습니다. 유형의 대수에서는 Unit실제로 제품 유형의 정체성입니다. 바이너리 제품은 다음과 같이 작성됩니다 (a,b). 단항 제품을 다음과 같이 작성할 수 (a)있으므로 논리 확장은 단순히 널 제품을 작성하는 것 ()입니다.
gardenhead

14

예를 들어 ()없이 메소드 이름을 사용하는 Javascript에서는 함수를 실행하지 않고 함수 자체를 반환합니다. 이 방법으로 예를 들어 함수를 다른 메소드에 인수로 전달할 수 있습니다.

Java에서 식별자 뒤에 () 또는 (...)이 있으면 메소드 호출을 의미하고 ()가없는 식별자는 멤버 변수를 나타냅니다. 메소드 또는 멤버 변수를 처리하는지 여부를 의심하지 않으므로 가독성이 향상 될 수 있습니다. 실제로 동일한 이름을 메소드와 멤버 변수에 모두 사용할 수 있으며 각각의 구문으로 액세스 할 수 있습니다.


4
+1 인간이 코드를 읽을 필요가있는 한, 가독성이 가장 중요합니다.
Tulains Córdova

1
@ TulainsCórdova 나는 펄이 당신과 동의하지 않을 것입니다.
Racheet

@Racheet : 펄 않을 수도 있지만 Perl Best Practices않습니다
slebetman

1
@Racheet Perl은 읽기 가능하도록 작성된 경우 매우 읽기 쉽습니다. 그것은 비의 비언어적 언어와 거의 동일합니다. 짧고 간결한 Perl은 스칼라 나 Haskell 코드가 그러한 언어를 경험 한 사람들이 읽을 수있는 것처럼 Perl 프로그래머에게 매우 읽기 쉽습니다. 나는 또한 문법적으로 완전히 정확한 매우 복잡한 방식으로 독일어를 말할 수 있지만, 독일어에 능숙하더라도 여전히 단어를 이해하지 못합니다. 그것은 독일의 잘못이 아닙니다. ;)
simbabque

Java에서는 메소드를 "식별"하지 않습니다. 그것을 호출합니다. Object::toString방법을 식별합니다.
njzk2

10

구문은 의미 체계를 따르므로 의미 체계부터 시작하겠습니다.

함수 나 메소드를 사용하는 방법은 무엇입니까?

실제로 여러 가지 방법이 있습니다.

  • 인수와 함께 또는 인수없이 함수를 호출 할 수 있습니다.
  • 함수는 값으로 취급 될 수있다
  • 함수를 부분적으로 적용 할 수 있습니다 (적어도 하나 이상의 인수를 가져와 전달 된 인수를 닫는 클로저 작성)

서로 다른 용도로 비슷한 구문을 사용하는 것이 모호한 언어를 만들거나 최소한 혼란스러운 언어를 만드는 가장 좋은 방법입니다 (그리고 우리는 그 언어를 충분히 가지고 있습니다).

C 및 C와 유사한 언어에서 :

  • 괄호를 사용하여 함수를 호출하면 다음과 같이 인수가 포함됩니다 (없음). func()
  • 함수를 값으로 취급하는 것은 &func(C 함수 포인터 만들기) 에서와 같이 단순히 이름을 사용하여 수행 할 수 있습니다
  • 일부 언어에서는 부분적으로 적용하기위한 간단한 구문이 있습니다. Java는 someVariable::someMethod예를 들어 허용 합니다 (메소드 수신기로 제한되지만 여전히 유용합니다)

각 사용법에 다른 구문이있어 쉽게 구분할 수 있습니다.


2
글쎄, "쉽게"는 "이미 이해 된 경우에만 분명합니다"상황 중 하나입니다. 초보자는 왜 어떤 문장 부호가 그 의미를 갖는지 설명없이 분명하지 않다는 점을 전적으로 정당화 할 것입니다.
Eric Lippert

2
@EricLippert : 실제로 쉽게 직관적 인 것은 아닙니다. 이 경우 괄호가 수학에서 함수 "호출"에도 사용된다는 점을 지적합니다. 즉, 많은 언어로 된 초보자는 일반적으로 구문보다 개념 / 의미론에 더 많은 어려움을 겪고 있습니다.
Matthieu M.

이 답변은 "커링"과 "부분 적용" 의 차이점을 혼동합니다 . ::Java 의 연산자는 카레 연산자가 아닌 부분 응용 프로그램 연산자입니다. 부분 응용 프로그램은 함수와 하나 이상의 값을 가져와 더 적은 값을 허용하는 함수를 반환하는 작업입니다. 카레는 값이 아닌 함수에서만 작동합니다.
Periata Breatta

@PeriataBreatta : 좋은 지적, 고정.
Matthieu M.

8

부작용이있는 언어에서는 변수의 (이론적으로 부작용이없는) 독서를 구별하는 것이 실제로 도움이됩니다.

variable

부작용을 일으킬 수있는 함수 호출

launch_nukes()

OTOH, (유형 시스템에서 인코딩 된 것 이외의) 부작용이 없다면, 변수를 읽는 것과 인수없이 함수를 호출하는 것까지 구별 할 필요가 없습니다.


1
OP는 개체가 유일한 인수이고 함수 이름 앞에 표시되는 경우 (함수 이름의 범위도 제공)를 나타냅니다. noun.verb구문은 의미가 명확 noun.verb()하고 약간 덜 어수선 해질 수 있습니다 . 마찬가지로, 함수 member_왼쪽 참조를 반환 전형적인 setter 함수보다 편리한 구문 제공 될 수 있습니다 obj.member_ = new_value대를 obj.set_member(new_value)합니다 ( _후위 말을 힌트 "노출"을 연상 _ 접두사 "숨겨진"기능).
Paul A. Clayton 1

1
@ PaulA.Clayton 나는 이것이 내 대답으로 어떻게 다루어지지 않는지 알지 못한다 : noun.verb함수 호출을 의미 한다면 , 단순한 멤버 액세스와 어떻게 구별합니까?
Daniel Jour

1
이론적으로 부작용이없는 변수를 읽는 것과 관련하여 나는 단지 다음과 같이 말하고 싶습니다. 항상 거짓 친구를 조심하십시오 .
저스틴 타임

8

다른 대답은 질문을 해결하려고 시도하지 않았습니다. 언어 디자인에 얼마나 많은 중복성이 있어야합니까? x = sqrt yx를 y의 제곱근으로 설정 하는 언어를 설계 할 수 있다고해서 반드시 그럴 필요는 없습니다.

중복성이없는 언어에서 모든 문자 시퀀스는 무언가를 의미합니다. 즉, 실수를 한 번만해도 오류 메시지가 표시되지 않으면 프로그램이 잘못된 작업을 수행하므로 프로그램이 사용자와 다른 작업을 수행 할 수 있습니다 의도하고 디버깅하기가 매우 어렵습니다. (정규 표현식으로 작업 한 사람이라면 누구나 알 수 있습니다.) 약간의 중복성은 많은 오류를 감지 할 수 있고 중복성이 많을수록 진단이 정확할 가능성이 높으므로 좋은 것입니다. 물론, 당신은 그것을 너무 멀리 가져갈 수 있습니다 (요즘 우리 중 아무도 COBOL로 글을 쓰고 싶지 않습니다). 그러나 균형이 맞습니다.

더 많은 단서가 있기 때문에 중복성은 가독성에 도움이됩니다. 중복성이없는 영어는 읽기가 매우 어렵고 프로그래밍 언어에서도 마찬가지입니다.


어떤 의미에서 나는 프로그래밍 언어에 "안전망"메커니즘이 있어야한다는 데 동의한다. 그러나 나는 구문에서 "약간의 중복성"이 그것을 다루는 좋은 방법이라는 것에 동의하지 않는다. 즉 , 상용구 이며, 주로하는 것은 오류를 발견하기 어렵게 만드는 잡음을 도입하고 구문 오류를 분산시키는 구문 오류의 가능성을 열어 준다 실제 버그. 가독성을 돕는 자세한 종류는 구문과 거의 관련이 없으며 명명 규칙과 관련이 있습니다. 그리고 안전망은 강력한 유형 시스템 으로 가장 효율적으로 구현되며, 대부분의 무작위 변경으로 인해 프로그램이 잘못 입력됩니다.
leftaroundabout

@leftaroundabout : 해밍 거리 측면에서 언어 디자인 결정에 대해 생각하고 싶습니다. 두 구조가 다른 의미를 갖는 경우, 적어도 두 가지 방식이 다르고 컴파일러 스 쿼크를 생성하는 한 가지 방식 만 다른 형식을 갖는 것이 종종 도움이됩니다. 언어 디자이너는 일반적으로 식별자를 쉽게 식별 할 수 있도록 할 책임이 없지만 컴파일 타임 초기화에만 사용할 수있는 할당이 필요 :=하고 비교 ==하는 =경우 오타가 비교를 할당으로 바꿀 가능성이 크게 줄어 듭니다.
supercat

@leftaroundabout : 나는 언어를 설계 할 경우 마찬가지로, 내가 필요로 가능성 것이다 ()제로 인수 함수의 호출뿐만 아니라 기능 "의 주소를 가지고"하는 토큰을 필요로한다. 전자의 행동이 훨씬 더 일반적이기 때문에 덜 일반적인 경우에 토큰을 저장하는 것이 그다지 유용한 것은 아닙니다.
supercat

@ supercat : 글쎄, 다시 말하면 이것이 잘못된 수준의 문제를 해결하고 있다고 생각합니다. 할당과 비교는 개념적으로 다른 작업이므로 각각 기능 평가와 기능을 수행합니다. 따라서 명확하게 구별되는 유형을 가져야하며, 오타가 컴파일 타임 유형 오류이기 때문에 운영자가 해밍 거리가 낮은 경우 더 이상 중요하지 않습니다.
leftaroundabout

@leftaroundabout : 부울 타입 변수에 대입을하거나 함수의 반환 형식이 함수 (또는 일부 언어에서는 실제 함수)를 가리키는 포인터 인 경우, 또는 함수 참조로 함수를 호출하면 구문 적으로 유효하지만 원래 버전과는 완전히 다른 프로그램을 생성 할 수 있습니다. 유형 검사는 일반적으로 이러한 오류를 발견하지만 구문을 구별하는 것이 더 나은 접근법처럼 보입니다.
supercat

5

대부분의 경우 언어 문법에 대한 구문 선택입니다. 다양한 개별 구성체가 모두 함께 취해질 때 (상대적으로) 모호하지 않은 문법에 유용합니다. (일부 C ++ 선언과 같이 모호한 부분이 있으면 해결을위한 특정 규칙이 있어야합니다.) 컴파일러에는 추측 할 수있는 위도가 없습니다. 언어 사양을 따라야합니다.


Visual Basic은 다양한 형태로 값을 반환하지 않는 프로 시저와 함수를 구분합니다.

프로시 저는 명령문으로 호출해야하며 괄호가 필요하지 않으며 쉼표로 구분 된 인수 (있는 경우) 만 필요합니다. 함수는 표현식의 일부로 호출되어야하며, parens가 필요합니다.

두 가지 형식 사이의 수동 리팩토링이 이전보다 더 고통스럽게 만드는 것은 상대적으로 불필요한 구별입니다.

(반면에 Visual Basic의이 같은 괄호 사용하는 ()우리는 다른 언어를 사용 숙고 수, 함수 호출에 같은 배열 참조를 들어, 그래서 배열 참조는 함수 호출처럼 보인다. 그리고 이것은 함수 호출에 배열의 수동 리팩토링을 용이하게! 그래서 []'에게들 배열 참조를 위해, 그러나 나는 digress ...)


C 및 C ++ 언어에서 변수의 내용은 이름을 사용하여 자동으로 액세스되며, 내용 대신 변수 자체를 참조하려면 단항 &연산자 를 적용하십시오 .

이러한 종류의 메커니즘은 함수 이름에도 적용될 수 있습니다. 원시 함수 이름은 함수 호출을 의미 할 수 있지만 단항 &연산자는 함수 (자체)를 데이터로 참조하는 데 사용됩니다. 개인적으로 변수와 같은 구문으로 부작용이없는 인수없는 함수에 액세스한다는 아이디어가 마음에 듭니다.

이것은 다른 구문 선택과 마찬가지로 완벽하게 그럴듯합니다.


2
프로 시저 호출에 괄호를 시각적으로 기본의 부족은 함수 호출에 비해 불필요한 구분, 반면 물론, 그들에게 필요한 괄호를 추가하면 사이의 불필요한 구분 될 것이다 매우있는 효과가 많은 BASIC에서 파생 된 언어로있는, 절차를 연상시키는. MS BASIC 버전에서 작업을 한 이후에도 오랜 시간이 걸렸지 만 여전히 구문을 허용하지 call <procedure name> (<arguments>)않습니까? 다른 생애에서 QuickBASIC 프로그래밍을했을 때 프로 시저를 다시 사용하는 것이 올바른 방법이라고 확신합니다.
Periata Breatta

1
@PeriataBreatta : VB는 여전히 "호출"구문을 허용하며, 호출해야 할 것이 표현식 인 경우 (예 : "Call If (someCondition, Delegate1, Delegate2) (Arguments)"라고 말할 수 있지만 직접 "If"연산자의 결과 호출은 독립형 명령문으로 유효하지 않습니다].
supercat

@PeriataBreatta VB6의 괄호 절차 호출이 DSL과 같은 코드를 좋게 보이기 때문에 좋아했습니다.
Mark Hurd

@supercat LinqPad에서는 Call"정상"생산 코드에서 거의 필요하지 않은 방법에 얼마나 자주 사용해야하는지 놀랍습니다 .
Mark Hurd

5

일관성과 가독성.

다음 X과 같이 함수를 호출한다는 것을 알게되면 X(arg1, arg2, ...)인수없이 동일한 방식으로 작동 할 것으로 기대합니다 X().

이제 동시에 변수를 기호로 정의하고 다음과 같이 사용할 수 있음을 알게되었습니다.

a = 5
b = a
...

이걸 찾으면 어떻게 생각할까요?

c = X

당신의 추측은 나의 것만 큼 좋습니다. 정상적인 상황에서는 X변수입니다. 그러나 우리가 당신의 길을 가야한다면 그것은 또한 기능 일 수 있습니다! 어떤 심볼이 어떤 그룹 (변수 / 기능)에 매핑되는지 기억해야합니까?

"함수는 대문자로 시작합니다. 변수는 소문자로 시작합니다"와 같은 인공적인 제약 조건을 적용 할 수 있지만, 때로는 디자인 목표 중 일부에 도움이 될 수 있지만 불필요하고 일이 더 복잡해집니다.

참고 1 : 다른 답변은 한 가지 이상을 완전히 무시합니다. 언어를 사용하면 함수와 변수에 동일한 이름을 사용하고 상황에 따라 구별 할 수 있습니다. 참조 Common Lisp예를 들어. 함수 x와 변수는 x완벽하게 공존합니다.

참고 2 : 허용되는 답변은 다음과 같은 구문을 보여줍니다 object.functionname. 첫째, 일류 함수를 가진 언어에는 보편적이지 않습니다. 둘째, 프로그래머로서 나는 이것을 추가 정보로 취급 functionname합니다 object. 여부는 object객체, 클래스 또는 네임 스페이스는 많은 문제가되지 않지만, 자신이 속한 하더군요 . 즉 object., 각 전역 함수에 인공 구문 을 추가 하거나 object모든 전역 함수를 보유 할 일부 구문 을 작성 해야합니다.

어느 쪽이든 함수와 변수에 대해 별도의 네임 스페이스를 가질 수있는 능력을 잃게됩니다.


예. 일관성은 충분한 이유, 완전 정지 (다른 지점이 유효하지 않다는 점이 아님)입니다.
Matthew 읽기

4

다른 답변에 추가하려면 다음 C 예제를 사용하십시오.

void *func_factory(void)
{
        return 0;
}

void *(*ff)(void);

void example()
{
        ff = func_factory;
        ff = func_factory();
}

호출 연산자가 선택 사항 인 경우 함수 지정과 함수 호출을 구별 할 방법이 없습니다.

타입 유추를 사용하여 함수가 무엇인지, 함수가 아닌지를 알아낼 수없는 JavaScript와 같은 타입 시스템이없는 언어에서는 더욱 문제가됩니다.


3
JavaScript에는 형식 시스템이 없습니다. 타입 선언 이 없다 . 그러나 서로 다른 유형의 가치의 차이를 완전히 알고 있습니다.
Periata Breatta

1
Periata Breatta : 요점은 Java 변수 및 속성에 값의 유형이 포함될 수 있으므로 코드를 읽을 때 함수인지 여부를 항상 알 수는 없습니다.
reinierpost

예를 들어,이 기능은 무엇을합니까? function cross(a, b) { return a + b; }
Mark K Cowan

@MarkKCowan 다음과 같습니다 : ecma-international.org/ecma-262/6.0/…
curiousdannii
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.