함수형 프로그래밍이 다른가요? 아니면 실제로 더 힘든가요?


12

함수형 프로그래밍이 다른가 ? 아니면 실제로 더 힘든가 ?

프로그래밍을 전혀 배운 적이없고 기능적 프로그래밍을 배운 사람을 말합니다. 프로그래밍을 전혀 배운 적이없는 사람과 명령형 프로그래밍을 배운 사람. 어느 쪽이 더 힘들까요? 아니면 같은?

내 질문 : 지금 문제는 입력을 낙타 사건이라고 말하십시오.

이러한 것으로는 qwe_asd_zxc_rty_fgh_vbn진다qweAsdZxcRtyFghVbn

절차 적 방법은 다음과 같습니다.

  1. 따라 나누다 _
  2. 첫 번째 항목을 건너 뛰는 배열을 반복하십시오.
  3. 각 항목마다 첫 글자를 대문자로
  4. 결과를 합치다

기능적인 방법은 다음과 같습니다.

  1. _반환을 찾을 수없는 경우input
  2. input첫 번째를 따라 자르십시오 _(우리가 얻는 qwe것과 같이 asd_zxc_rty_gfh_cvb)
  3. 첫 글자를 대문자로 head바꾸고f(tail)

만약 당신이 기능적 배경 을 가지고 있고 절차 적 프로그래밍에 상당한 경험 이 있다면 , 나는 묻고 싶다 : 절차 적 방법을 이해하는데 더 오래 걸리거나 기능적인 방법을 이해하는데 더 오래 걸립니까?

당신이있는 경우 절차-배경을 하지만, 기능적인 프로그래밍 경험의 많은 년, 나는 같은 질문을하고 싶습니다 : 그것은 절차 적 방법을 알아 내기 위해 더 이상 당신을 데려 갈 것이다 있거나 기능에서 그림을 당신을 위해 오래 걸립니다 방법?


5
Ehrm, "프로 시저 방식"은 map돌연변이 루프 대신 3 단계에 사용하면 완벽하게 작동하는 것 같습니다 . 두 번째 방법은 표준 라이브러리에 split 함수가없는 경우에만 고려할 것입니다 (이 경우 사용하지 않는 명령 솔루션과 비교해야합니다 split).
sepp2k 2018 년

8
귀하의 예제 중 하나에 대해 특별히 기능적이거나 절차적인 것은 없습니다. 함수형 프로그래밍에 대한 잘못된 이해에서 외삽하려는 것처럼 들립니다. 특이한 결과를 얻는 것이 당연합니다.
Rein Henrichs

함수형 프로그래밍이 힘들다고 생각하지 않습니다. 프로그래밍 경험이 없으면 배우기 쉽지만 어떤 이유로 명령형 프로그래밍을 배우면 기능 프로그래밍이 어려워집니다.
dan_waterworth

1
JavaScript, C #, Groovy와 같은 주류 언어에는 점점 더 많은 기능이 포함되어 있기 때문에 기능과 절차의 구분이 무의미하다고 생각합니다.
user281377

2
명령형 프로그래밍은 이전 프로그래밍 경험이없는 사람들에게는 훨씬 어렵고 직관적이지 않습니다. 같은 표현 x=x+1은 예기치 않은 뇌를 날려 버릴 수 있습니다. 함수형 프로그래밍은 자연스럽고 순수하고 편리하며 엄격하게 수학 함수일뿐입니다.
SK-logic

답변:


12

그냥 다릅니다. 함수형 프로그래밍은 대부분의 사람들에게 익숙한 수학과 훨씬 더 밀접한 관련이 있습니다. "불변 변수"전체는 "변동"마인드가 깊이 뿌리 박혀있는 명령형 프로그래머에게 충격을줍니다.

새로 온 사람들에게는 무언가 의 가치바꿀 수 없다는 것이 종종 직관적입니다 .

CS를 공부하면서 우리는 첫 번째 과정으로서 기능적 언어를 배웠습니다. 그리고 C ++ 또는 Java를 배운 사람은 모두 이전에 어려움을 겪었습니다. 프로그래밍에 익숙하지 않은 사람들은이를 쉽게 이해할 수있었습니다.


jalf 프로그래밍에 익숙하지 않은 사람들 중 하나입니까?
Pacerier 2016 년

나는 그 사이 어딘가에 있었다. 나는 그 전에 C ++과 일부 PHP로 조금 찔 렀지 만 명령적인 사고 방식에 익숙해지기에는 충분하지 않았습니다. 수업 전체를 보았을 때 패턴이 분명했습니다. 또한 이것은 거의 10 년 전에 이루어
졌으므로

불변 변수? 수학은 함수형 프로그래밍 언어가 아닙니까? 수학의 변수는 확실히 변경 가능합니다.
user56834

20

그냥 다르다

프로그래밍 할 때 당신이 생각하는 방식을 코드로 본질적으로 번역 할 때, 당신의 생각과 최종 솔루션 사이의 거리는 "인지 간격"이라고 할 수 있습니다. 간격이 클수록 브리지하기가 더 어려워집니다.

절차 적 배경에서 온다면 절차 적으로 생각하도록 스스로를 훈련 시켜서 기능 코드의 차이가 줄어들고 그 반대도 마찬가지입니다.

프로그래밍 패러다임이 다른 어떤 것보다 본질적으로 더 쉬운 유일한 방법은 일반 언어와 같이 이미 알고있는 것에 매핑하는 것이므로 짧은 간격으로 시작합니다.

어쨌든 기능적이고 절차적인 개념은 매우 유동적 인 개념이며 겹치는 경향이 있습니다.


4

그렇습니다. 기능 프로그래밍은 많은 사람들이 이해하기 어려운 경향이 있습니다 (특히 이미 절차 적 프로그래밍에 먼저 노출 된 사람들).

또한 함수형 프로그래밍의 예가 실제로 함수형 프로그래밍의 좋은 예는 아니라고 말합니다. 재귀를 사용하고 상태를 수정하는 대신 결과를 작성하지만 그 이상은 아닙니다.

함수형 프로그래밍의 더 좋은 예를 얻으려면 "밑줄을 검색하고 다음 문자를 대문자로 변환"하는 대신보다 일반적인 문제를 고려하십시오. 패턴을 검색하고 임의의 코드를 실행하는 특별한 경우로 생각하십시오. 발견되었습니다.

많은 언어가이를 지원하지만이를 위해서는 정규식과 같은 패턴을 지정해야합니다. 그러나 정규 표현식은 특수 목적의 프로그래밍 언어에 지나지 않으며 RE 구현은 해당 언어의 컴파일러 및 / 또는 해석기입니다. RE를 컴파일 한 결과는 기본적으로 (특수 RE 가상 머신에서) 일부 입력에 대해 표현식을 일치시키기 위해 실행하는 함수입니다.

Perl과 같은 방식으로 특수 언어를 사용하여 패턴을 지정하고 특수 컴파일러를 사용하여 해당 문자열을 일종의 함수와 유사한 것으로 변환하고 특수 해석기가 해당 함수와 같은 것을 실행합니다. 기능적 언어에서는 일반적으로 언어 자체를 사용하여 패턴을 지정하고 언어 자체 컴파일러를 사용하여 실제 함수 를 생성 합니다. 우리는 그 함수를 즉석에서 생성 할 수 있지만 (원하는 경우 RE를 컴파일 할 수있는 것처럼), 그렇게 할 때 특별한 RE 작업을 수행하는 대신 언어의 다른 함수처럼 결과를 실행할 수 있습니다.

결과적으로 문제를 비교적 쉽게 일반화 할 있습니다. 그러나 '_'와 '대문자'를 변환에 직접 하드 코딩하는 대신 다음과 같은 것을 가질 수 있습니다.

s&r(pattern, transform, string) {
    if (!pattern(string))
        return string
    else
        return transform(matched part of string) + s&r(rest of string);
}

그러나 패턴을 RE로 지정하는 것과 달리 패턴을 실제 함수로 직접 지정하고 계속 사용할 수 있습니다.

my_pattern(string) return beginning(string) == '_';

그런 다음 해당 기능 을 s & r에 전달합니다 . 지금은 매우 사소한 기능이며 완전히 정적으로 인코딩했습니다. 기능 언어는 우리가 RE처럼 사용할 때 크게 흥미로워지고 사용자 입력과 같은 것을 기반으로 완전히 새로운 함수를 즉시 생성하지만 함수와 달리 실행하기 위해 특별한 RE 인터프리터가 필요하지 않은 RE와는 달리 다른 것과 마찬가지로 정상적인 기능입니다.


4

라켓 의 전체 코드는 다음과 같습니다 .

;; camelize : string -> string
(define (camelize str)
  (let ([parts (regexp-split #rx"_" str)])
    ;; result of regexp-split is never empty
    (apply string-append
           (first parts)
           (map string-titlecase (rest parts)))))

(camelize "qwe_asd_zxc_rty_fgh_vbn")
;; => "qweAsdZxcRtyFghVbn"

절차 적 경험을 가진 함수형 프로그래머로서, 절차 적 솔루션을 "인식"하는 데 시간이 더 걸리지는 않을 것이라고 생각하지만, 입력하는 데 시간이 더 걸릴 것입니다.

BTW, 원래 게시물의 예상 결과 예가 잘못되었습니다. 끝에 "h"가 없습니다.


지적하기위한 gd. 생성
Pacerier

3

저의 애완 동물 이론은 프로그래밍 모델이 실제 컴퓨터 작업에 더 가까울수록 이해하기 쉽다는 것입니다. 포인터는 본질적으로 기계 주소임을 인식 할 때까지 포인터를 이해하기 어렵습니다. 작은 예제를 의식적으로 밟고 스택 프레임을보고 동일한 변수의 다른 값이 저장되는 위치를 인식 할 때까지 재귀를 이해하기가 어렵습니다. 그렇다고해서 어셈블러 프로그래밍이 고급 프로그래밍보다 쉽다는 것을 의미하지는 않습니다. 그러나 프로그래밍 방식이나 일반 유용성에 관계없이 숙련도에 핵심적인 정신 모델이 어떻게되는지 궁금합니다.

이제 절차 모델은 일반적인 머신 아키텍처에 다소 가깝습니다. 할당은 메모리 (또는 레지스터) 쓰기입니다. 프로 시저 호출은 실제로 멋진 점프이고, if실제로는 조건부 점프입니다. 그러나 Lisp에서는 예를 들어 어휘 바인딩 또는 람다 식에 해당하는 간단한 하위 수준이 없습니다. 그것을 이해하기 위해서는 언어 수준과 실제 기계 사이에 완전히 분리 된 추상 기능 기계를 상상해야합니다. 왜냐하면 대부분의 사람들은 결코 그렇게 멀지 않기 때문입니다.

(나는 생각 폰 노이만 아키텍처는 궁극적으로 임의이라는 생각을 잘 알고, 우리가 대신 직접적 관련이없는 컴퓨터 아키텍처의 세부 사항과와 편견 초보자의 마음은 프로그래밍 언어의 의미에 소개는 안된다. 사실, 나는했습니다 그러나 나는 점점 고귀하지만 잘못 인도 된 목표라고 생각한다. 사람들은 처음부터 이해를 쌓아서 프로그래밍을 배우고 함수형 프로그래밍으로가는 길은 더 길다.)


7
그 논리에 따라 어셈블러는 모든 언어 중에서 가장 배우기
쉬워야합니다.)

4
함수형 프로그래밍은 올바른 방향에서 나오면 이해하기 쉽습니다. 언급 한 "추상적 인 기능성 기계"는 간단히 대수 입니다. 평가는 용어 재 작성에 의해 수행됩니다. 기능 적용은 대체에 의해 수행됩니다. 프로그래머는 수년간의 수학 클래스에서 이미 본 것과 동일한 도구를 사용하여 문제를 해결하는 방법을 배웁니다. 그들이 CS를 추구한다면 나중에 거북 더미를 만날 시간이 충분하다. 그렇지 않은 경우에도 여전히 유용한 문제 해결 기술과 디자인 원칙을 배웠습니다. 프로그램 설계 방법을 살펴보십시오 .
Ryan Culpepper 2016 년

2
@mko 아니요,이 논리에 의해 실제 바이트 코드 011011001001101...는 배우기 가장 쉬운 언어입니다!
MarkJ

2
@konrad : RISC 어셈블러는 아마도 배우기 가장 쉬운 언어 일 것입니다. 유용한 무언가를 만드는 방법을 아는 것은 또 다른 이야기입니다.
Bryan Boettcher
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.