기능적 프로그래밍 언어와 명령형 프로그래밍 언어의 차이점은 무엇입니까?
C #, Visual Basic, C ++ 및 Java와 같은 OOP (object-oriented programming) 언어를 포함한 대부분의 주류 언어는 명령형 (프로 시추 럴) 프로그래밍을 지원하도록 설계되었지만 Haskell / gofer와 같은 언어는 순전히 기능적입니다. 이 두 가지 프로그래밍 방법의 차이점이 무엇인지 자세히 설명 할 수 있습니까?
프로그래밍 방식을 선택하는 것은 사용자 요구 사항에 달려 있지만 기능적 프로그래밍 언어를 배우는 것이 권장되는 이유는 무엇입니까?
정의 : 명령형 언어는 일련의 문장을 사용하여 특정 목표에 도달하는 방법을 결정합니다. 이 문장들은 각각 차례로 실행될 때 프로그램의 상태를 변경한다고합니다.
예 : Java는 필수 언어입니다. 예를 들어 일련의 숫자를 추가하는 프로그램을 만들 수 있습니다.
int total = 0;
int number1 = 5;
int number2 = 10;
int number3 = 15;
total = number1 + number2 + number3;
각 명령문은 값을 각 변수에 지정하는 것에서 해당 값의 최종 추가에 이르기까지 프로그램의 상태를 변경합니다. 일련의 5 개의 문장을 사용하여 프로그램은 숫자 5, 10 및 15를 함께 더하는 방법을 명시 적으로 알려줍니다.
기능적 언어 : 기능적 프로그래밍 패러다임은 문제 해결에 대한 순수한 기능적 접근을 지원하기 위해 명시 적으로 작성되었습니다. 함수형 프로그래밍은 선언적 프로그래밍의 한 형태입니다.
순수 함수의 장점 : 순수 함수로 함수 변환을 구현하는 주된 이유는 순수 함수를 구성 할 수 있다는 것입니다. 즉, 자체 포함 및 상태 비 저장입니다. 이러한 특성으로 인해 다음과 같은 여러 가지 이점이 있습니다. 가독성 및 유지 관리 성 향상. 각 기능은 주어진 인수에 따라 특정 작업을 수행하도록 설계 되었기 때문입니다. 이 기능은 외부 상태에 의존하지 않습니다.
더 쉬운 반복 개발. 코드를 리팩토링하기가 쉽기 때문에 디자인 변경이 구현하기가 더 쉬운 경우가 많습니다. 예를 들어, 복잡한 변환을 작성한 다음 변환에서 일부 코드가 여러 번 반복된다는 것을 인식하십시오. 순수한 메소드를 통해 리팩토링하면 부작용에 대해 걱정하지 않고 순수한 메소드를 호출 할 수 있습니다.
더 쉬운 테스트 및 디버깅. 순수 함수는 더 쉽게 테스트 할 수 있으므로 일반적인 값, 유효 엣지 케이스 및 유효하지 않은 엣지 케이스를 사용하여 순수 함수를 호출하는 테스트 코드를 작성할 수 있습니다.
OOP 사용자 또는 명령형 언어의 경우 :
객체 지향 언어는 사물에 대한 고정 된 조작 세트가 있고 코드가 발전함에 따라 주로 새로운 사물을 추가 할 때 좋습니다. 기존 메소드를 구현하는 새 클래스를 추가하면 기존 클래스를 그대로 유지할 수 있습니다.
기능적 언어는 고정 된 사물 집합이 있고 코드가 발전함에 따라 기존 사물에 대한 새로운 작업을 주로 추가 할 때 좋습니다. 기존 데이터 유형으로 계산하는 새 기능을 추가하면 기존 기능이 그대로 유지됩니다.
단점 :
프로그래밍 방식을 선택하는 것은 사용자 요구 사항에 따라 달라 지므로 사용자가 올바른 방식을 선택하지 않을 경우에만 피해가 발생합니다.
진화가 잘못되면 문제가 있습니다.
- 객체 지향 프로그램에 새로운 작업을 추가하려면 새로운 메소드를 추가하기 위해 많은 클래스 정의를 편집해야 할 수 있습니다
- 기능 프로그램에 새로운 종류의 것을 추가하려면 새로운 기능을 추가하기 위해 많은 기능 정의를 편집해야합니다.
차이점은 다음과 같습니다.
피할 수 없는:
- 스타트
- 신발 사이즈 9 1/2를 켭니다.
- 열쇠 [7]를 보관할 수있는 공간을 주머니에 넣으십시오.
- 열쇠를 주머니에 넣을 방에 열쇠를 넣으십시오.
- 차고를 입력하십시오.
- 차고를 엽니 다.
- 차를 입력하십시오.
... 등등 ...
- 냉장고에 우유를 넣으십시오.
- 중지.
기능적 하위 범주 인 선언적 :
- 유당 소화에 문제가 없다면 우유는 건강 음료입니다.
- 일반적으로 냉장고에 우유를 저장합니다.
- 냉장고는 물건을 시원하게 보관하는 상자입니다.
- 상점은 품목이 판매되는 장소입니다.
- "판매"는 돈으로 물건을 교환하는 것을 의미합니다.
- 또한 물건으로 돈을 교환하는 것을 "구매"라고합니다.
... 등등 ...
- 냉장고에 우유가 있는지 확인하십시오 (필요한 경우-게으른 기능적 언어의 경우).
요약 : 명령형 언어에서는 컴퓨터에서 메모리의 비트, 바이트 및 단어를 변경하는 방법과 순서를 알려줍니다. 기능적인 것들에서, 우리는 컴퓨터에게 사물, 행동 등이 무엇인지 알려줍니다. 예를 들어, 0의 계승은 1이고 다른 모든 자연수의 계승은 그 수의 곱과 전임의 계승이라고합니다. 우리는 말하지 않습니다 : n의 계승을 계산하려면 메모리 영역을 예약하고 거기에 1을 저장 한 다음 해당 메모리 영역의 숫자에 숫자 2에서 n을 곱하고 결과를 같은 장소에 저장하십시오. 메모리 영역에는 계승이 포함됩니다.
대부분의 현대 언어는 명령형과 기능면에서 다양하지만 기능적 프로그래밍을 더 잘 이해하려면 java / c #과 같은 기능적 언어가 아닌 명령형 코드와 대조적으로 Haskell과 같은 순수한 기능적 언어의 예를 취하는 것이 가장 좋습니다. 나는 항상 예제로 설명하기가 쉽다고 생각하므로 아래는 하나입니다.
함수형 프로그래밍 : n, n의 계승 계산! 즉, nx (n-1) x (n-2) x ... x 2 X 1
-- | Haskell comment goes like
-- | below 2 lines is code to calculate factorial and 3rd is it's execution
factorial 0 = 1
factorial n = n * factorial (n - 1)
factorial 3
-- | for brevity let's call factorial as f; And x => y shows order execution left to right
-- | above executes as := f(3) as 3 x f(2) => f(2) as 2 x f(1) => f(1) as 1 x f(0) => f(0) as 1
-- | 3 x (2 x (1 x (1)) = 6
Haskel을 사용하면 함수 값을 인수 값 수준으로 오버로드 할 수 있습니다. 다음은 명령의 정도를 증가시키는 명령 코드의 예입니다.
//somewhat functional way
function factorial(n) {
if(n < 1) {
return 1;
}
return n * factorial(n-1);
}
factorial(3);
//somewhat more imperative way
function imperativeFactor(n) {
int f = 1
for(int i = 1; i <= n; i++) {
f = f * i
}
return f;
}
이 읽기 는 명령형 코드가 부분, 기계 상태 (i in for loop), 실행 순서, 흐름 제어에 어떻게 초점을 맞추는 지 이해하기에 좋은 참고 자료가 될 수 있습니다.
The later example can be seen as java/c# lang code roughly and first part as limitation of the language itself in contrast of Haskell to overload the function by value ( zero ) and hence can be said it is not purist functional language, on the other hand you can say it support functional prog. to some extent.
Disclosure: none of the above code is tested/executed but hopefully should be good enough to convey the concept; also I would appreciate comments for any such correction :)
Functional Programming is a form of declarative programming, which describe the logic of computation and the order of execution is completely de-emphasized.
Problem: I want to change this creature from a horse to a giraffe.
- Lengthen neck
- Lengthen legs
- Apply spots
- Give the creature a black tongue
- Remove horse tail
Each item can be run in any order to produce the same result.
Imperative Programming is procedural. State and order is important.
Problem: I want to park my car.
- Note the initial state of the garage door
- Stop car in driveway
- If the garage door is closed, open garage door, remember new state; otherwise continue
- Pull car into garage
- Close garage door
Each step must be done in order to arrive at desired result. Pulling into the garage while the garage door is closed would result in a broken garage door.
Functional programming is "programming with functions," where a function has some expected mathematical properties, including referential transparency. From these properties, further properties flow, in particular familiar reasoning steps enabled by substitutability that lead to mathematical proofs (i.e. justifying confidence in a result).
It follows that a functional program is merely an expression.
You can easily see the contrast between the two styles by noting the places in an imperative program where an expression is no longer referentially transparent (and therefore is not built with functions and values, and cannot itself be part of a function). The two most obvious places are: mutation (e.g. variables) other side-effects non-local control flow (e.g. exceptions)
On this framework of programs-as-expressions which are composed of functions and values, is built an entire practical paradigm of languages, concepts, "functional patterns", combinators, and various type systems and evaluation algorithms.
By the most extreme definition, almost any language—even C or Java—can be called functional, but usually people reserve the term for languages with specifically relevant abstractions (such as closures, immutable values, and syntactic aids like pattern matching). As far as use of functional programming is concerned it involves use of functins and builds code without any side effects . used to write proofs
Imperative programming style was practiced in web development from 2005 all the way to 2013.
With imperative programming, we wrote out code that listed exactly what our application should do, step by step.
The functional programming style produces abstraction through clever ways of combining functions.
There is mention of declarative programming in the answers and regarding that I will say that declarative programming lists out some rules that we are to follow. We then provide what we refer to as some initial state to our application and we let those rules kind of define how the application behaves.
Now, these quick descriptions probably don’t make a lot of sense, so lets walk through the differences between imperative and declarative programming by walking through an analogy.
Imagine that we are not building software, but instead we bake pies for a living. Perhaps we are bad bakers and don’t know how to bake a delicious pie the way we should.
So our boss gives us a list of directions, what we know as a recipe.
The recipe will tell us how to make a pie. One recipe is written in an imperative style like so:
- Mix 1 cup of flour
- Add 1 egg
- Add 1 cup of sugar
- Pour the mixture into a pan
- Put the pan in the oven for 30 minutes and 350 degrees F.
The declarative recipe would do the following:
1 cup of flour, 1 egg, 1 cup of sugar - initial State
Rules
- If everything mixed, place in pan.
- If everything unmixed, place in bowl.
- If everything in pan, place in oven.
So imperative approaches are characterized by step by step approaches. You start with step one and go to step 2 and so on.
You eventually end up with some end product. So making this pie, we take these ingredients mix them, put it in a pan and in the oven and you got your end product.
In a declarative world, its different.In the declarative recipe we would separate our recipe into two separate parts, start with one part that lists the initial state of the recipe, like the variables. So our variables here are the quantities of our ingredients and their type.
We take the initial state or initial ingredients and apply some rules to them.
So we take the initial state and pass them through these rules over and over again until we get a ready to eat rhubarb strawberry pie or whatever.
So in a declarative approach, we have to know how to properly structure these rules.
So the rules we might want to examine our ingredients or state, if mixed, put them in a pan.
With our initial state, that doesn’t match because we haven’t yet mixed our ingredients.
So rule 2 says, if they not mixed then mix them in a bowl. Okay yeah this rule applies.
Now we have a bowl of mixed ingredients as our state.
Now we apply that new state to our rules again.
So rule 1 says if ingredients are mixed place them in a pan, okay yeah now rule 1 does apply, lets do it.
Now we have this new state where the ingredients are mixed and in a pan. Rule 1 is no longer relevant, rule 2 does not apply.
Rule 3 says if the ingredients are in a pan, place them in the oven, great that rule is what applies to this new state, lets do it.
And we end up with a delicious hot apple pie or whatever.
Now, if you are like me, you may be thinking, why are we not still doing imperative programming. This makes sense.
Well, for simple flows yes, but most web applications have more complex flows that cannot be properly captured by imperative programming design.
In a declarative approach, we may have some initial ingredients or initial state like textInput=“”
, a single variable.
Maybe text input starts off as an empty string.
We take this initial state and apply it to a set of rules defined in your application.
If a user enters text, update text input. Well, right now that doesn’t apply.
If template is rendered, calculate the widget.
- If textInput is updated, re render the template.
Well, none of this applies so the program will just wait around for an event to happen.
So at some point a user updates the text input and then we might apply rule number 1.
We may update that to “abcd”
So we just updated our text and textInput updates, rule number 2 does not apply, rule number 3 says if text input is update, which just occurred, then re render the template and then we go back to rule 2 thats says if template is rendered, calculate the widget, okay lets calculate the widget.
In general, as programmers, we want to strive for more declarative programming designs.
Imperative seems more clear and obvious, but a declarative approach scales very nicely for larger applications.
I think it's possible to express functional programming in an imperative fashion:
- Using a lot of state check of objects and
if... else
/switch
statements - Some timeout/ wait mechanism to take care of asynchornousness
There are huge problems with such approach:
- Rules/ procedures are repeated
- Statefulness leaves chances for side-effects/ mistakes
Functional programming, treating functions/ methods like objects and embracing statelessness, was born to solve those problems I believe.
Example of usages: frontend applications like Android, iOS or web apps' logics incl. communication with backend.
Other challenges when simulating functional programming with imperative/ procedural code:
- Race condition
- Complex combination and sequence of events. For example, user tries to send money in a banking app. Step 1) Do all of the following in parallel, only proceed if all is good a) Check if user is still good (fraud, AML) b) check if user has enough balance c) Check if recipient is valid and good (fraud, AML) etc. Step 2) perform the transfer operation Step 3) Show update on user's balance and/ or some kind of tracking. With RxJava for example, the code is concise and sensible. Without it, I can imagine there'd be a lot of code, messy and error prone code
I also believe that at the end of the day, functional code will get translated into assembly or machine code which is imperative/ procedural by the compilers. However, unless you write assembly, as humans writing code with high level/ human-readable language, functional programming is the more appropriate way of expression for the listed scenarios
I know this question is older and others already explained it well, I would like to give an example problem which explains the same in simple terms.
Problem: Writing the 1's table.
Solution: -
By Imperative style: =>
1*1=1
1*2=2
1*3=3
.
.
.
1*n=n
By Functional style: =>
1
2
3
.
.
.
n
Explanation in Imperative style we write the instructions more explicitly and which can be called as in more simplified manner.
Where as in Functional style, things which are self-explanatory will be ignored.
'programing tip' 카테고리의 다른 글
기본 클래스 org.gradle.wrapper.GradleWrapperMain을 찾거나로드 할 수 없습니다. (0) | 2020.06.29 |
---|---|
Keytool 애플리케이션은 어디에 있습니까? (0) | 2020.06.29 |
Swift에서 클로저를 변수로 저장 (0) | 2020.06.29 |
Xcode 7 베타 경고 : 인터페이스 방향 및 시작 스토리 보드 (0) | 2020.06.29 |
계획된 "개인 보호"C # 액세스 수정 자의 의미는 무엇입니까? (0) | 2020.06.28 |