순전히 기능적인 언어는 모듈성을 어떻게 처리합니까?


23

나는 객체 지향 배경에서 왔으며 클래스는 클래스를 추상화하여 레이어를 추상화하여 코드를 쉽게 재활용 할 수있게하여 객체를 만들거나 상속하는 데 사용할 수 있다는 것을 알게되었습니다.

예를 들어 동물 클래스를 가질 수 있고 그로부터 고양이와 개를 물려받으며 모두 동일한 특성을 상속받습니다. 그러한 하위 클래스에서 동물의 품종이나 이름을 지정할 수있는 객체를 만들 수 있습니다 그것의.
또는 클래스를 사용하여 약간 다른 것을 처리하거나 포함하는 동일한 코드의 여러 인스턴스를 지정할 수 있습니다. 검색 트리의 노드 또는 여러 개의 다른 데이터베이스 연결과 유사합니다.

최근에 함수형 프로그래밍으로 넘어 가고 있기 때문에 궁금해지기 시작했습니다.
순전히 함수형 언어는 어떻게 그런 것들을 처리합니까? 즉, 클래스와 객체 개념이없는 언어입니다.


1
기능이 클래스를 의미하지 않는다고 생각하는 이유는 무엇입니까? frist 클래스 중 일부는 LISP- CLOS 에서 나왔습니다 . clojure 네임 스페이스유형 또는 모듈haskell을 살펴보십시오 .

수업이없는 기능적 언어를 언급했습니다. DO
Electric Coffee

1
예를 들어, Caml의 자매 언어 인 OCaml은 객체를 추가하지만 Caml 자체에는 객체가 없습니다.
Electric Coffee

12
"순전히 기능적"이라는 용어는 참조 투명성을 유지하고 언어에 객체 지향 기능이 있는지 여부와 관련이없는 기능적 언어를 의미합니다.
sepp2k 2016 년

2
케이크는 거짓말입니다 .OO의 코드 재사용은 FP보다 훨씬 어렵습니다. OO가 수년에 걸쳐 코드 재사용을 주장한 모든 것에 대해, 나는 그것이 최소한의 시간을 따르는 것을 보았습니다. (오직 내가 잘못하고 있다고 말할 수 있습니다. 수년간 OO 시스템을 설계하고 유지 관리 해야하는 OO 코드 작성 방법에 익숙합니다. 내 결과의 품질을 알고 있습니다)
Jimmy Hoffa

답변:


19

많은 기능 언어에는 모듈 시스템이 있습니다. (많은 객체 지향 언어도 마찬가지입니다.) 그러나 언어가없는 경우에도 함수를 모듈로 사용할 수 있습니다.

JavaScript가 좋은 예입니다. JavaScript에서 함수는 모듈과 객체 지향 캡슐화를 구현하는 데 사용됩니다. JavaScript의 주요 영감이었던 Scheme에는 기능 있습니다. 함수는 객체, 모듈 ( 라켓 단위 라고 함 ), 데이터 구조 등 거의 모든 것을 구현하는 데 사용됩니다 .

OTOH, Haskell 및 ML 제품군에는 명시 적 모듈 시스템이 있습니다.

객체 지향은 데이터 추상화에 관한 것입니다. 그게 다야. 모듈성, 상속, 다형성, 심지어 변경 가능한 상태는 직교 관심사입니다.


8
oop와 관련하여 이러한 것들이 어떻게 작동하는지 설명 할 수 있습니까? 단순히 개념이 존재한다고 말하는 것이 아니라 ...
Electric Coffee

주석-모듈과 단위는 라켓에서 서로 다른 두 가지 구성입니다. 모듈은 네임 스페이스와 비슷하며, 네임 스페이스와 OO 인터페이스 사이의 중간 정도입니다. 워드 프로세서는 차이에 더 많은 세부 사항으로 이동

@ 잭 : 라켓에는이라는 개념이 있다는 것을 몰랐습니다 module. 라켓에는 module모듈이 아니라는 개념과 모듈이지만 개념은 아닌 개념이 있다는 것은 불행한 일입니다 module. 어쨌든, "유닛은 네임 스페이스와 OO 인터페이스 사이의 중간 정도입니다"라고 썼습니다. 글쎄, 모듈이 무엇인지에 대한 그런 종류의 정의가 아닙니까?
Jörg W Mittag

모듈과 단위는 모두 값에 바인딩 된 이름 그룹입니다. 모듈은 다른 특정 바인딩 세트에 종속 될 수있는 반면 , 유닛은 유닛을 사용하는 다른 코드가 제공 해야하는 일반적인 바인딩 세트에 종속 될 수 있습니다 . 단위는 바인딩을 통해 매개 변수화 되고 모듈 은 매개 변수화 되지 않습니다. 바인딩에 의존하는 모듈 map과 바인딩에 의존하는 유닛 map은 모듈 map 와 같은 특정 바인딩을 참조 해야 한다는 점에서 racket/base다릅니다. 반면에 유닛의 다른 사용자는 유닛에 대해 다른 정의를 줄 수 있습니다 map.
Jack

4

"기능적 언어로 모듈성을 어떻게 달성 할 수 있습니까?"라는 두 가지 질문을하는 것 같습니다. 다른 답변과 "기능적 언어로 추상화를 어떻게 만들 수 있습니까?" 대답하겠습니다.

OO 언어에서는 명사, "동물", "메일 서버", "그의 정원 포크"등에 집중하는 경향이 있습니다. 기능적 언어는 동사를 강조합니다. "걷다", "메일 가져 오기" , "prod"등

그러므로 기능적 언어의 추상화가 사물보다는 동사 나 연산에 관한 경향이 있다는 것은 놀라운 일이 아닙니다. 이것을 설명하려고 할 때 항상 도달하는 한 가지 예는 파싱입니다. 기능적 언어에서 구문 분석기를 작성하는 좋은 방법은 문법을 지정한 다음 해석하는 것입니다. 인터프리터는 구문 분석 프로세스에 대한 추상화를 작성합니다.

이것의 또 다른 구체적인 예는 얼마 전에 내가 작업했던 프로젝트입니다. 하스켈에서 데이터베이스를 작성하고있었습니다. 가장 낮은 수준에서 작업을 지정하기위한 하나의 '내장 언어'가있었습니다. 예를 들어, 저장 매체에서 물건을 쓰고 읽을 수있었습니다. 최고 수준에서 작업을 지정하기위한 별도의 별도 '임베디드 언어'가있었습니다. 그런 다음 작업을 상위 수준에서 하위 수준으로 변환하기 위해 본질적으로 통역사가 있습니다.

이것은 상당히 일반적인 추상화 형태이지만 기능적 언어로 제공되는 유일한 것은 아닙니다.


4

"기능적 프로그래밍"은 모듈화 문제에 대한 시사점을 제공하지는 않지만 특정 언어는 다양한 방식으로 프로그래밍을 처리합니다. 코드 재사용과 추상화는 코드를 재사용하기가 더 어려워 질수록 상호 작용합니다. 추상화를 제외하고 두 가지 재사용 문제를 다룰 것입니다.

정적으로 유형이 지정된 OOP 언어는 전통적으로 공칭 서브 타이핑을 사용했습니다. 즉, 클래스 / 모듈 / 인터페이스 A 용으로 설계된 코드는 B가 A를 명시 적으로 언급 할 때만 클래스 / 모듈 / 인터페이스 B 만 처리 할 수 ​​있습니다. B가 A의 모든 메소드 및 / 또는 필드를 가질 때마다 A를 위해 설계된 코드는 B를 처리 할 수 ​​있습니다.보다 일반적인 클래스 / 인터페이스 A가 필요하기 전에 다른 팀이 B를 작성할 수있었습니다. 예를 들어 OCaml에서 구조적 서브 타이핑 모듈 시스템, OOP와 유사한 객체 시스템 및 매우 독특한 다형성 변형 유형에 적용됩니다.

OOP와 FP wrt의 가장 두드러진 차이점. 모듈화는 OOP 번들의 기본 "단위"가 동일한 값의 경우에 대한 다양한 조작을 오브젝트로 함께 묶는 반면, FP 번들의 기본 "단위"는 다양한 값의 경우에 대한 동일한 조작 인 함수로 함께 번들됩니다. FP에서는 여전히 모듈과 같이 작업을 함께 묶는 것이 매우 쉽습니다. (BTW, Haskell이나 F #은 본격적인 ML 제품군 모듈 시스템을 가지고 있지 않습니다.) 식 문제모든 값에 대해 작업하는 새 작업 (예 : 기존 객체에 새 메서드 연결)과 모든 작업에서 지원해야하는 새 값 사례 (예 : 동일한 인터페이스의 새 클래스 추가)를 점진적으로 추가하는 작업입니다. 아래의 첫 번째 Ralf Laemmel 강의 (C #에 광범위한 예제가 있음)에서 논의했듯이 OOP 언어에서는 새로운 작업을 추가하는 것이 문제가됩니다.

스칼라에서 OOP와 FP를 결합하면 가장 강력한 언어 중 하나가 될 수 있습니다. 모듈성. 그러나 OCaml은 여전히 ​​제가 가장 좋아하는 언어이며 개인적이고 주관적인 견해로는 스칼라에 미치지 않습니다. 아래의 두 Ralf Laemmel 강의는 Haskell의 표현 문제에 대한 해결책을 설명합니다. 이 솔루션은 완벽하게 작동하지만 결과 데이터를 파라 메트릭 다형성으로 사용하기가 어렵다고 생각합니다. 아래 링크 된 Jaques Garrigue 기사에서 설명한 OCaml의 다형성 변이체의 표현 문제를 해결하는 데는이 단점이 없습니다. 또한 OCaml에서 비 OOP 및 OOP 모듈화의 사용을 비교하는 교과서 장으로 연결됩니다.

다음은 Expression Problem 에서 확장 된 Haskell 및 OCaml 관련 링크입니다 .


2
이 자료들이 무엇을하는지 더 자세히 설명해 주시겠습니까? 그리고 질문에 대답 할 때 왜 그 자료들을 추천하십니까? "링크 전용 답변" 은 Stack Exchange에서 환영받지 못합니다
gnat

2
방금 링크 대신 링크로 실제 답변을 제공했습니다.
lukstafi 2016 년

0

실제로 OO 코드는 재사용이 훨씬 적으며 의도적으로 설계된 것입니다. OOP의 기본 개념은 특정 데이터 조각에 대한 작업을 클래스 또는 상속 계층의 적절한 위치에있는 특정 권한있는 코드로 제한하는 것입니다. 이것은 변경의 부작용을 제한합니다. 데이터 구조가 변경되면 코드에서 책임질 수있는 위치가 너무 많습니다.

불변성을 사용하면 데이터 사본을 변경할 수있는 사람이 없기 때문에 주어진 데이터 구조를 누가 조작 할 수 있는지는 신경 쓰지 않아도됩니다. 이를 통해 기존 데이터 구조에서보다 쉽게 ​​작업 할 수있는 새로운 기능을 만들 수 있습니다. 단지 기능을 만들어 도메인 관점에서 적절 해 보이는 모듈로 그룹화하면됩니다. 상속 계층 구조에 어디에 넣을 지 걱정할 필요가 없습니다.

다른 종류의 코드 재사용은 기존 함수에서 작동하는 새로운 데이터 구조를 만드는 것입니다. 이것은 제네릭 및 형식 클래스와 같은 기능을 사용하여 기능적 언어로 처리됩니다. 예를 들어 Haskell의 Ord 유형 클래스를 사용 sort하면 Ord인스턴스 가있는 모든 유형 에서 함수 를 사용할 수 있습니다 . 인스턴스가없는 경우 쉽게 만들 수 있습니다.

Animal예를 들어, 급지 기능 구현을 고려 하십시오 . 간단한 OOP 구현은 Animal개체 컬렉션을 유지 관리하고 각 개체 feed에 대해 메서드를 호출하여 모든 개체를 반복 합니다.

그러나 세부 사항에 도달하면 상황이 까다로워집니다. Animal객체는 자연스럽게 종류의 음식이 먹고 무엇을 알고, 얼마나 그것은 전체 느낌을 위해 필요합니다. 그것은 않습니다 하지 음식이 유지되는 경우 자연적으로 알고 있고 그래서 얼마나 볼 수 있습니다 FoodStore개체가 단지마다의 종속성이되었다 Animal중 하나의 필드로, Animal객체, 또는의 매개 변수로 전달 feed하는 방법. 또는 Animal클래스를보다 응집력 있게 유지 feed(animal)하기 위해 FoodStore객체 로 이동 하거나 클래스 AnimalFeeder또는 이와 유사한 클래스의 가증을 만들 수 있습니다 .

FP에서는 Animal항상 함께 그룹화되어 있는 필드에 대한 성향이 없으므로 재사용 가능성에 흥미로운 영향을 미칩니다. 당신의 목록이 말 Animal필드이 좋아 함께, 기록 name, species, location, food type, food amount, 등 또한 목록이 FoodStore같은 필드 레코드를 location, food type하고 food amount.

먹이의 첫 단계 (food amount, food type)는 동물의 양에 대해 음수 로 해당 레코드 목록을 쌍 목록에 매핑하는 것입니다 . 그런 다음 각 유형의 음식의 양을 합하는 것과 같이 이러한 쌍으로 모든 종류의 작업을 수행하는 함수를 만들 수 있습니다. 이 함수들은 하나 Animal또는 FoodStore모듈 에 완벽하게 속하지는 않지만 두 가지 모두에 의해 재사용 성이 높습니다.

[(Num A, Eq B)]재사용 가능하고 모듈화 된 유용한 기능을 수행하는 많은 함수 가 생길 수 있지만 어디에 넣을 것인지 또는 그룹으로 무엇을 부를 것인지 파악하는 데 어려움이 있습니다. 그 결과 FP 모듈은 분류하기가 더 어렵지만 분류는 훨씬 덜 중요합니다.


-1

널리 사용되는 솔루션 중 하나는 코드를 모듈로 나누는 것입니다. 다음은 JavaScript에서 수행되는 방법입니다.

    media.podcast = (function(name) {
    var fileExtension = 'mp3';        

     function determineFileExtension() {
         console.log('File extension is of type ' + fileExtension);
     }

     return {
         download: function(episode) {
            console.log('Downloading ' + episode + ' of ' + name);
            determineFileExtension();
        }
    }    
}('Astronomy podcast'));

자바 스크립트에서이 패턴을 설명하는 전체 기사는 , 그 외에도 같은 모듈을 정의하는 다른 방법의 숫자가 RequireJS , CommonJS , Google Closure 입니다. 또 다른 예로 Erlang은 API와 패턴을 적용하는 모듈동작 이 모두 있으며 OOP의 인터페이스와 유사한 역할을합니다.

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