퍼스트 클래스 기능


11

나는 이번 주말에 Lisp를 진지하게 살펴보기 시작했습니다. (이것은 Lisp를 배우고 C #에서 프로젝트로 되돌아 가지 않는 것을 의미합니다) 그것을 좋아한다고 말해야합니다. 나는 다른 기능적 언어들 (F #, Haskell, Erlang)과 관련이 있지만 Lisp이 내게 준 그림을 느끼지 못했습니다.

이제 Lisp을 계속 배우면서 비 기능 언어가 일급 기능을 지원하지 않는 이유가 궁금해졌습니다. C #과 같은 언어는 대리자와 비슷한 작업을 수행 할 수 있으며 C / C ++에서 함수에 대한 포인터를 사용할 수있는 정도이지만 이러한 언어에서 결코 기능이되지 않는 이유가 있습니까? 함수를 일류로 만드는 데 단점이 있습니까? 나에게 그것은 매우 유용하므로 더 많은 언어 (기능 패러다임 외부)가 그것을 구현하지 않는 이유에 대해 잃어 버렸습니다.

[편집] 지금까지 답변을 주셔서 감사합니다. 현재 많은 언어가 이제 일류 함수를 지원한다는 것을 알았으므로 언어가이를 구현하는 데 시간이 오래 걸리는 이유는 무엇입니까? [/편집하다]


3
C #이 "유사한 일"을 할 수 있다는 데 동의하지 않습니다. 나는 그것이 모든 의도와 목적 (일종의 전제를 망칠 것)을위한 일류 기능을 가지고 있다고 말하고 싶습니다. 함수 리터럴에 대한 구문이 있으며 함수를 변수 등에 넣을 수 있습니다.
Logan Capaldo

@ Logan-C # 예제 포함 여부에 대해 토론했지만 이 위키 백과 항목 을 기반으로하기로 결정했습니다 . 엔트리에 따르면, "함수의 동적 상태를 유지하는 객체는 수동으로 구성되어야하기 때문에"진정한 일류 함수는 없습니다. 그러나 그것이 잘못된 진술이라면, 나는 왜 그런지 알고 싶습니다! (결국, 나는 배우고 내 길에 갇히지 않기 위해 여기에 있습니다!)
Jetti

2
위키 백과 항목이 오래되었습니다. 현대 C #은 적절한 람다를 제공합니다.
SK-logic

나는 문단이 제대로 작성되지 않았다고 생각합니다. C ++ functors가 일류가 아니며 C # 대리자가 아니라고 말하는 것 같습니다. functors에 대한 논쟁에 동의 할 수도 있지만 C # 델리게이트에 대해서는 확실하지 않습니다. 또한 "(람다 리프팅 참조)"라고되어 있는데, 이는 "값으로서의 기능"보다는 어휘 폐쇄를 지원하는 이러한 언어에 대한 진술입니다. 다른 하나없이 가질 수 있습니다. 이 경우에도 C #에는 해당되지 않지만 어휘 폐쇄가 있습니다. 문제의 일부는 "일류 함수"가 모호한 용어 일 수 있다는 것입니다.
Logan Capaldo

1
@Logan & SK-Logic-의견을 보내 주셔서 감사합니다. 나는 아직도 배우고 있으며 타지 않는 것이 매우 좋습니다. 그래서 고맙습니다. 의견과 답변에 대단히 감사합니다!
Jetti

답변:


5

C #, VB.NET, Python, JavaScript, 심지어 C ++ 0x조차도 일류 함수를 제공합니다.

최신 정보:

클로저를 구현하려면 람다 리프팅이 필요합니다. 람다 리프팅은 명령형 프로그래머에게는 원래 외계인 기술입니다. 적절한 일류 함수 (클로저 포함)에는 런타임 및 VM의 지원이 최소한 필요합니다. 또한 오래된 기능 기술을 명령형 세계에 적용하는 데 시간이 걸렸습니다.

그리고 가장 중요한 부분-가비지 수집이 없으면 일류 함수를 거의 사용할 수 없습니다. Java 및 결과적으로 .NET을 사용하여 최근에야 대량 프로그래밍에 도입되었습니다. 그리고 원래 Java 접근 방식은 일반 코더가 언어를 이해할 수 있도록 언어를 지나치게 단순화하는 것이 었습니다. .NET은 처음에 왔으며 최근에는 (IMHO, 정당화되고 적절한) 방향에서 나왔습니다.

이러한 모든 개념은 업계에서 소화하는 데 시간이 걸립니다.


응답을 기반으로 원래 질문을 편집했습니다.
Jetti

일급 함수! = 클로저 (그리고 후자는 GC가 훨씬 더 필요합니다). 그렇습니다. 그것들은 밀접한 관련이 있지만 당신은 거의 분리되지 않습니다.

@delnan은 어휘 클로저 함수의 형태가 없어도 런타임에 구성 할 수없고 구성 할 수 없으므로 일류 함수 정의에 필수입니다.
SK-logic

아니요. 둘러싸는 범위의 변수를 참조하는 것을 허용하지 않을 수 있습니다 (또는 함수 생성시 참조 된 변수의 값을 복사하십시오-이것이 클로저로 간주되는 경우 dunno). 결과는 특별히 유용하지는 않지만 런타임에 클로저 없이도 함수를 구성 할 수 있으므로 (이상한) 일류 함수가 있습니다.

1
@ SK-logic : C ++ 0x는 일반적인 트릭으로 가비지 수집없이 클로저를 제공합니다-> 변수가 범위를 벗어나도 여전히 참조에 집착하는 경우 참조는 정의되지 않은 동작입니다. 그래서 가능합니다 ... 그것은 개발자에게 호 너스를 넣습니다.
Matthieu M.

5

일류 함수는 클로저 없이는 훨씬 덜 흥미 롭습니다.

동적 범위 관리 (가비지 수집)가 없으면 클로저를 실제로 사용할 수 없습니다. C / C ++의 성능을 높이는 것 중 하나는 메모리를 수동으로 관리하는 언어를 컴파일하기가 훨씬 쉬워서 C / C ++를 방정식에서 제외시키는 것입니다.

그렇습니다. OOP 영향의 문제가 있습니다. 더 이상 메소드와 특성을 분리하지 않아도됩니다. 메서드 자체는 함수를 값으로 받아들이는 속성입니다. 그런 맥락에서, 당신은 언제라도 바보 같은 것들을 바꿀 수 있기 때문에 메소드를 오버로드한다는 것은 실제로 무엇을 의미합니까? 예를 들어, 전체 언어에 큰 패러다임 전환을 도입하지 않고도 Java에 실제로 추가 할 수 있습니까? 사람들이 그 구조가 항상 항상 같은 방식으로 작동한다는 것을 보장한다는 것을 알면 계약이나 그 의미 (IMO False) 보안의 의미는 어디입니까? 객체에 묶인 함수를 메소드로서 다른 유기체로 취급하는 것은 언어에서 함수가 처음에는 독립적으로 존재하지만 실제로는 옵션이 아닌 Java에서는 독립적으로 존재할 수 있습니다.

JavaScript에서 OOP와 기능은 매우 밀접하게 관련되어 있으며 개인적으로 일류 펑크를 그렇지 않은 언어로 묶어 놓는 것이 아니라고 생각합니다. 그러나 그것은 객체와 그 메소드 자체의 높은 수준의 변경 가능성뿐만 아니라 마치 마치 마치 마치 객체의 멤버 인 것처럼 함수를 호출 할 수있는 등 패러다임의 변화를 필요로합니다.

언어는 대부분의 작업을 수행하기위한 도구로만 구성된 도구가 아닙니다. 그들은 패러다임입니다. 연결된 모든 (또는 연결된 것처럼 보이는) 방식으로 모든 종류의 아이디어, 전략 및 의견 묶음. 많은 경우 명사 및 동사와 같은 기능은 실제로 패러다임에 전혀 맞지 않거나 전혀 적합하지 않습니다.

즉, 코드없이 코딩해야 할 때 팔이 빠진 것 같습니다.


모든 방법을 봉인 된 것으로 취급하거나 가장 관심있는 방법을 봉인하면 괜찮습니다.
Alexei Averchenko

@AlexeiAverchenko 나는 당신이 그 말의 의미를 100 % 확신하지 못한다고 기쁘게 생각합니다. 죄송합니다. 지금까지 귀하의 의견을 놓쳤습니다. 인터넷 검색 "밀봉 된 방법"
Erik Reppen 2016 년

4

정말 불가능하지 않습니다. 그러나 이것은 또 다른 기능이며 복잡성 예산은 제한적입니다. 언어 디자이너는 "필요하지 않은 이유는 무엇일까요?이 언어는 OS 프로그래밍을위한 것입니다!" 나머지 언어와 병합하려면 상당한 노력이 필요할 수 있습니다. 예를 들어, 오버로드가있는 경우 함수 유형에 유형 시스템 (예 : Java)을 심각하게 추가해야 할 수도 있습니다 (@Renesis가이를 지적 해 주셔서 감사합니다). 또한 실행 가능한 라이브러리를 제공해야 map합니다. 아무도 자신을 정의 하고 싶지 않습니다.

또한 언어의 다른 목표를 달성하기가 더 어려워 질 수 있습니다.

  • 최적화하는 것이 "어려워"집니다 (실제로는 어렵지 않지만 익숙한 방법과는 다른 방법이 필요합니다). 예를 들어, 전역 함수를 재 할당 할 수있는 경우 f인라인하기 전에 해당 기능 이 재 할당되지 않음 을 증명해야 합니다.
  • 비슷한 맥락에서 함수를 완벽하게 갖춘 객체를 만드는 경우, 그와 관련된 오버 헤드를 제거하고 인수 및 반환 주소를 푸시하고 점프 하는 것처럼 효율적인 (속도 공간 방향) 호출을 수행하려면 스마트 컴파일러와 JIT가 필요 합니다. 일부 주소.
  • 이미 언급했듯이, 그것은 또 다른 완전한 기능이며 또 다른 패러다임을 지원하기위한 첫 번째 단계입니다. 단순한 언어를 원한다면 다른 것을 던지지 않고 일류 함수를 추가 할 여유없을 것입니다 (더 중요하게 생각할 수 있습니다) 밖.
  • 아마도 그것은 다른 언어와 잘 어울리지 않을 것입니다. 스몰 토크 이후 OOP의 최상의 화신이되도록 언어를 디자인한다면, 매우 다른 패러다임을 제공하는 대신에 그 언어에 집중할 수 있습니다. 특히 두 가지를 통합하기 어려운 경우 (위 참조). N 패러다임은 N + 1 패러다임보다 나쁘게 프로그래밍하는 것보다 프로그래밍이 더 즐겁습니다.

같은 맥락에서 어떤 프로그래밍 언어 L1에 매우 다른 언어 L2의 기능 F가 없는지 묻습니다.


1

첫 번째 문제는 객체 지향과 기능을 혼합 할 수 없다는 오해라고 생각합니다. JavaScript , ActionScript , Python , C # , F # 과 같이 Wikipedia에 의해 설명 된 빠른 언어 목록 .

두 번째 문제는 일급 함수 의 정의 인 것 같습니다. 예를 들어 C #을 고려하지 않는 이유는 무엇입니까?

나는 기능적 언어 전문가가 아니므로 내가 틀렸다면 의견을 수정 해주십시오. 그러나 제 이해는 일류 함수 자체를 포함하는 것이 언어가 기능적 패러다임을 지원하는지 여부를 정의한다는 것 입니다.

진짜 질문은 무엇입니까?

따라서 객체 지향 언어 도 작동 할 수 있으며 이러한 언어에는 일류 함수가 포함되어 있다는 것을 이해하면 원하는 객체 지향 언어 일류 함수를 포함 하지 않는 이유는 무엇입니까?

기능 과부하

주요한 이유 중 하나는 언어가 함수 오버로딩 을 지원하도록 선택한 경우 (예 : Java의 경우) 퍼스트 클래스 함수를 정의하기가 어렵다는 것입니다 .

public int dispatchEvent(Event event);
public int dispatchEvent(String event, Object data);

dispatchEvent변수는 어떤 함수를 참조합니까?

클래스 기반 프로그래밍

클래스 기반 프로그래밍은 언어가 일류 객체를 지원하는 것을 방해하지는 않지만 더 혼란 스럽거나 질문에 대한 답변을 추가 할 수 있습니다.

예를 들어 ECMAScript 언어로서의 ActionScript는 JavaScript와 같은 훨씬 더 기능적인 패러다임에서 시작되었습니다. 함수는 본질적으로 객체에 바인딩되지 않았으므로 실행 시점의 범위이므로 본질적으로 모든 객체와 함께 호출 될 수 있습니다.

(비 동적) 클래스를 추가 하면 클래스 자체가 아니라 인스턴스에 본질적으로 바인딩 된 함수가 있습니다. 이것은 Function.apply내가 어떻게 처리했는지 알아 내기 위해 정직하게 파지 않은 사양에 약간의 주름을 던졌습니다 .


3
"일류 함수 자체를 포함하면 언어가 기능적으로 작동합니다." - 잘못된. 전제 조건입니다. 예. 그러나 변경 가능한 상태, 순차적 진술보다는 표현식 및 함수 적용에 중점을두고 참조 투명성에 중점을 두지 않는 것과 같이 (단지 세 가지 이름으로) 더 많은 것이 있습니다.

@delnan 그 다음에 올바른 Wikipedia로 가야합니다 ... "기능적 언어"와 "기능적 패러다임을 지원하는 언어"가 다른 두 가지가 아니라면.
니콜

1
@ Rensis : 그들은 다른 것들입니다. C에서 객체 (vtables 포함)와 같은 것을 만들 수는 있지만 예쁘지 않습니다. "일류 함수를 가지고있다"에서 "기능적인 언어"로가는 것은 그리 나쁘지는 않지만 여전히 차이가 있습니다. 또한, "위의 기능은 함수형 프로그래밍 스타일 [...]에 필수적 입니다." (예 : "정의 기능"아님) 및 FP 페이지의 다른 여러 기능을 나열합니다.

@delnan, 알았어, 나는 내 말을 고쳤다. 방금 나열된 언어 각각에 대한 Wikipedia 페이지와 마찬가지로 언어가 기능적 패러다임을 지원하는 것으로 간주되는 조건을 의미했습니다. 그게 기능 프로그래밍 스타일 의 일부라고 말하는 것은 아닙니다 .
Nicole

0

나는 같은 것을 스스로 궁금해했다. 람다가있는 언어에 있으면 나는 그들을 많이 사용합니다. PHP 5.3으로 클로저를 할 수 있다는 것을 알면 PHP조차도 좋아집니다 (리프만큼 좋지는 않지만 여전히 더 좋습니다)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.