[functional-programming] 절차 적 프로그래밍과 기능적 프로그래밍의 차이점은 무엇입니까? [닫은]

절차 적 프로그래밍함수형 프로그래밍에 대한 Wikipedia 기사를 읽었 지만 여전히 약간 혼란 스럽습니다. 누군가 그것을 핵심으로 끓일 수 있습니까?



답변

함수형 언어는 (이상적으로) 수학 함수, 즉 n 개의 인수 를 가져 와서 값을 반환하는 함수를 작성할 수 있습니다 . 프로그램이 실행되면이 기능은 필요에 따라 논리적으로 평가됩니다. 1

반면 절차 언어는 일련의 순차적 단계를 수행합니다. (순차 논리를 연속 전달 스타일 이라는 기능적 논리로 변환하는 방법이 있습니다 .)

결과적으로 순전히 기능적인 프로그램 은 입력에 대해 항상 동일한 값 을 산출 하며 평가 순서는 잘 정의되지 않습니다. 즉, 사용자 입력 또는 임의 값과 같은 불확실한 값은 순전히 기능적인 언어로 모델링하기가 어렵습니다.


1 이 답변의 다른 모든 내용은 일반화입니다. 이 속성은 결과가 호출되는 곳이 아닌 결과가 필요할 때 계산을 평가하는 것을 “게으름”이라고합니다. 모든 기능적 언어가 실제로 보편적으로 게으른 것도 아니고 게으름도 기능적 프로그래밍으로 제한되지 않습니다. 오히려, 여기에 주어진 설명은 구별되고 반대되는 범주가 아니라 유동적 인 아이디어 인 서로 다른 프로그래밍 스타일에 대해 생각하기위한“정신적 틀”을 제공합니다.


답변

기본적으로 두 가지 스타일은 음과 양입니다. 하나는 조직되어 있고 다른 하나는 혼란입니다. 기능적 프로그래밍이 확실한 선택 인 상황이 있으며 다른 상황은 절차 적 프로그래밍이 더 나은 선택입니다. 그렇기 때문에 최근 두 가지 프로그래밍 스타일을 모두 수용하는 새로운 버전의 언어가 두 개 이상 있습니다. ( 펄 6D 2 )

절차 :

  • 루틴의 출력이 항상 입력과 직접적인 상관 관계가있는 것은 아닙니다.
  • 모든 것은 특정 순서로 이루어집니다.
  • 루틴을 실행하면 부작용이있을 수 있습니다.
  • 선형 방식으로 솔루션 구현을 강조하는 경향이 있습니다.

펄 6

sub factorial ( UInt:D $n is copy ) returns UInt {

  # modify "outside" state
  state $call-count++;
  # in this case it is rather pointless as
  # it can't even be accessed from outside

  my $result = 1;

  loop ( ; $n > 0 ; $n-- ){

    $result *= $n;

  }

  return $result;
}

D 2

int factorial( int n ){

  int result = 1;

  for( ; n > 0 ; n-- ){
    result *= n;
  }

  return result;
}

기능의:

  • 종종 재귀 적입니다.
  • 주어진 입력에 대해 항상 동일한 출력을 반환합니다.
  • 평가 순서는 일반적으로 정의되지 않습니다.
  • 상태 비 저장이어야합니다. 즉, 아무 작업도 부작용을 가질 수 없습니다.
  • 병렬 실행에 적합
  • 나누고 정복하는 접근법을 강조하는 경향이 있습니다.
  • 지연 평가 기능이있을 수 있습니다.

하스켈

( Wikipedia 에서 복사 );

fac :: Integer -> Integer

fac 0 = 1
fac n | n > 0 = n * fac (n-1)

또는 한 줄로 :

fac n = if n > 0 then n * fac (n-1) else 1

펄 6

proto sub factorial ( UInt:D $n ) returns UInt {*}

multi sub factorial (  0 ) { 1 }
multi sub factorial ( $n ) { $n * samewith $n-1 } # { $n * factorial $n-1 }

D 2

pure int factorial( invariant int n ){
  if( n <= 1 ){
    return 1;
  }else{
    return n * factorial( n-1 );
  }
}

사이드 노트 :

팩토리얼은 실제로 서브 루틴을 만들 때와 같은 방식으로 Perl 6에서 새 연산자를 만드는 것이 얼마나 쉬운지를 보여주는 일반적인 예입니다. 이 기능은 Perl 6에 세분화되어 Rakudo 구현의 대부분의 연산자가이 방식으로 정의됩니다. 또한 기존 연산자에 고유 한 다중 후보를 추가 할 수도 있습니다.

sub postfix:< ! > ( UInt:D $n --> UInt )
  is tighter(&infix:<*>)
  { [*] 2 .. $n }

say 5!; # 120␤

이 예는 또한 숫자 작성 곱셈 연산자와 결합 된 범위 작성 2..$n메타 연산자 ( [ OPERATOR ] LIST) 및 목록 작성 메타 연산자 ( )를 보여줍니다 . ( *)
또한 --> UInt서명 대신 서명을 넣을 수 있음을 보여줍니다 returns UInt.

( 인수없이 호출 2하면 곱하기 “연산자”가 반환 되므로 범위를 시작하여 벗어날 수 있습니다 1)


답변

나는 다른 곳 에서이 정의를 본 적이 없지만 여기에 주어진 차이점을 상당히 잘 요약한다고 생각합니다.

함수형 프로그래밍은 표현식에 중점을 둡니다.

절차 적 프로그래밍은 문장에 중점을 둡니다 .

표현식에는 값이 있습니다. 기능적 프로그램은 가치있는 표현으로서 컴퓨터가 수행해야 할 일련의 명령입니다.

명령문에는 값이없고 대신 일부 개념적 기계의 상태를 수정합니다.

순전히 기능적인 언어에서는 상태를 조작 할 수있는 방법이 없다는 의미에서 어떤 진술도 없을 것입니다 (그들은 여전히 ​​”statement”라는 구문 구조를 가질 수 있지만, 상태를 조작하지 않으면 이러한 의미에서 진술이라고하지 않습니다. ). 순전히 절차적인 언어에서는 표현이 없으며 모든 것은 기계의 상태를 조작하는 명령 일 것입니다.

Haskell은 상태를 조작 할 방법이 없기 때문에 순전히 기능적인 언어의 예입니다. 프로그램의 모든 것은 머신의 레지스터와 메모리의 상태를 조작하는 명령문이기 때문에 머신 코드는 순전히 절차 적 언어의 예입니다.

혼란스러운 부분은 대다수의 프로그래밍 언어에 표현과 문장이 모두 포함되어 있어 패러다임을 혼합 할 수 있다는 것입니다. 언어는 문장 대 표현의 사용을 장려하는 정도에 따라 기능적 또는 절차 적 언어로 분류 될 수 있습니다.

예를 들어, 함수 호출은 표현식이기 때문에 C는 COBOL보다 기능적이지만 COBOL에서 서브 프로그램 호출은 명령문 (공유 변수의 상태를 조작하고 값을 리턴하지 않음)입니다. Python은 단락 평가를 사용하여 조건부 논리를 표현식으로 표현할 수 있기 때문에 C보다 더 기능적입니다 (if 문이 아닌 test && path1 || path2). 체계의 모든 것이 표현이기 때문에 체계는 파이썬보다 더 기능적입니다.

절차 적 패러다임을 장려하는 언어로 기능적 스타일로 작성할 수 있으며 그 반대도 마찬가지입니다. 언어에서 권장하지 않는 패러다임으로 글을 쓰는 것이 더 어려워지고 어색합니다.


답변

컴퓨터 과학에서 기능 프로그래밍은 계산을 수학 함수의 평가로 취급하고 상태 및 변경 가능한 데이터를 피하는 프로그래밍 패러다임입니다. 상태의 변화를 강조하는 절차 적 프로그래밍 스타일과 달리 함수의 적용을 강조합니다.


답변

절차 적 / 기능적 / 객관적 프로그래밍은 문제에 접근하는 방법에 관한 것이라고 생각합니다.

첫 번째 스타일은 모든 단계를 계획하고 한 번에 한 단계 (절차)를 구현하여 문제를 해결합니다. 다른 한편으로, 함수형 프로그래밍은 문제가 하위 문제로 나뉘고 각 하위 문제가 해결되고 (해당 하위 문제를 해결하기위한 함수 작성) 결과가 결합되는 분할 및 정복 방식을 강조합니다. 전체 문제에 대한 답을 만드십시오. 마지막으로, 객관적 프로그래밍은 컴퓨터 내에 각각 고유 한 특성을 가지고 있으며 다른 객체와 상호 작용하는 많은 객체가있는 미니 월드를 만들어 실제 세계를 모방합니다. 이러한 상호 작용에서 결과가 나타납니다.

각 스타일의 프로그래밍에는 고유 한 장단점이 있습니다. 따라서 “순수한 프로그래밍”과 같은 것을 수행하는 것 (즉, 순전히 절차 적-아무도 이상한 일을하거나 전혀 기능적이거나 순전히 객관적인 일을하지 않습니다)은 일부 초급 문제를 제외하고는 불가능하지는 않지만 매우 어렵습니다. 프로그래밍 스타일의 장점을 보여 주도록 설계되었습니다 (따라서 순수성을 좋아하는 사람들을 “weenie”: D라고합니다).

그런 다음 이러한 스타일에서 각 스타일에 맞게 최적화 된 프로그래밍 언어가 있습니다. 예를 들어, 어셈블리는 모든 절차에 관한 것입니다. 자, 대부분의 초기 언어는 C, Pascal과 같은 Asm뿐만 아니라 절차 적입니다 (Fortran, 나는 들었습니다). 그런 다음 우리는 객관적인 학교에서 모두 유명한 Java를 가지고 있습니다 (실제로 Java와 C #은 “돈 지향”이라는 클래스에 있지만 다른 토론의 대상입니다). 또한 목표는 스몰 토크입니다. 기능 학교에서는 “거의 기능적”(일부는 불완전한 것으로 간주) Lisp 가족 및 ML 가족과 많은 “순전히 기능적인”Haskell, Erlang 등을 갖습니다. 그런데 Perl, Python과 같은 많은 일반 언어가 있습니다. 루비


답변

함수형 프로그래밍

num = 1
def function_to_add_one(num):
    num += 1
    return num


function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)

#Final Output: 2

절차 적 프로그래밍

num = 1
def procedure_to_add_one():
    global num
    num += 1
    return num


procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()

#Final Output: 6

function_to_add_one 기능이다

procedure_to_add_one 절차이다

함수를 5 번 실행하더라도 2 를 반환 할 때마다

당신이 실행하는 경우 절차를 다섯 번, 다섯 번째 실행의 끝에서 당신에게 줄 것이다 (6) .


답변

Konrad의 의견을 확대하려면 :

결과적으로 순전히 기능적인 프로그램은 입력에 대해 항상 동일한 값을 산출하며 평가 순서는 잘 정의되지 않습니다.

이 때문에 기능 코드는 일반적으로 병렬화가 더 쉽습니다. 함수의 부작용은 (일반적으로) 없으며, 일반적으로 인수에 대해 행동하기 때문에 많은 동시성 문제가 사라집니다.

함수형 프로그래밍은 코드가 올바른지 증명할 수 있어야 할 때도 사용됩니다 . 이것은 절차 적 프로그래밍과는 훨씬 더 어렵습니다 (기능적으로 쉽지는 않지만 여전히 더 쉽습니다).

면책 조항 : 몇 년 동안 기능 프로그래밍을 사용하지 않았으며 최근에 다시보기 시작 했으므로 여기에 완전히 정확하지 않을 수 있습니다. 🙂