비 FP 사람들이 소량의 기능 프로그래밍을 이해할 수 있습니까? [닫은]


43

사례 : 회사에서 일하면서 많은 데이터를 배열로 처리하는 Python으로 응용 프로그램을 작성하고 있습니다. 나는 현재이 프로그램의 유일한 개발자이지만, 아마도이 시점에서 다른 프로그래머가 아마도 (1-3 년) 사용하거나 수정하거나 확장 할 것입니다. 아마도 도움을 받기 위해 직접 거기에 없을 수도 있지만 시간이 있으면 이메일을 통해 지원을 제공 할 수도 있습니다.

따라서 함수형 프로그래밍 (Haskell)을 배운 개발자로서 다음과 같은 필터링을 해결하는 경향이 있습니다.

filtered = filter(lambda item: included(item.time, dur), measures)

나머지 코드는 OO입니다. 나에게 따르면 훨씬 간단하고 아름답 기 때문에 이와 같이 해결하려는 작은 경우 일뿐입니다.

질문 : 오늘 이런 코드를 작성해도 괜찮습니까?

  • FP를 작성 / 학습하지 않은 개발자는 이와 같은 코드에 어떻게 반응합니까?
  • 읽을 수 있습니까?
  • 수정 가능?
  • 아이에게 줄이 무엇인지 설명하는 것과 같은 문서를 작성해야합니까?

     # Filter out the items from measures for which included(item.time, dur) != True

나는 상사에게 물었다. "FP는 마술이다. 그러나 그것이 효과적이고 가장 효율적인 해결책이라면 그것을 사용해도 좋다"고 말했다.

이것에 대한 당신의 의견은 무엇입니까? 비 FP 프로그래머로서 코드에 어떻게 반응합니까? 코드가 "구글 가능"하므로 코드의 기능을 이해할 수 있습니까? 이것에 대한 의견을 듣고 싶습니다.


14
제 생각에 많은 현대 언어는 어느 정도의 기능적 프로그래밍을 허용 하고 그것을 사용 하는 것이 점점 더 일반적이됩니다. 개인적으로 나는 적어도 상대적으로 간단한 필터링 / 매핑 작업을 위해 그것을 말하고 싶습니다.
Joachim Sauer

나는 FP를 좋아하기 때문에 아무런 영향을받지 않습니다. 간단하지 않은 경우 주석을 추가하는 것이 좋습니다.
Bruno Schäpper

3
귀하의 의견은 더 명확 할 수 있습니다. 필터에는 테스트가 참인 요소가 포함되므로 주석은 다음 # Select the item's from measures for which included(item.time, dur) == True과 같이 읽을 수 있습니다. , 이중 부정을 피하면 항상 이해력이 향상됩니다.
Martijn Pieters

6
대신 목록 이해를 고려해 보셨습니까? 그것들은 종종 맵 / 필터보다 "파이 토닉"으로 간주됩니다.
phant0m

2
@MatjazMuhic 글쎄, 그건 아름답다 ...;)
kd35a

답변:


50

읽을 수 있습니까?

나에게 : 예, 그러나 파이썬 커뮤니티는 종종 map()/를 사용하는 것보다 목록 이해를보다 깨끗한 솔루션으로 간주하는 것으로 이해합니다 filter().

실제로 GvR은 이러한 기능을 완전히 삭제하는 것도 고려 했습니다.

이걸 고려하세요:

filtered = [item for item in measures if included(item.time, dur)]

또한 이것은 목록 이해가 항상 목록을 반환한다는 이점이 있습니다. map()그리고 filter()다른 한편으로는 파이썬 3에서 반복자를 반환합니다.

참고 : 반복자를 대신 []사용하려면 ()다음 과 같이 간단하게 교체하십시오 .

filtered = (item for item in measures if included(item.time, dur))

솔직히 말해서, 파이썬 을 사용 map()하거나 filter()파이썬에서 사용할 이유가 거의 없습니다 .

수정 가능합니까?

그러나 확실히, 더 쉽게 만드는 한 가지가 있습니다. 람다가 아닌 함수로 만드십시오.

def is_included(item):
    return included(item.time, dur)
filtered = filter(is_included, measures)
filtered = [item for item in measures if is_included(item)]

상태가 더욱 복잡해지면 훨씬 쉽게 확장 할 수 있으며 수표를 재사용 할 수 있습니다. (다른 기능 내에서 기능을 만들 수 있으므로 사용하는 위치에 더 가깝게 유지할 수 있습니다.)

FP를 작성 / 학습하지 않은 개발자는 이와 같은 코드에 어떻게 반응합니까?

그는 파이썬 문서를 검색하고 5 분 후에 어떻게 작동하는지 알고 있습니다. 그렇지 않으면 그는 파이썬으로 프로그래밍해서는 안됩니다.

map()하고 filter()있습니다 매우 간단합니다. 모나드를 이해하도록 요구하는 것과는 다릅니다. 그렇기 때문에 그런 의견을 쓸 필요가 없다고 생각합니다. 좋은 변수와 함수 이름을 사용하면 코드는 거의 자명하다. 개발자가 모르는 언어 기능을 예상 할 수 없습니다. 아시다시피, 다음 개발자는 사전이 무엇인지 모를 수도 있습니다.

우리가 이해하지 못하는 것은 일반적으로 읽을 수 없습니다. 따라서 이전에 본 적이 없다면 목록 이해력보다 쉽게 ​​읽을 수 있다고 주장 할 수 있습니다. 그러나 Joshua가 그의 의견에서 언급했듯이, 적어도 다른 대안이 실질적인 이점을 제공하지 않는다면 다른 개발자가 사용하는 것과 일치하는 것이 중요하다고 생각합니다.


5
그것은 가치도 언급 할 수 있습니다 발전기 식 으로, 지능형리스트 대신 목록의 반환 발전기와 같은 작업, map그리고 filter파이썬 3에서 할
제임스

@ 제임스 : 좋은 생각, 나는 그들을 내 게시물에 추가했습니다. 감사!
phant0m

2
필자는 일반적으로 인라인 생성기 또는 목록 이해 로 대체하기가 어렵 기 때문에 항상 목록 이해 인수를 사용할 수reduce 있는 반례를 제시합니다 . reduce
kojiro

4
해당 언어의 선호되는 관용구에 주목하여 +1 IMHO 일관성은 엄청난 가치를 지니고 있으며 "스피커"의 상당 부분이 때때로 의견보다 더 많은 유지 관리 기능을 제공 할 수있는 방식으로 언어를 사용합니다.
Joshua Drake

4
"파이썬 문서를 구글로 검색하고 5 분 후에 어떻게 작동하는지 알고있다. 그렇지 않으면 파이썬으로 프로그래밍해서는 안된다."
Bjarke Freund-Hansen

25

개발자 커뮤니티가 함수형 프로그래밍에 대한 관심을 다시 얻고 있기 때문에 원래 완전히 객체 지향적 인 언어로 된 일부 함수형 프로그래밍을 보는 것은 드문 일이 아닙니다. C #이 좋은 예입니다. 여기서 익명 형식과 람다 식은 함수형 프로그래밍을 통해 훨씬 짧고 표현력이 좋습니다.

기능 프로그래밍은 초보자에게는 이상합니다. 예를 들어, 교육 과정에서 초보자에게 C #의 함수형 프로그래밍을 통해 코드를 향상시키는 방법을 설명했지만 일부는 확신하지 못했으며 일부는 원래 코드를 이해하기가 더 쉽다고 말했습니다. 내가 그들에게 준 예는 다음과 같습니다.

리팩토링 전 코드 :

var categorizedProducts = new Dictionary<string, List<Product>>();

// Get only enabled products, filtering the disabled ones, and group them by categories.
foreach (var product in this.Data.Products)
{
    if (product.IsEnabled)
    {
        if (!categorizedProducts.ContainsKey(product.Category))
        {
            // The category is missing. Create one.
            categorizedProducts.Add(product.Category, new List<Product>());
        }

        categorizedProducts[product.Category].Add(product);
    }
}

// Walk through the categories.
foreach (var productsInCategory in categorizedProducts)
{
    var minimumPrice = double.MaxValue;
    var maximumPrice = double.MinValue;

    // Walk through the products in a category to search for the maximum and minimum prices.
    foreach (var product in productsInCategory.Value)
    {
        if (product.Price < minimumPrice)
        {
            minimumPrice = product.Price;
        }

        if (product.Price > maximumPrice)
        {
            maximumPrice = product.Price;
        }
    }

    yield return new PricesPerCategory(category: productsInCategory.Key, minimum: minimumPrice, maximum: maximumPrice);
}

FP를 사용하여 리팩토링 한 후 동일한 코드 :

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

이것은 나를 생각하게합니다 :

  • 코드를 관리 할 다음 개발자가 전체적인 경험과 함수형 프로그래밍에 대한 지식을 충분히 보유하고 있다는 사실을 걱정하지 않아도됩니다.

  • 그렇지 않으면 함수형 프로그래밍을 피하거나 구문의 장점, 장점 및 가능한주의 사항과 비 기능적 프로그래밍 방식을 동시에 설명하는 자세한 설명을 넣으십시오.


8
FP가 코드를 다른 사람이 읽을 수있게 만들지 않으면 +1합니다 .
György Andrasek

7
FP를 전혀 보지 못한 사람이 어떻게 이전 코드를 더 잘 읽을 수 있는지 알 수 있습니다. 그러나 이것을 100으로 곱하면 어떻게 될까요? 거의 영어와 같은 문장 묘화 100 짧은 간결 읽고 무엇을 배관 수천 줄의 대 어떻게 코드를. 아무리 친숙하더라도 코드의 양이 너무 많아서 친숙 함이 더 이상 큰 승리가 아니어야합니다. 어떤 시점에서는 누구나 FP의 요소에 익숙해 져서 수천 줄의 친숙한 코드를 읽는 것보다 몇 줄을 읽는 것이 더 쉬워야합니다.
Esailija

7
가장 귀찮은 점은 개발자가 기능적 스타일을 배우지 않는 것이 허용된다고 믿는 것에 만족한다는 것입니다. 장점은 여러 번 입증되었으며 패러다임은 주류 언어로 지원됩니다. 사람들이 기능적 기술을 이해하는 능력이 부족한 경우, 사용을 의도하지 않더라도 자신을 가르쳐야합니다. 나는 열정적 인 열정으로 XSLT를 싫어하지만 그것이 전문가로서 그것을 배우는 것을 막지 못했습니다.
Sprague

2
@MainMa 요점은 완전히 유효합니다. 좀 더 구체적으로 말해야합니다. 의미하는 바는 특정 언어의 개발자가 해당 언어의 기능을 효과적으로 사용해야한다는 것입니다. 예를 들어 C #에서 '기능적 스타일'(필터 / 맵 / 감소 스타일 프로그래밍 또는 함수 전달 / 반환)을 사용하는 것은 새로운 것이 아니므로 그러한 명령문을 읽을 수없는 C # 개발자는 업데이트해야합니다. 기술 ... 아마 아주 빨리. 확실히 모든 개발자는 약간의 Haskell을 배워야한다고 생각하지만 학문적 이유로 만 사용해야합니다. 이것은 다른 것입니다.
Sprague

2
@Sprague : 나는 당신의 요점을 알고 그것에 동의합니다. 예를 들어 C # 프로그래머가 너무 많은 프로그래머가 제네릭을 사용하지 않을 때 FP의 패러다임을 사용하기 시작한다고는 거의 기대할 수 없습니다. 숙련되지 않은 프로그래머가 너무 많을 때까지, 우리의 직업에 대한 기준은 낮을 것입니다. 특히 기술적 배경이없는 대부분의 사람들은 개발에 관한 모든 것을 전혀 이해하지 못하기 때문입니다.
Arseni Mourzenko

20

저는 비 FP 프로그래머이며 최근 JavaScript로 동료의 코드를 수정했습니다. 콜백이 포함 된 Http 요청이 있었는데, 여기에는 포함 된 명령문과 매우 비슷합니다. 나는 그것을 모두 알아내는 데 약간의 시간 (30 분 정도)이 걸렸다 고 말해야한다 (모든 코드는별로 크지 않았다).

의견이 없었으며, 그럴 필요도 없다고 생각합니다. 동료에게 자신의 코드를 이해하도록 도와달라고 요청조차하지 않았습니다.

약 1.5 년 동안 일하고 있다는 점을 고려할 때, 대부분의 프로그래머가 그렇게 한 이후로 그러한 코드를 이해하고 수정할 수 있다고 생각합니다.

또한 Joachim Sauer가 자신의 의견에서 언급 한 것처럼 C # (예 : indexOf)과 같은 여러 언어로 된 FP 조각이 종종 있습니다. FP가 아닌 많은 프로그래머가이 문제를 자주 다루기 때문에 포함 된 코드 스 니펫은 끔찍하거나 이해하기 어려운 것이 아닙니다.


1
귀하의 의견에 감사드립니다! 다른 관점에서 더 많은 정보를 얻었습니다. 맹인이되기가 쉬우므로 FP를 몰랐을 때의 모습을 모르겠다. :)
kd35a

1
@ kd35a, 천만에요. 운 좋게도 여기서 객관적 일 수있다))
superM

1
많은 언어에 FP 요소가 포함되어 있음을 지적한 +1
Joshua Drake

LINQ는 C #에서 FP의 주요 예입니다.
Konrad Morawski

3

나는 확실히 그렇다고 말할 것입니다!

함수형 프로그래밍에는 여러 가지 측면이 있으며 예제와 같이 고차 함수를 사용하는 것은 그 중 하나 일뿐입니다.

예를 들어, 다음과 같은 이유로 순수한 기능 을 작성하는 것은 모든 언어로 작성된 소프트웨어 ( "순수"에 의해 부작용이 없음)에 매우 중요하다고 생각합니다.

  • 그들은 단위 테스트가 더 쉽다
  • 그들은 부작용 효과보다 훨씬 작곡이 가능합니다.
  • 그들은 디버그하기가 더 쉽다

또한 종종 FP에서 빌린 또 다른 개념 인 값과 변수의 변경을 피합니다.

이 두 기술은 파이썬과 일반적으로 기능적으로 분류되지 않은 다른 언어에서 잘 작동합니다. 언어 자체 (예 : finalJava의 변수)에 의해 지원되기도합니다 . 따라서, 미래의 유지 보수 프로그래머는 코드를 이해하는 데 방해가되지 않습니다.


2

우리는 작년에 일한 회사에 대해서도 같은 토론을했습니다.

토론은 "매직 코드"와 관련이 있는지 여부와 관련이 있습니다. 좀 더 살펴보면 사람들이 실제로 "매직 코드"에 대해 매우 다른 견해를 가지고있는 것 같습니다. 토론을 제기 한 사람들은 대부분 기능 스타일을 사용한 표현식 (PHP)이 "매직 코드"인 반면 코드에서 더 많은 FP 스타일을 사용한 다른 언어에서 시작한 개발자는 마법 코드가 오히려 파일 이름 등을 통해 파일을 동적으로 포함시킬 때

우리는 이것에 대해 어떤 결론도 내리지 못했습니다. 사람들은 대부분 익숙하지 않은 코드가 "매직"이거나 읽기 어렵다고 생각합니다. 다른 사용자에게 친숙하지 않은 코드를 피하는 것이 좋습니다. 나는 그것이 사용되는 곳에 달려 있다고 생각합니다. 데이터를 명확하고 읽기 쉽고 직관적 인 방식으로 터널링해야하는 기본 방법 (또는 응용 프로그램의 중요한 부분)에서 fp 스타일 식 (동적 파일 포함 등)을 사용하지 않는 것이 좋습니다. 반면에, 나는 봉투를 밀기를 두려워하지 않을 것이라고 생각합니다. 다른 개발자들은 FP 코드에 직면하면 FP를 빨리 배우고 문제에 대해 상담 할 수있는 좋은 사내 리소스를 가지고있을 것입니다.

TL; DR : 응용 프로그램의 높은 수준의 중앙 부분에서는 피하십시오 (응용 프로그램 기능에 대한 개요를 보려면 읽어야합니다). 그렇지 않으면 사용하십시오.


높은 수준의 코드에서는 사용하지 않는 것이 좋습니다!
kd35a

나는 항상 다른 유형의 블록 (정적 메소드, 퍼블릭 메소드, 생성자 등)에서 프로그래밍 기술을 정의 할 때 형식주의가 부족하고 많은 기회가 있다고 생각했습니다. 좋은 대답은 ... 그 생각의.
Sprague

2

C ++ 커뮤니티는 최근에 람다도 얻었으며 거의 ​​비슷한 질문이 있다고 생각합니다. 그러나 대답은 같지 않을 수 있습니다. C ++에 해당하는 것은 다음과 같습니다.

std::copy_if(measures.begin(), measures.end(), inserter(filter),
  [dur](Item i) { return included(i, dur) } );

이제는 std::copy새로운 것이 아니며 _if변형도 새로운 것이 아니지만 람다입니다. 그러나 그것은 문맥에서 다소 명확하게 정의되어 있습니다 : dur캡처되어 일정 Item i하며 루프가 다양하며 단일 return명령문이 모든 작업을 수행합니다.

이것은 많은 C ++ 개발자들에게는 수용 가능해 보입니다. 나는 고차원 람다에 대한 의견을 제시하지 않았으며, 훨씬 덜 받아 들일 것으로 기대합니다.


흥미로운 점은 언어에 따라 다른 답변이있을 수 있다는 점입니다. 아마도 @Christopher Käck 관련 게시물 은 PHP- 코더가 Python- 코더보다 이러한 종류의 문제에 더 많은 문제가 있음을 알려줍니다.
kd35a

0

파이썬에 유창하지 않은 동료 개발자에게 코드 스 니펫을 게시하고 코드를 이해하는지 확인하기 위해 5 분 동안 코드를 조사 할 수 있는지 물어보십시오.

그렇다면 아마도 갈 것입니다. 그렇지 않은 경우 더 명확하게 만들어야합니다.

동료가 멍청하고 분명해야 할 것을 이해하지 못할 수 있습니까? 예,하지만 항상 KISS에 따라 프로그래밍해야합니다.

어쩌면 당신의 코드가 더 간단하고 바보 같은 접근법보다 더 효율적이고보기 좋거나 우아 할 수 있습니까? 그런 다음 스스로에게 자문을 구해야합니다.이 작업을 수행해야합니까? 다시 한 번, 대답이 '아니요'이면하지 마십시오!

이 모든 후에도 여전히 FP 방식이 필요하다고 생각하고 FP 방식을 원한다면 반드시 그렇게하십시오. 본능을 믿으십시오. 포럼의 대부분의 사람들보다 귀하의 요구에 더 적합합니다. :)


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