Java에서 기능 프로그래밍이 가능합니까? [닫은]


42

나는 Amazon.com 서점을 탐색하고 있었고, 난 책을 우연히 만났다 "자바 개발자를위한 기능 프로그래밍" .

나는 매우 기본적인 기능 프로그래밍을 알고 있으며 3 년 동안 Java로 프로그래밍 해 왔습니다.

Java에서도 Functional Programming이 가능하다는 것을 알고 싶습니다.


2
스타일은 가능하지만 그 상세는 너무 많은 자바의 문법 주어진 견딜 수 : functionaljava.org
YURIY Zubarev

7
@nCdy JRuby를 확인해야하는 이유? 자세한 설명을 제공해주세요.
Chiron

1
groovy 확인 :-)
Ant 's

6
나는 이것이 Java 언어와 Java 플랫폼 사이의 구별을 제기하는 일종의 질문이라고 생각합니다.
Thomas Owens

2
@ ThorbjørnRavnAndersen : "기능적 프로그래밍"이 "게으른 평가"에 의해 정의되었다고 생각하는 것은 무엇입니까? 그것을 선택하는 것은 이상한 예처럼 보인다.
John Bartholomew

답변:


70

"기능적 프로그래밍"과 "가능한"의 의미에 따라 다릅니다.

기능적 패러다임에 따라 분명히 구현할 수 있습니다. 그러나 Java 언어는 구문 설탕을 제공하지 않으므로 일부는 지루할 것이고 일부는 매우 신비합니다.

마찬가지로 C와 같이 비 OO로 인식되는 언어로 객체 지향 코드를 작성할 수 있습니다.

자바 라이브러리

이미 당신을 위해 합법적 인 일을하고 신비한 것을 숨겨줌으로써 당신을 도울 수있는 라이브러리가 있습니다 :

이것들은 FP 유능한 언어에서 기대할 수 있듯이보다 기능적인 접근 방식과보다 친숙한 구문 및 의미론으로 Java 코드를 작성할 수 있습니다. 이유가 바로 그것입니다.

JVM 언어

그리고 분명히 Java 위에 기능적 언어를 구현할 수 있습니다 . 그런 다음 해당 언어를 FP 언어로 사용할 수 있습니다. 어느 것이 당신이 요청한 것보다 약간 높은 추상화 수준이지만 상대적으로 맥락 내입니다 (여기서 바람을 피우고 있습니다).

예를 들어 다음을 확인하십시오.

다소 기능적인 JVM 언어

그것들이 정확히 원하는 것은 아니지만 Java 플랫폼으로 포팅되었으며 Java의 상대적으로 재미 있지 않은 (예, 말장난) 성격에서 벗어나 더 많은 것을 줄 수있는 다른 언어가 많이 있습니다. 적응성. JRuby , JythonRhino 와 같은 주목할만한 경쟁자 ( Ruby , PythonJavaScript / ECMAScript 각각에 해당 )도 기능 프로그래밍에 흥미로운 잠재력을 제공하지만 실제로는 실제로 기능 프로그래밍 언어는 아닙니다. 제트 브레인 즈 코 틀린기능 언어가 아니라는 점을 분명히 인정하면서 일부 기능적 구성을 지원하며 살펴볼 가치가 있습니다.

추가 자료

다음 기사 나 비디오를 읽거나 볼 수도 있습니다.


2
Clojure 소스 코드는 이제 Github github.com/clojure/clojure에서
Chiron

1982 년의 @The Legend : 나는 당신의 의견보다 빠르다. 나는 이미 공식 clojure.org 사이트로의 링크를 변경했다. 사람들이 빨리 반응하는 것을 보는 것이 좋습니다.
haylem

ABCL ( common-lisp.net/project/armedbear )도 있지만 성숙 / 성숙하지 않은 규모와 Common Lisp 구현인지는 알 수 없습니다.
Vatine

@Vatine : 흥미롭고 절대 들어 보지 못했습니다 . 훑어보고 추가하십시오.
haylem

1
나는 Alan Perlis의 용어 "Turing Tarpit"이 랑 주인이 할 수 있는 일을하려고 노력 했지만 (튜링이 완료 되었기 때문에) 시도해서는 안되는 고통과 복잡성에 대해서만 사랑한다 .
itsbruce

11

당신이 언급 한 책을 읽고 있습니다. 정말 좋은 BTW입니다.

예, Java에서 작동하는 것이 가능합니다. 어느 정도까지 달성 할 수 있는지 모르겠지만 많은 기능적 프로그래밍 관용구를 구현할 수 있습니다.

가장 중요한 것 중 하나는 "상태를 변경하지 마십시오"라는 마음으로 코딩하는 것입니다.

예를 들어, 불완전 성을 달성하기 위해 final 키워드를 사용합니다. 데이터 구조를 사용하려는 경우 변경 불가능한 데이터 구조로 코딩해야합니다. Google Guava 라이브러리는 이미이 작업을 수행하고 있습니다.

또한 동시 프로그래밍의 경우 Akka 프레임 워크 (액터 모델)를 사용할 수 있습니다.

JVM 바이트 코드는 함수형 프로그래밍 언어에 매우 중요한 기능인 테일 콜 최적화를 지원하지 않습니다 (적어도 아직).


"JVM 바이트 코드는 기능적 프로그래밍 언어에 매우 중요한 기능인 테일 콜 최적화를 지원하지 않는다는 점을 언급 할 가치가 있습니다.": 무슨 의미입니까? 스칼라는 TCO를 가지고 있습니다.
Giorgio

@Giorgio : 스칼라는 컴파일 타임에 TCO를 수행합니다.
scrwtp

@scrwtp : 그로 인해 성능 저하가 있습니까? 또는 컴파일 타임 TCO의 단점은 무엇입니까?
Giorgio

@ Giorgio : Chiron이 원래 언급했듯이 Java 바이트 코드는 기본적으로 지원하지 않습니다. 함수형 언어는이 문제를 해결하여 꼬리 재귀 호출을 루프로 컴파일하지만 JVM이 아닌 언어-> 바이트 코드 컴파일러의 기능입니다.
scrwtp

@scrwtp : Chiron의 답변에 따르면 "JVM 바이트 코드는 기능 프로그래밍 언어에 매우 중요한 기능인 테일 콜 최적화를 지원하지 않습니다." JVM에서 기능적 언어의 구현이 불이익을받는 것처럼 들리지만 테일 콜 최적화가 컴파일 된 코드에서 시뮬레이션 될 수 있기 때문에 이것은 사실이 아닙니다. 그래서 Chiron의 진술에 동의하지만 약간 오해의 소지가 있습니다.
Giorgio

6

네, 확실히 가능한 그 어떤 튜링 완전한 언어 / 실행 환경 조합에서 가능한 것과 같은 방식으로. 당신이하고있는 일을 안다면 아주 잘 수행 할 수 있습니다.

그것이 얼마나 현명한 지 잘 모르겠습니다. 특히, 그것은 관용적이지 않다는 점을 명심하십시오 (즉, 매우 이상하게 보일 것입니다. 비 전통적인 일을하고 일반 Java에 익숙한 사람들을 혼동해야합니다)

예를 들어 새로운 기능을 정의하는 이상한 코드가 생길 것입니다.

Function twoStrings=new Function() {
  public Object apply(Object param1) {
    // do something to param1 and return a result
  }
}

기능적 프로그래밍을 수행하려면 일반적으로 다음이 필요합니다.

  • 퍼스트 클래스 함수 - "함수"를 나타내며 하나 이상의 매개 변수에 함수를 적용하는 "적용"메소드가있는 추상 클래스 또는 인터페이스를 정의하여 Java로 쉽게 작성할 수 있습니다.
  • 마감 -최종 필드에 저장된 마감 값으로 함수 객체의 인스턴스를 만듭니다. 이를 위해 익명의 내부 클래스를 사용할 수 있습니다.
  • 표준 고차 함수 라이브러리 -까다 롭지 만 몇 시간 안에 간단한 기능 언어를 부트 스트랩하기 위해 직접 작성할 수 있습니다. 더 멋진 것을 원한다면 사람들이 Java로 작성한 다른 기능 라이브러리를 확인할 수 있습니다.

운동이나 재미있는 취미 프로젝트로도 가능합니다. 그러나 JVM의 장점을 유지하면서 Java 라이브러리에 액세스하는 동안 진지한 기능적 프로그래밍을하고 싶을 때 Clojure 는 내 생각에 가장 좋은 옵션입니다.

ps Clojure의 핵심은 실제로 Java로 작성되었으므로 실제로는 새로운 현대 언어 구문 뒤에 지저분한 세부 사항을 숨기면서 Java에서 기능 프로그래밍을 수행하는 방법에 대한 매우 흥미로운 사례입니다. Clojure 소스 코드는 관심있는 사람들을 위해 GitHub에 있습니다 .


흥미롭게도, 최신 버전의 IntelliJ IDEA가 이러한 익명의 것들을 편집기에 표시하기 위해 더 간단한 형태로 접을 것임을 알았습니다. 중복 크래프트를 숨기는 pretyt 알맞은 작업을 수행합니다. 물론이 모든 것은 Java 8과 관련이 없습니다.
Ben Hardy

4

Java에서는 다소 기능적 일 수 있습니다. 그렇게하는 것은 심각하게 고통 스럽다 . 대신에

myList.each { doSomething(it); }

당신은 다음과 같은 것을 가지고 있습니다 :

myList.each(new Function() { public void do(Object arg) { something(); }})

클로저와 함수를 일등 객체로 사용하여 진정한 기능 프로그래밍을 원한다면 다른 언어를 선택하십시오. Scala, Clojure, Groovy는 모두 JVM에서 실행되며 레거시 Java 클래스와 상호 작용할 수 있습니다. .


함수형 프로그래밍은 익명 클래스 대신 블록을 사용하는 것이 아닙니다. Java 8에는 블록이 있으므로 게시 된 코드가 더 우아해 보이지만 기능적 프로그래밍은 아닙니다.
Chiron

@ Legend : 이해하지만 잘 설명하지 못했습니다.
케빈 클라인

이것은 감독 / 관찰입니다. 어떤 언어를 사용하더라도 실제로 함수를 정의해야하며 그 부분을 건너 뛸 수 없습니다. 따라서 Java는 거의 간결합니다. Function 객체를 익명으로 만들면됩니다. 이를 수행 할 수 있습니다. 기능 f = new Function () {public void do () {}}; .... 그런 다음에 그 함수를 호출하십시오 .... myMethodToCallAFunction (Function f) {f.do ()} ... 브로스와 브로 니 니스입니다. 받아 들여.
Alexander Mills

3

대답은 "그렇습니다."라고 말할 수 있지만, 많은 기능 언어에서 가장 중요한 기능 중 하나는 우수한 유형 시스템입니다. Java로 직접 관리 할 수는 없습니다.

기능적 프로그램을 작성하고 JVM을 유지하려는 경우 일반적인 용의자 인 Scala와 Clojure 중 Frege 를 볼 것을 권장 할 수 있습니다 . Frege는 Haskell과 매우 유사한 구문 및 유형 시스템을 가지고 있지만 프로그램은 Java 코드로 직접 변환되며 다른 Java 코드와 상호 작용할 수 있습니다.


2

글쎄, 모든 종류의 것들이 가능합니다. C에서 객체 지향 프로그래밍을 수행 할 수 있습니다. 좋은 생각이 아닙니다.

Java는 FP 용으로 설계되지 않았으므로 순수한 FP 스타일로 모든 작업을 수행하려고하면 문제가 발생합니다. 언어를 다루는 대신 언어와 싸우는 것입니다. 언어뿐만 아니라 멋진 무료 Java 라이브러리도 있습니다. 따라서 순수한 FP로 가지 마십시오. FP의 아이디어 중 일부를 가져 와서 Java 코드에 통합하지만 모든 아이디어에 이를 수행 할 수는 없다는 점을 이해 하십시오.


0

OpenJDK 팀은 최신 OpenJDK 8 바이너리를 다운로드하고 Collections API에 도입 된 새로운 람다 식과 새로운 기능 관용구 (다른 것들 중에서도)를 사용하도록 권장합니다. 명확한 기능적 스타일로 프로그래밍 할 수 있습니다. "Java에서 기능 프로그래밍?"을 참조하십시오. 구아바, FunctionalJava 및 LambdaJ와 같은 사전 Java8 라이브러리와의 JDK8 콜렉션 비교


-3

가능해 보이지만 순수한 기능적 프로그래밍은 아닙니다. 명령형 프로그래밍이 발생할 수 있습니다.

haylem이 언급 한대로 가능한 함수형 프로그래밍의 의미를 묻는 이유는 없습니다 . 여기있어:

"기능적 프로그래밍"과 "가능한"의 의미에 따라 다릅니다.

함수형 프로그래밍은 설명이 많을지라도 다른 정의 나 의미를 가질 수 없습니다.
OOP와 마찬가지로 "OOP의 의미는 무엇입니까?"
분명히 많은 설명이있을 것이지만, OOP의 목표 인 하나의 목표와 관련이있을 것입니다. 함수형 프로그래밍
에도 동일하게 적용됩니다 .

기능적 의미를 말할 때 프로그램은 기능으로 구성됩니다.
함수의 역할은 평가 된 인수 / 매개 변수를 반환하는 것입니다 (인수는 변수는 함수 선언의 일부인 변수 인 동안 함수를 호출 할 때 나온 표현식입니다).

또한 함수는 동일한 인수가 전달 될 때 항상 동일한 결과를 반환합니다. 이렇게하면 버그를 피하거나 향후 버그를 디버그하는 것이 더 쉽습니다. 함수형 프로그래밍을 통해 전역 변수 수정과 같은 부작용을 피할 수 있습니다.

JavaScript의 예 :

function increment(lis){
    return lis.map(
        function (x){
            return x+2;
        }
    );
}

var myList = [4, 7, 2, 3];
console.log(increment(myList));
console.log(myList);

함수 증가는 객체 내부의 각 요소에 1 개의 값을 더하고 결과를 반환합니다. myList의 값은 변하지 않았지만 함수를 호출 할 때 해당 객체의 요소에 추가 된 값을 보았습니다.

내 응답으로 자바에서 가능한 기능 프로그래밍? , 나는 자바에서 진정한 함수형 프로그래밍을 할 수 없다고 생각합니다. Java는 실제로 OOP로 설계되었으므로 명령형 프로그래밍을 확장하고 유지 관리 성을 위해 개선했습니다. 객체, 변수 등의 상태가 변경되면 이미 명령형 프로그래밍입니다.

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