자바 스크립트는 함수형 프로그래밍 언어입니까?


34
  • 자바 스크립트는 기능적인 언어입니까? 나는 그것이 객체를 가지고 있다는 것을 알고 당신도 그것으로 OOP를 할 수 있지만, 그것은 또한 기능적인 언어입니까, 그런 식으로 사용될 수 있습니까?
  • OOP가 프로그래밍의 다음 진화처럼 어떻게 보 였는지, 그것이 '기능 프로그래밍'이 다음 진화라는 것을 의미합니까? 기여자보다 중재자를 위해 더 많은;)).
  • 나는 예제를 통해 가장 잘 배웁니다. 어쩌면 누군가가 OOP 방식으로 동일한 작업을 수행 한 다음 기능적 프로그래밍 방식으로 기능적 프로그래밍의 기능을 이해하고 비교할 수 있습니다.

나는 '함수 프로그래밍'이 정직하다는 것을 완전히 이해하지 못한다. : P 자바 스크립트를 함수형 프로그래밍과 비교하는 것은 완전히 틀릴 수있다.

함수형 프로그래밍을 평신도 용어로 사용하려면 익명 함수를 사용하여 단순히 중단의 이점이 있습니까?

아니면 너무 간단한가요? 간단한 방법으로 OOP는 객체를 통한 추상화의 이점이지만 OOP를 설명하기에는 너무 단순하다고 생각합니다.

이것이 함수형 프로그래밍의 좋은 예입니까? ...

자바 스크립트 OOP 예 :

// sum some numbers
function Number( v )
{ 
  this.val = v;
}

Number.prototype.add( /*Number*/ n2 )
{
    this.val += n2.val;
}

기능적 프로그래밍 예 :

function forEach(array, action) 
{
   for (var i = 0; i < array.length; i++)
       action(array[i]);
}  

function add(array)
{
    var i=0;
    forEach(array, function(n)
    {
        i += n;
    });
    return i;
}

var res = add([1,9]);

"함수 프로그래밍 언어"의 정의에 따라 다릅니다. 넓은 의미에서 닫힌 값으로 기능적 값을 작성하는 능력, 즉 "람다"구조 (람다 미적분의 의미로)를 갖는 것으로 이해 될 수 있으며, 그런 다음 자바 스크립트가 계산에 적합합니다.
Basile Starynkevitch

2
Or is that way too simple?그렇습니다. 익명 함수는 때때로 함수형 프로그래밍을 선호하는 함수형 언어 및 다중 패러다임 언어와 관련이 있지만 함수형 언어의 고유 한 특성은 아닙니다. 그러나 그것들을 λ- 미적분의 구현으로 보면, 그것들은 함수형 프로그래밍의 핵심 부분입니다. 요점은 그것이 그렇게 간단하지 않다는 것입니다. :)
yannis

Javascript의 디자인은 구현이 테일 콜 최적화를 수행 할 수 없도록합니다. 내 책에서는 혼자서 기능적이라고 표시되지 않습니다.
dan_waterworth

I know it has objects & you can do OOP with it also아냐, 못해 클래스와 객체를 구분하지 않는 프로토 타입 기반 프로그래밍입니다. 개인적으로 저는이 기본 수준에서 프로토 타입 기반 프로그래밍에 결함이 있다고 생각합니다.
RokL

Javascript는 기능적 언어가 아니며 기능적 기능을 가지고 있지만 확실히 오래된 명령형 C도 있습니다. 실제로 모든 언어에는 기본 기능이 있습니다. Haskell, ML 등과 같은 순수한 기능적 언어는 명령형이 아닌 선언적 언어입니다.
ALXGTV

답변:


72

자바 스크립트는 기능적인 언어입니까? 나는 그것이 객체를 가지고 있다는 것을 알고 당신도 그것으로 OOP를 할 수 있지만, 그것은 또한 기능적인 언어입니까, 그런 식으로 사용될 수 있습니까?

때때로 사람들은 명령형 프로그래밍 또는 절차 적 프로그래밍 이라는 의미에서 기능적 프로그래밍을 말할 것 입니다. 엄밀히 말하면 기능 프로그래밍 은 다음과 같습니다.

컴퓨터 과학에서 기능 프로그래밍은 계산을 수학 함수의 평가로 취급하고 상태 및 변경 가능한 데이터를 피하는 프로그래밍 패러다임입니다 . 상태의 변화를 강조하는 명령형 프로그래밍 스타일과 달리 함수 적용을 강조합니다. 함수형 프로그래밍은 함수 정의, 함수 적용 및 재귀를 조사하기 위해 1930 년대에 개발 된 공식 시스템 인 람다 미적분학에 뿌리를두고 있습니다. 많은 함수형 프로그래밍 언어는 람다 미적분에 대한 정교한 것으로 볼 수 있습니다.

Javascript는 널리 알려 지거나 기능 언어로 사용되지는 않지만 몇 가지 기능 요소가 있습니다 .

JavaScript는 Scheme과 공통점이 많습니다. 역동적 인 언어입니다. s- 표현을 쉽게 시뮬레이션 할 수있는 유연한 데이터 유형 (배열)이 있습니다. 그리고 가장 중요한 것은 함수는 람다입니다.

SchemeLisp 의 방언이며 , 아마도 대부분의 프로그래머가 함수형 프로그래밍에 대해 생각할 때 생각하는 언어 중 하나 일 것입니다. 그것이 올 때 방향을 객체 , 자바 스크립트 객체 지향 언어입니다. 그러나 객체 방향은 프로토 타입 기반입니다 .

프로토 타입 기반 프로그래밍은 클래스가없는 객체 지향 프로그래밍 스타일이며 프로토 타입 역할을하는 기존 객체를 복제하는 프로세스를 통해 동작 재사용 (클래스 기반 언어의 상속이라고 함)이 수행됩니다. 이 모델은 클래스리스, 프로토 타입 지향 또는 인스턴스 기반 프로그래밍이라고도합니다. 위임은 프로토 타입 기반 프로그래밍을 지원하는 언어 기능입니다.

따라서 Javascript는 객체 지향적이지만 C ++, C #, Java 및 PHP와 같은 언어와 마찬가지로 다른 일반적인 클래스 기반 모델을 따르지 않습니다 . 물론 그것은 또한 명령형 언어이기 때문에 위에서 설명한 기능적 프로그래밍과 혼동됩니다.

OOP가 프로그래밍의 다음 진화와 같이 어떻게 보 였는지, 그것이 '기능 프로그래밍'이 다음 진화라는 것을 의미합니까?

객체 지향과 함수형 프로그래밍은 다양한 프로그래밍 패러다임 중 하나 일 뿐이며 , 개념과 추상화가 다른 다양한 스타일의 프로그래밍입니다. 핵심 단어는 "다른"입니다. 다른 것보다 낫거나 다른 것보다 더 진화 된 단일 패러다임은 없으며, 각각의 패러다임은 각각 다른 시나리오보다 더 나은 시나리오에 적합합니다. 일부는 다른 것보다 기원이 훨씬 더 길지만, 더 오래 생존할수록 더 나은 진화론 적 용어로 볼 수 있습니다. 그러나 그것은 그것을 보는 현명한 방법이 아닙니다.

위에서 설명한 다른 언어와 마찬가지로 Javascript는 다중 패러다임입니다. 명령형, 프로토 타입 기반 객체 지향 및 기능 스타일로 코드를 작성할 수 있습니다. 당신이 짓고있는 것에 가장 적합한 것을 선택하는 것은 당신에게 달려 있습니다. 몇 가지 단일 패러다임 언어가 있으며, 표준 예제는 Java이며 클래스 기반 객체 지향 프로그래밍 1 만 허용합니다 .

언어와 패러다임을 패션 문장으로 취급하려는 충동에 저항해야합니다. 프로그래밍에 대한 지식과 지식이 거의없는 팬보이 / 팬걸이나 마케팅 담당자가 작성하는 쓰레기가 많이 있습니다. "더 나은", "더 진화 된"등과 같은 용어는 적용되지 않습니다.

나는 예제를 통해 가장 잘 배웁니다. 어쩌면 누군가가 OOP 방식으로 동일한 작업을 수행 한 다음 기능적 프로그래밍 방식으로 기능적 프로그래밍의 기능을 이해하고 비교할 수 있습니다.

그것은 끔찍한 학습 방법이 될 것입니다. 기능 및 객체 방향은 스타일이 매우 다르며 매우 단순한 스타일 이외의 예는 하나 또는 다른 스타일에 맞지 않습니다.

1 그러나 최근에는 범위를 일반 프로그래밍으로 확장하려고 시도하지만 어떻게 진행되는지 봅시다.


결론적으로:

  • Javascript를 배우는 데 집중하면 아름답고 매우 유용한 언어입니다. 과대 광고가 아닌 언어를 배우십시오.
  • 상당히 다른 몇 가지 패러다임, 모두 똑같이 유용합니다. 당신이 원하는 것을 선택하고 당신이 짓는 것에 가장 적합한 것을 선택하십시오.
  • 함수형 프로그래밍을 배우려면 Scheme 또는 Clojure 와 같이 더 적합한 언어를 선택하십시오 . 그러나 먼저 관련된 수학적 개념을 이해해야합니다.
  • 묻기 전에 약간의 조사를하십시오. 대부분의 질문은 관련 Wikipedia 기사에 의해 답변됩니다. 연구 방법과 질문 방법을 아는 것은 모든 프로그래머에게 매우 중요한 기술입니다.

5
+1 훌륭한 반응. 프로그래밍 교육이 체계화되는 방식으로 인해 새로운 코더는 패러다임이 배타적이고 이산 적이라고 생각하는 것 같지만 그렇지 않습니다. 기능적 개념을 이용하는 OOP 코드를 작성해보십시오. 이벤트 중심 프로그래밍 은 패러다임이지만 EDP의 측면은 모든 GUI 및 웹 프로그램에 영향을줍니다. OOP의 핵심 기능인 다형성 은 실제로 일반적인 프로그래밍입니다. 이러한 아이디어의 이름을 지정하면 좋은 프로그래밍을 개념화하는 데 도움이되지만 다른 것을 배제하기 위해 하나를 사용해서는 안됩니다.
kojiro

원래 질문과 대답은 Javascript를 설명하고 함수 프로그래밍과 관련이 있지만, 당신의 대답은 내가 본 OO와 함수 프로그래밍 사이의 더 나은 비교 중 하나라고 생각합니다. 잘 했어.
AnotherDeveloper

"이것은 끔찍한 학습 방법이 될 것입니다."방금 문제를 제시하고 OOP 및 FP 스타일 ( github.com/crista/exercises-in-programming-style)을 포함한 다양한 패러다임으로이 책을 읽었습니다 . 나는 그것으로부터 많은 것을 배웠다!
Nick

@nick 패러다임의 모습과 작동 방식 만 설명 할 수 있지만 , 가장 중요한 측면 인지 는 설명 하지 않습니다 . 그러나 왜 :) 왜 우리는 이러한 것들이 과정이라는 것을 잊어 버릴 수 있는지 배우기 전에 알아야합니다.
매튜 브렌트

8

자바 스크립트는 기능적인 언어로 사용될 수 있으며, 실제로는 잘 작동합니다. 모나드 를 구현 하는 것은 람다 구문 등을 지원할 수 있습니다. 그것은 많은 객체 지향 기능을 가지고 있다는 점에서 기능적인 언어는 아니지만 그 방식으로 사용될 수 있습니다. 실제로 Javascript를 기능적 언어로 사용하는 것이 그것을 사용하는 좋은 방법이라는 것을 알았습니다. (예제 jQuery와 underscore.js)


좋고 간결한! 함수형 프로그래밍은 종종 js에서 작업을 수행하는 가장 쉬운 방법이라고 동의했습니다.
bunglestink

모나드보다 더 흥미로운 것은 화살표는 JS ( cs.umd.edu/projects/PL/arrowlets )를 구현할 수 있다는 것 입니다. 자, 왜 누군가가 JavaScript에서 화살표를 원할 것인지에 대해서는 공개 질문입니다. 그러나 할 수 있습니다.
rtperson

나는 그것이 화살표가 유용하다는 것을 알기에 충분하지 않다는 것을 인정할 것이다. 그러나 저는 Javascript로 Monads에 관한 책을 작업 중이며 Arrows에 대한 장을 추가 할 수 있습니다 ( shop.oreilly.com/product/0636920023890.do )
Zachary K

6

진화는 일반적으로 증분 변경을 의미합니다 . OOP는 절차 적 프로그래밍에 점진적으로 추가되지는 않습니다. 실제로 기본 프로그래밍 모델과 완전히 직교하며 이들과 결합 될 수 있습니다. 함수형 프로그래밍은 절차 적, OOP 또는 그 밖의 어떤 것에도 추가되지 않습니다. 기본 컴퓨팅 원리를 표현하기위한 대안 적 기초 이며 실제로 첫 번째 컴퓨터가 등장하기 훨씬 전에 공식화 된 첫 번째 기초입니다. 그러한 모든 기본 시스템이 동등하다는 것을 이해하는 것이 중요합니다 (즉, 하나는 다른 것으로 표현 될 수 있음).

기능적 접근 방식을 이해하려면 먼저 기본 수학 을 구해야합니다 . Javascript에서 기능적 스타일 로 코딩하는 것이 무엇을 의미하는지 느끼고 싶다면 jQuery 사용을 시작하십시오 .


2

아니.

JavaScript는 무엇보다도 객체 지향 언어입니다.

충분한 노력을 기울 이면 튜링 전체 언어로 기능적 스타일을 채택 할 수 있으므로 기능적 스타일로 JavaScript 프로그램을 작성할 수 없다는 것은 아닙니다 . 원하는 경우 어셈블러에서 기능 프로그래밍을 수행 할 수 있습니다. 그러나 이것이 모든 언어를 기능적으로 만드는 것은 아닙니다 . 하스켈 명령형 또는 Java를 논리 프로그래밍 언어라고도 부를 수 있습니다.이 접근 방식을 취하면 용어는 곧 의미가 없게됩니다.

IMO 언어를 적절한 패러다임으로 분류하는 방법은 다음을 고려하는 것입니다.

  • 언어 구조에 의해 가능하게 된 지배적 인 스타일은 무엇입니까 (JavaScript의 경우 분명히 OOP, 기능 언어는 대신 함수와 불변의 데이터 값을 강조합니다)
  • 언어의 핵심 라이브러리에서 지원되는 패러다임 (JavaScript 용 OOP)
  • 언어에서 비활성화 또는 권장하지 않는 기능 (기능 언어는 JavaScript의 경우가 아닌 가변 변수를 권장하지 않거나 금지 함)
  • 언어를 사용하는 개발자 커뮤니티에서 어떤 개발 스타일이 널리 퍼져 있습니까 (OOP는 JavaScript 세계에서 분명히 널리 퍼져 있습니다)

개인적으로 저는 언어를 주장하는 것을 좋아하는 많은 사람들이 현재 유행하는 용어이기 때문에 "기능적"이라고 생각합니다.

수년 동안 프로그래밍 패러다임에 대해 약간 길지만 재미있는 관점을 원한다면 Bob Martin 아저씨의 비디오 "The Last Programming Language"를 볼 가치가 있습니다. 저에게이 대화의 위대한 통찰은 프로그래밍 패러다임이 어떤 기능을 넣었는지가 아니라 어떤 기능을 제거하는지에 의해 정의된다는 것입니다.


What is the dominant style enabled by the language constructs나는 당신이 그것을 펄에 적용하려고 감히 ... 또는 당신의 다른 포인트, 정말로 :)
yannis

2
펄? 좋은 도전입니다! 그것은 당신이 원하는 거의 모든 패러다임을 해킹 할 수 있다는 점에서 어셈블리 언어와 다소 비슷하지만, 내가 보았던 (일반적인) 사용법은 주로 명령형 / 절차 적 언어로 사용됩니다.
mikera

글쎄, 죄송합니다. 당연히. 그리고 드물지만 기능적 입니다. perl은 단지 perl이다. 그것을 이해하려고 노력하는 것은 의미가 없다. :)
yannis

JavaScript는 최소한 클로저와 퍼스트 클래스 함수를 가지고 있기 때문에 Java보다 약간 더 기능적입니다. 그러나 귀하의 권리, JavaScript는 C #만큼 기능적입니다.
Raynos 2012 년

2

Javascript는 프로토 타입 우선이며, 기능을 1 급 객체로 사용함으로써 부여 된 기능적 기능을 제공합니다.

즉, 함수를 데이터로 사용할 수 있으므로 상태를 유지하는 변수의 필요성이 줄어드는 흥미로운 효과가 있습니다. var 문에 도달하거나 하나 이상의 "if"문을 사용하고 있다면 기능적 스타일에서 벗어나고있는 것입니다.

기능적 스타일의 또 다른 특유한 특징은 함수가 평가 결과 만 반환해야하며 범위를 벗어난 상태에는 부작용이 없어야한다는 것입니다.

// oops, this is producing a side effect
function sideEffecter(){//theres no input...        
    window.thingy = 'foo';
    // hey, this isn't returning anything!!!
} 

기능적 언어는 비파괴 적이므로 입력을 변경하지 않고 입력을 기반으로 완전히 새로운 데이터를 반환합니다. 이 스레드를 참조하십시오 : https : //.com/questions/749084/jquery-map-vs-each

기능적 언어는 또한 목록 / 컬렉션을 처리하는 "map", "fold", "reduce"와 같은 이름을 가진 많은 방법을 공통적으로 갖추고 있습니다. JS에서는 다른 언어와 달리 이러한 언어를 수동으로 만들어야 합니다. 최신 JS 구현에는 이러한 기능 중 일부가 포함되어 있지만 일부 예제 는 underscore.js 와 같은 라이브러리를 참조하십시오 .

명심해야 할 중요한 점 (IMO)은 JS가 일부 기능적 패턴을 활용할 수 있지만 항상 실행할 수있는 것은 아니라는 것입니다.

예를 들어 배열을 반복하십시오. 기능적 스타일이나 기본 루프 구조를 사용하여이 작업을 수행 할 수 있으며 일반적으로 루프 성능이 우수합니다. 이 예를 들어보십시오. 크기가 커지는 루프로 맞추고 다른 브라우저에서 실행 시간을 기록하십시오 (이미 이미 수행했지만 벤치 마크를 잃어 버렸습니다-죄송합니다!) :

var test = ['foo', 'bar', 'baz'], removeFunc, removeLoop;

//(semi)functional style...
// to be really functional each condition in the ternary would be another function
removeFunc = function(src, trg) {
    return src.length === 0 ? 
        src : 
            src[0] === trg ? 
                src.slice(1) : 
                    [src[0]].concat(removeFunc(src.slice(1), trg));
};

//but this is faster
removeLoop = function(src, trg){
    var len = src.length, // using variables to represent state...
        i=0, 
        result = [];        
    while(i < n){
       if(src[i] !== trg){
          result.push(src[i]);
       }
       i = i+1;
    }
}

또한, 기능적인 구조를 사용하여 상당한 크기의 루프에 도달하고 특정 형태의 임시 스택 관리를 사용하지 않는 경우 스택을 오버플로 할 수 있습니다 (공평하기는하지만이를 위해서는 BIG 목록이 필요합니다. ..). Node.js 환경에서 작업하는 경우 분명히 고정 대상에 가깝지만 각 브라우저에서 변형 최적화를 혼합해야합니다.

Javascript에서 기능적 구성을 사용해서는 안된다는 말이 아닙니다. 환경과 관련된 구현의 제한 사항을 알고 있어야합니다.

관심있는 링크는 다음과 같습니다.

뛰어난 "Eloquent Javascript"의 Javascript 기능 프로그래밍에 대한 장

리틀 쉬머

내 친구가 Little Schemer를 기반으로 JS 라이브러리를 작성했습니다.

FP를 더 잘 이해하는 데 도움이되는 Scheme에 대한 유용한 자습서

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