기능적 프로그래밍 가독성


13

나는 기능적인 언어를 배우기 전에 기억하기 때문에 이것에 대해 궁금합니다. 모두 끔찍하고 끔찍하게 읽을 수 없다고 생각했습니다. 이제 Haskell과 f #을 알고 있기 때문에 적은 코드를 읽는 데 시간이 조금 더 걸리지 만 작은 코드는 명령형 언어에서 동등한 양보다 훨씬 많은 양을 얻으므로 순이익처럼 느껴지고 극도로 나쁘지 않습니다. 기능적으로 연습했습니다.

내 질문은, 나는 OOP 사람들로부터 기능적 스타일을 읽을 수 없다는 말을 끊임없이 듣는다. 이것이 사실인지 궁금하고 자신을 혐오하거나 그들이 기능적 언어를 배우는 데 시간이 걸린다면 전체 스타일을 더 이상 OOP보다 읽을 수 없을 것입니까?

누구든지 증거를 보았거나 그들이 말할 수있는 빈도로 이런 일이 일어났다는 일화를 보았습니까? 기능적으로 작성하는 것이 실제로 가독성이 떨어지는 경우 계속 사용하고 싶지는 않지만 그 경우에 해당되는지 여부는 알 수 없습니다.


1
나는 "슈퍼 Nario 형제"에 대한 코드보고 기억 svn.coderepos.org/share/lang/haskell/nario 나는 거의 와우의 사고를 기억 함수형 프로그래밍에 대해 아무것도 알고 때. 이것은 정말 읽기 쉬운 것 같습니다
WuHoUnited



3
@BlackICE linq와 람다는 "기능적 프로그래밍"을 정의 하는 것과는 거리가 멀다. 함수형 프로그래밍은 함수를 객체 / 클래스 / 레코드가 아닌 유형으로 인식하기 시작할 때 완전히 새로운 능력과 기술을 많이 사용하기 때문에 유형 시스템이 아닌 경우가 많습니다. LINQ 및 Lambda 식 (또는 목록 모나드 및 고차 함수)은 두 가지 구체적인 결과 기법 일 뿐이며 그 중 더 많은 기법이 있습니다.
Jimmy Hoffa

답변:


15

코드 가독성은 매우 주관적 입니다. 이 때문에 다른 사람들은 동일한 코드를 읽을 수 있거나 읽을 수없는 것으로 간주합니다.

과제 x = x + 1는 수학자에게 이상하게 들립니다. 과제는 비교와 오해의 소지가 있기 때문입니다.

간단한 OOP 디자인 패턴은 이러한 패턴에 익숙하지 않은 사람에게는 완전히 불분명합니다. singleton을 고려하십시오 . 누군가가 물어 보곤 "나는 개인 생성자가 필요합니까 왜 신비 방법은 무엇? getInstance() 우리는 전역 변수를하지 않는 이유는 무엇입니까?와 객체가를 할당?"

FP 코드에도 동일하게 적용됩니다. 배후 의 논리적 패턴 을 알지 못하면 함수를 다른 함수의 인수로 전달하는 방법과 같이 매우 기본적인 것을 이해하는 것조차 매우 어렵습니다.

이것을 말하면 FP는 은총이 아니라는 것을 이해해야합니다. FP를 적용하기 어려운 많은 응용 프로그램이 있으므로 읽기 어려운 코드로 이어질 수 있습니다 .


사람들은 자신과 비슷한 것을 창조해야합니다 (인류). 예를 들어 컴퓨터 비전에서도 신경망이 생겼습니다. 인간의 몸은 대상, 속성, 방법으로 구성되며 대상, 속성, 방법을 사용하여 다른 것을 설명합니다. 따라서 함수형 프로그래밍은 의미가 없습니다
user25

12

짧은 답변:

사람들이 기능적 프로그래밍 코드를 읽기 어렵다고 말하는 요소 중 하나는 더 간단한 구문을 선호한다는 것입니다.

긴 대답 :

함수형 프로그래밍 자체는 코드 작성 스타일이 아니라 패러다임이므로 읽을 수 없거나 읽을 수 없습니다. 예를 들어 C #에서 함수형 프로그래밍은 다음과 같습니다.

return this.Data.Products
    .Where(c => c.IsEnabled)
    .GroupBy(c => c.Category)
    .Select(c => new PricesPerCategory(category: c.Key, minimum: c.Min(d => d.Price), maximum: c.Max(d => d.Price)));

Java, C # 또는 유사한 언어에 대한 충분한 경험이있는 사람이라면 누구나 읽을 수있는 것으로 간주됩니다.

반면에 언어 구문은 널리 사용되는 OOP 언어에 비해 많은 기능적 언어 (하스켈 및 F # 포함)에 비해 더 간결하여 일반 영어 단어보다는 기호를 우선적으로 사용합니다.

이것은 FP 이외의 언어에도 적용됩니다. 인기있는 OOP 언어를 영어 단어를 더 많이 사용하는 덜 인기있는 언어와 비교하면 프로그래밍 경험이없는 사람들이 마지막 언어를 이해하기가 더 쉬울 것입니다.

비교:

public void IsWithinRanges<T>(T number, param Range<T>[] ranges) where T : INumeric
{
    foreach (var range in ranges)
    {
        if (number >= range.Left && number <= range.Right)
        {
            return true;
        }
    }

    return false;
}

에:

public function void IsWithinRanges
    with parameters T number, param array of (Range of T) ranges
    using generic type T
    given that T implements INumeric
{
    for each (var range in ranges)
    {
        if (number is from range.Left to range.Right)
        {
            return true;
        }
    }

    return false;
}

같은 방법으로:

var a = ((b - c) in 1..n) ? d : 0;

다음과 같이 가상의 언어로 표현 될 수 있습니다.

define variable a being equal to d if (b minus c) is between 1 and n or 0 otherwise;

짧은 구문이 더 좋을 때?

초보자에게는 더 자세한 구문을 이해하기 쉽지만 숙련 된 개발자에게는 더 간단한 구문이 더 쉽습니다. 코드가 짧을수록 입력 할 문자 수가 적어 생산성이 향상됩니다.

특히 구문에서 추론 할 수있는 것을 나타 내기 위해 키워드를 입력하도록 강요하는 것은 실제로 의미가 없습니다.

예 :

  • PHP에서는 function특별한 이유없이 모든 함수 나 메소드 앞에 입력 해야합니다.

  • Ada는 항상 자동 완성 기능이있는 올바른 IDE가 없기 때문에 개발자가 많은 영어 단어를 입력하도록 강요했기 때문에 항상 나를 놀라게했습니다. 나는 최근에 Ada를 사용하지 않았고 공식 튜토리얼이 다운되어 예제를 제공 할 수 없습니다. 누구든지 모범이 있다면 내 대답을 자유롭게 수정하십시오.

  • 구문 1..n많은 FP (Matlab과)에 사용은,에 의해 대체 될 수있다 between 1, n거나 between 1 and n또는 between (1, n). 이 between키워드를 사용하면 언어 구문에 익숙하지 않은 사람들이 이해하기가 훨씬 쉬워 지지만 두 개의 점은 입력하기가 훨씬 빠릅니다.


8
나는 정서에 동의하지만 다른 이유가 있습니다. 코드는 일반적으로 코드보다 훨씬 자주 읽으므로 전문가가 코드를 쉽게 작성할 수있는 방법 이 아닙니다 . 짧은 표시기 (예를 들어, 세미콜론 대신 개행 문자, 두 가지 일치 항목)에서 이미 눈에 띄게 표시되는 경우 코드가 짧을수록 귀중한 시간, 화면 공간 및 정신 용량을 낭비하지 않으면 서 가독성 높일 수 있습니다 . 너무 암호 가되면 아플 수도 있습니다 (예 : 루프 변수와 컨테이너를 구별하는 데 도움이되기 때문에 over 선호합니다 ). for x in xsfor x xs

내가 찾은 많은 사람들이 FP에 대해 불만을 표시 한 것은 귀하가 말한대로 나열된 C # 스 니펫에 대해서도 불만을 표시하며 FP의 예이기도합니다. 아마도 대부분의 OOP 사람들이 스 니펫을 읽을 수 있다고 생각한다면 대부분의 OOP 사람들이 내 경험에서 할 것이라고 확신하지는 않지만 이것은 가독성보다 동료들에게 더 큰 문제 일 것입니다.
지미 호파

@ Jimmy Hoffa : C # 스 니펫과 초보자 프로그래머가 어떻게 인식하는지에 대해 논의하는 programmers.stackexchange.com/a/158721/6605를 참조하십시오 .
Arseni Mourzenko

1
@Sergiy : Java 또는 C #에서 메소드 서명에는 method키워드 가 없습니다 . 예 : public int ComputePrice(Product product). PHP가했던 것처럼 그러한 키워드를 추가하면 더 쉽게 읽을 수있게하는 대신 혼란을 더할 수 있습니다. 프로그래머가 함수가 서명의 함수라는 것을 이해할 수 없다면,이 프로그래머는 경험이 전혀 없거나, 코드는 내가 본 것 중 최악의 코드보다 훨씬 더 읽을 수 없습니다.
Arseni Mourzenko

1
@ Sergiy : 자세한 정보가 도움이 될 수있는 경우가 있지만 (그렇지 않으면 언어와 같은 코드를 볼 수 있습니다 p i ComputePrice(product): _.unitPrice * ~.cart[_]) 일부 언어는 너무 멀리 밀어냅니다. functionPHP 에서 중복 키워드 의 예가 좋은 예입니다.
Arseni Mourzenko

6

그 이유 중 하나는 함수형 프로그래밍이 훨씬 더 추상적 인 개념으로 작동하는 경향이 있다고 생각합니다. 이것은 개념을 이해하고 이해하는 사람들에게는 문제의 본질을 적절하게 표현하기 때문에 코드를 더 짧고 읽기 쉽게 만들지 만, 익숙하지 않은 사람들에게는 읽을 수 없습니다.

예를 들어, 기능 프로그래머의 경우 Maybe모나드 또는 Either모나드 내의 다른 지점에서 실패 할 수있는 코드를 작성하는 것이 당연합니다 . 또는 State모나드 의 도움으로 상태 저장 계산을 작성합니다 . 그러나 모나드의 개념을 이해하지 못하는 사람에게는이 모든 것이 일종의 검은 마법처럼 보입니다.

따라서 함수 또는 클로저 를 사용하여 컬렉션에 매핑하는 것과 같이 이해하거나 배우기 쉬운 한 가지 개념을 사용하는 한 OOP 팀에서도 기능적인 프로그래밍 비트를 사용하는 것이 합리적이라고 생각합니다 .

(물론 일부 코드를 작성한 프로그래머에 따라 다릅니다. 어떤 언어로도 읽을 수없는 코드를 쓸 수있을뿐만 아니라 멋지고 깔끔한 스타일로 쓸 수도 있습니다.)


2

가독성은 패러다임, 모델 등과 관련이 없습니다. 더 많은 코드가 문제 도메인의 의미를 반영할수록 그러한 문제 도메인의 용어와 관용구를 더 많이 운영할수록 더 읽기 쉽습니다.

이것이 OOP 코드가 전혀 읽을 수없는 이유입니다. 많은 실제 문제가 자연스럽게 계층 적 분류법으로 표현되는 것은 아닙니다. 서로에게 메시지를 전달하는 객체는 이상한 개념이며 "실제"와는 거리가 멀다. 놀랍게도 기능 관용구에 자연스럽게 매핑 될 수있는 훨씬 더 많은 실제 개념이 있습니다. 문제는 선언적으로 정의되는 경향이 있으므로 선언적 솔루션이 더 자연 스럽습니다.

그러나 순수한 기능, 순수한 OOP, 순수한 데이터 흐름 또는 순수한 것보다 현실에 더 가까운 다른 의미가 많이 있습니다. 그리고이 사실로 인해 문제 해결에 대한 언어 중심의 접근 방식은 기존의 모든 "순수한"패러다임을 꺾고 가장 읽기 쉬운 코드를 생성합니다. 도메인 별 언어를 사용하면 모든 문제가 고유 한 용어로 표현됩니다. 그리고 기능적 언어는 DSL 구현을 촉진하는 데있어 OOP 주류보다 약간 우수합니다 (물론 더 나은 접근 방식이 가능합니다).


1

코드 가독성은 주관적입니다. 나는 어떤 사람들은 이해의 부족으로 그것을 비판 할 것이라고 확신합니다. 공통 패턴이 구현되는 방식에는 자연스럽게 다른 관용구가 있습니다. 예를 들어, 방문자 패턴은 패턴이 일치하는 언어에서는 실제로 의미가 없습니다 .

타입 추론은 까다로운 기능이 될 수 있습니다. 일반적으로 개발 속도가 빠르지 만 상황에 따라 혼동되는 오류로 인해 어떤 유형이 포함되는지 파악하기 어려울 수 있습니다. 이것은 함수형 프로그래밍 언어에 국한되지 않습니다. C ++ 템플릿에서도 보았습니다!

현대 언어는 다중 패러다임 인 경향이 있습니다 . 여기에는 C #과 F #이 모두 포함됩니다. C #에서는 기능적 스타일을, F #에서는 명령형 스타일을 작성할 수 있습니다. 기능 언어를 비판하는 사람들은 아마도 객체 지향 언어로 기능 코드를 작성할 것입니다.

기능적 언어의 상업적 개발은 여전히 ​​비교적 미숙합니다. 모든 언어에서 잘못된 형식으로 간주 될 수있는 많은 실수를 보았습니다. 같은 :

  1. 불일치를 일으키는 언어를 배우면서 리팩토링이 아닌 스타일 변경.
  2. 한 파일에 너무 많습니다.
  3. 한 줄에 문장이 너무 많습니다.

실수와 관련하여 다음과 같이 추가 할 수도 있습니다. 4. 기호 남용, 예 : ~ @ # $ % ^ & * () -_ + = \ | /.,; 5. 암시 적 기능 : 선택적 선언 / 키워드 / 문, 암시 적 변환 등
Sergiy Sokolenko
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.