웹을 검색하여 선언적이고 명령적인 프로그래밍에 대한 정의를 찾고 있습니다. 그러나 내가 찾은 리소스 중 일부에 사용 된 언어는 매우 어려운 것입니다 (예 : Wikipedia) . 누구 든지이 주제 (아마도 C #)에 대한 관점을 가져올 수있는 실제 사례가 있습니까?
웹을 검색하여 선언적이고 명령적인 프로그래밍에 대한 정의를 찾고 있습니다. 그러나 내가 찾은 리소스 중 일부에 사용 된 언어는 매우 어려운 것입니다 (예 : Wikipedia) . 누구 든지이 주제 (아마도 C #)에 대한 관점을 가져올 수있는 실제 사례가 있습니까?
답변:
선언적 프로그래밍과 명령형 프로그래밍의 훌륭한 C # 예제는 LINQ입니다.
명령형 프로그래밍을 사용하면 컴파일러에게 원하는 단계를 단계별로 알려줍니다.
예를 들어이 모음부터 시작하여 홀수를 선택해 봅시다.
List<int> collection = new List<int> { 1, 2, 3, 4, 5 };
명령형 프로그래밍을 통해이를 단계별로 수행하고 원하는 것을 결정합니다.
List<int> results = new List<int>();
foreach(var num in collection)
{
if (num % 2 != 0)
results.Add(num);
}
여기, 우리는 말합니다 :
반면에 선언적 프로그래밍을 사용 하면 원하는 것을 설명하지만 반드시 얻는 방법을 설명하지는 않는 코드를 작성합니다 (원하는 결과는 선언하지만 단계별로 선언하지는 않음).
var results = collection.Where( num => num % 2 != 0);
여기서는 "모음 단계를 거치지 말고"이상한 부분을 모두 알려주십시오 "라고 말하고 있습니다.이 항목이 이상하지 않으면 결과 모음에 추가하십시오."
많은 경우 코드는 두 디자인이 혼합되어 있으므로 항상 흑백이 아닙니다.
collection.Where
Linq가 제공하는 선언적 구문을 사용하지 않습니다. 예를 들어 msdn.microsoft.com/en-us/library/bb397906.aspx 를 참조 하십시오from item in collection where item%2 != 0 select item
. 함수 호출은 함수가 System.Linq 네임 스페이스에 있다고해서 선언 프로그래밍이되지 않습니다.
선언적 프로그래밍은 원하는 것을 말할 때이며 명령형 언어는 원하는 것을 얻는 방법 을 말할 때 입니다.
파이썬의 간단한 예 :
# Declarative
small_nums = [x for x in range(20) if x < 5]
# Imperative
small_nums = []
for i in range(20):
if i < 5:
small_nums.append(i)
첫 번째 예는 목록을 작성하는 "구현 세부 사항"을 지정하지 않기 때문에 선언적입니다.
C # 예제를 연결하면 일반적으로 LINQ를 사용 하면 원하는 스타일 을 얻는 방법 을 말하지 않기 때문에 선언적인 스타일 이됩니다. 당신은 당신이 원하는 것을 말하고 있습니다. SQL에 대해서도 똑같이 말할 수 있습니다.
선언적 프로그래밍의 장점 중 하나는 컴파일러가 직접 작성하는 것보다 더 나은 코드를 생성 할 수있는 결정을 내릴 수 있다는 것입니다. 다음과 같은 쿼리가있는 경우 SQL 예제로 실행
SELECT score FROM games WHERE id < 100;
SQL "컴파일러"는이 id
필드가 인덱스 필드인지 또는 인덱스되지 않은지 알고 있기 때문에이 쿼리를 "최적화"할 수 있습니다.이 경우 어쨌든 전체 데이터 세트를 반복해야합니다. 또는 SQL 엔진이 빠른 병렬 검색을 위해 8 개 코어를 모두 사용하기에 완벽한시기라는 것을 알고있을 것입니다. 프로그래머로서 여러분 은 이러한 조건에 관심이 없으며 특별한 경우를 처리하기 위해 코드를 작성할 필요가 없습니다.
선언적 대 명령형
프로그래밍 패러다임은 컴퓨터 프로그래밍의 기본 스타일입니다. 명령 적, 선언적, 기능적 (선언적 패러다임의 하위 집합으로 간주) 및 객체 지향의 네 가지 기본 패러다임이 있습니다.
선언적 프로그래밍 (Declarative programming) : 제어 흐름을 설명하지 않고 (무엇을하는지) 계산 논리를 표현하는 프로그래밍 패러다임입니다. DSL (Declarative Domain Specific Language)의 잘 알려진 예로는 CSS, 정규식 및 SQL의 하위 집합 (예 : SELECT 쿼리)이 있습니다. HTML, MXML, XAML, XSLT ...와 같은 많은 마크 업 언어가 종종 선언적입니다. 선언적 프로그래밍은 명령 세트로서의 프로그램과 원하는 답에 대한 주장으로서의 프로그램 간의 구별을 흐리게하려고 시도합니다.
명령형 프로그래밍 : 프로그램 상태를 변경하는 명령문으로 계산을 설명하는 프로그래밍 패러다임입니다. 선언적 프로그램은 프로그래밍 명령 또는 수학적 주장으로 이중으로 볼 수 있습니다.
함수형 프로그래밍 : 계산을 수학 함수의 평가로 취급하고 상태 및 변경 가능한 데이터를 피하는 프로그래밍 패러다임입니다. 상태의 변화를 강조하는 명령형 프로그래밍 스타일과 달리 함수 적용을 강조합니다. Haskell과 같은 순수 기능 언어에서 모든 기능에는 부작용이 없으며 상태 변경은 상태를 변환하는 기능으로 만 나타납니다.
MSDN 에서 다음과 같은 명령형 프로그래밍 예제는 1에서 10까지의 숫자를 반복하여 짝수를 찾습니다.
var numbersOneThroughTen = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//With imperative programming, we'd step through this, and decide what we want:
var evenNumbers = new List<int>();
foreach (var number in numbersOneThroughTen)
{ if (number % 2 == 0)
{
evenNumbers.Add(number);
}
}
//The following code uses declarative programming to accomplish the same thing.
// Here, we're saying "Give us everything where it's odd"
var evenNumbers = numbersOneThroughTen.Select(number => number % 2 == 0);
두 예제는 모두 같은 결과를 낳으며 하나는 다른 것보다 나쁘지 않습니다. 첫 번째 예제에는 더 많은 코드가 필요하지만 코드를 테스트 할 수 있으며 명령 방식을 통해 구현 세부 정보를 완전히 제어 할 수 있습니다. 두 번째 예에서 코드는 더 읽기 쉽다. 그러나 LINQ는 장면 뒤에서 일어나는 일을 제어 할 수 없습니다. LINQ가 요청한 결과를 제공 할 것임을 신뢰해야합니다.
위의 모든 답변과 다른 온라인 게시물은 다음과 같습니다.
그들이 우리에게 말하지 않은 것은 그것을 달성하는 방법 입니다. 프로그램의 일부를보다 선언적으로 표현하려면 다른 부분 에서 구현 세부 사항 ( 명령형 코드) 을 숨기도록 추상화 를 제공 해야합니다 .
list.Where()
새로운 필터링 된 목록을 얻는 데 사용할 수 있습니다 . 이것이 작동하기 위해 Microsoft는 LINQ 추상화에 대한 모든 노력을 기울였습니다.실제로 함수형 프로그래밍과 함수형 라이브러리가 더 선언적인 이유 중 하나는 루프와 목록 생성을 추상화하여 모든 구현 세부 사항 (루프가있는 명령형 코드)을 숨기고 있기 때문입니다.
어떤 프로그램에서든 항상 명령형 코드와 선언적 코드가 모두 있어야 합니다. 프로그램의 다른 부분이 선언적으로 사용할 수 있도록 추상화 뒤에 모든 명령형 코드 를 숨기는 것 입니다.
마지막으로 함수형 프로그래밍과 LINQ를 사용하면 프로그램을보다 선언적으로 만들 수 있지만 더 많은 추상화를 제공하여 항상 더 선언적으로 만들 수 있습니다. 예를 들면 다음과 같습니다.
// JavaScript example
// Least declarative
const bestProducts = [];
for(let i = 0; i < products.length; i++) {
let product = products[i];
if (product.rating >= 5 && product.price < 100) {
bestProducts.push(product);
}
}
// More declarative
const bestProducts = products.filter(function(product) {
return product.rating >= 5 && product.price < 100;
});
// Most declarative, implementation details are hidden in a function
const bestProducts = getBestProducts();
PS 선언적 프로그래밍의 극단적 인 점은 새로운 도메인 특정 언어 (DSL)를 발명하는 것입니다.
debit
, deposit
등 대신 imparative 코드 반복account.balance += depositAmount
선언적 / 제 국적 프로그래밍 토론에서 거의 나타나지 않는 또 다른 예제 인 사용자 인터페이스를 추가하겠습니다.
C #에서는 다양한 기술을 사용하여 UI를 작성할 수 있습니다.
필수적인 끝에서 DirectX 또는 OpenGL을 사용하여 버튼, 체크 박스 등을 한 줄씩 (또는 실제로는 삼각형 별) 매우 필수적으로 그릴 수 있습니다. 사용자 인터페이스를 그리는 방법은 사용자에게 달려 있습니다.
선언 끝에 WPF가 있습니다. 기본적으로 XML을 작성하고 (예, "XAML"기술적으로) 프레임 워크가 적합합니다. 당신은 사용자 인터페이스가 어떻게 생겼는지 말합니다. 방법을 알아내는 것은 시스템에 달려 있습니다.
어쨌든, 또 다른 생각입니다. 한 언어가 선언적이거나 명령 적이라고해서 다른 언어의 특정 기능이 없다는 의미는 아닙니다.
또한 선언적 프로그래밍의 이점 중 하나는 코드를 읽는 것에서 목적을보다 쉽게 이해할 수있는 반면 명령형은 실행을보다 세밀하게 제어 할 수 있다는 것입니다.
그것의 요지 :
선언적-> what
원하는 작업
명령형-> how
원하는 작업
나는 캠브리지 코스 + 그들의 예에서 설명을 좋아했다 :
int x;
-무엇 (선언적)x=x+1;
- 어떻게CSS
입니다 명령형은 다음?
차이점은 주로 전체 추상화 수준과 관련이 있습니다. 선언적으로, 어느 시점에서 프로그램은 결과를 얻는 방법에 대해 프로그램이 많은 위도를 가지도록 개별 단계에서 멀리 떨어져 있습니다.
연속체에서 어딘가에 떨어지는 것으로 모든 지시 사항을 볼 수 있습니다.
추상화 정도 :
Declarative <<=====|==================>> Imperative
선언적인 실제 예 :
명령형 실제 예 :
명령형 프로그래밍에서는 개발자가 코드 실행 방법을 단계별로 정의해야합니다. “1st Street로 이동하여 Main으로 좌회전하고 2 블럭을 운전 한 후 Maple로 우회전 한 다음 왼쪽의 세 번째 집에서 멈춰야합니다.” 선언 버전은 다음과 같이 들릴 수 있습니다. 하나는 무언가를하는 방법을 말한다; 다른 하나는해야 할 일을 말합니다.
선언적 스타일은 명령형 스타일에 비해 두 가지 장점이 있습니다.
- 여행자가 긴 지시 사항을 외우도록 강요하지는 않습니다.
- 가능한 경우 여행자가 경로를 최적화 할 수 있습니다.
Calvert, C Kulkarni, D (2009). 필수 LINQ. 애디슨 웨슬리 48.
명령형 프로그래밍은 컴퓨터에 명시 적으로 수행 할 작업과 수행 방법 (예 : 순서 지정 등)을 알려줍니다.
씨#:
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine("Hello World!");
}
선언은 컴퓨터에 무엇을해야하는지 알려주지 만 실제로는 수행 방법이 아닙니다. Datalog / Prolog는 이와 관련하여 가장 먼저 떠오르는 언어입니다. 기본적으로 모든 것이 선언적입니다. 주문을 보장 할 수는 없습니다.
C #은 훨씬 더 필수적인 프로그래밍 언어이지만 Linq와 같이 특정 C # 기능은 더 선언적입니다.
dynamic foo = from c in someCollection
let x = someValue * 2
where c.SomeProperty < x
select new {c.SomeProperty, c.OtherProperty};
같은 것을 필사적으로 쓸 수 있습니다.
dynamic foo = SomeCollection.Where
(
c => c.SomeProperty < (SomeValue * 2)
)
.Select
(
c => new {c.SomeProperty, c.OtherProperty}
)
(wikipedia Linq의 예)
컴퓨터 과학에서 선언적 프로그래밍은 제어 흐름을 설명하지 않고 계산의 논리를 표현하는 프로그래밍 패러다임입니다.
에서 http://en.wikipedia.org/wiki/Declarative_programming
간단히 말해, 제어 흐름 (루프, if 문 등)의 복잡성이 없기 때문에 선언적 언어가 더 간단합니다.
ASP.Net 'code-behind'모델이 좋은 비교입니다. 선언적인 '.ASPX'파일과 필수 'ASPX.CS'코드 파일이 있습니다. 필자는 대본의 선언적 절반에서 필요한 모든 작업을 수행 할 수 있으면 더 많은 사람들이 수행중인 작업을 따를 수 있다는 사실을 종종 알게됩니다.
필립 로버츠의 도둑질 :
두 가지 예 :
1. 배열의 모든 숫자를 두배로 늘리기
필수적으로 :
var numbers = [1,2,3,4,5]
var doubled = []
for(var i = 0; i < numbers.length; i++) {
var newNumber = numbers[i] * 2
doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]
선언적으로 :
var numbers = [1,2,3,4,5]
var doubled = numbers.map(function(n) {
return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]
2. 목록의 모든 항목 합산
필수적으로
var numbers = [1,2,3,4,5]
var total = 0
for(var i = 0; i < numbers.length; i++) {
total += numbers[i]
}
console.log(total) //=> 15
선언적으로
var numbers = [1,2,3,4,5]
var total = numbers.reduce(function(sum, n) {
return sum + n
});
console.log(total) //=> 15
명령형 예제는 어떻게 새로운 변수를 생성하고, 변경하고, 새로운 값을 반환하는 것 (즉, 무언가를 발생시키는 방법)을 포함하는 반면, 선언적 예제는 주어진 입력에서 실행되고 초기 입력을 기반으로 새로운 값을 반환합니다 (예 : , 우리가 원하는 것).
명령형 프로그래밍
C / C ++, Java, COBOL, FORTRAN, Perl 및 JavaScript와 같은 프로그래밍 규칙이 필요한 프로그래밍 언어입니다. 이러한 언어로 작성하는 프로그래머는 데이터 처리 및 프로그래밍에 대한 지식을 바탕으로 문제를 해결하기 위해 적절한 조치 순서를 개발해야합니다.
선언적 프로그래밍
전통적인 프로그래밍 논리를 작성할 필요가없는 컴퓨터 언어. 사용자는 C ++ 또는 Java와 같은 절차 적 프로그래밍 언어에서 필요한 프로그램 단계보다는 입력 및 출력 정의에 집중합니다.
선언적 프로그래밍 예제는 CSS, HTML, XML, XSLT, RegX입니다.
선언적 프로그램은 "보편적 인"명령형 구현 / vm에 대한 데이터 일뿐입니다.
장점 : 일부 하드 코딩 (및 검사) 형식으로 데이터 만 지정하는 것이 일부 명령 알고리즘의 변형을 직접 지정하는 것보다 간단하고 오류가 덜 발생합니다. 일부 복잡한 사양은 DSL 형식으로 만 직접 작성할 수 없습니다. DSL 데이터 구조에 사용되는 최고 및 주파수는 세트와 테이블입니다. 요소 / 행 사이에 종속성이 없기 때문입니다. 그리고 당신이 의존성을 가지지 않으면 자유롭게 수정하고 지원할 수 있습니다. (예를 들어 클래스가있는 모듈-행복한 모듈과 취약한 기본 클래스 문제가있는 클래스와 비교) 선언 및 DSL의 모든 제품은 해당 데이터 구조 (테이블 및 세트)의 이점을 즉시 따릅니다. 또 다른 장점-DSL이 다소 추상적 인 경우 (잘 설계된) 선언적 언어 vm의 구현을 변경할 수 있습니다. 예를 들어 병렬 구현을하십시오.
마이너스 : 당신은 옳은 것 같아요. 일반 (및 DSL로 매개 변수화 된) 명령 알고리즘 / vm 구현은 특정 것보다 느리고 메모리가 부족할 수 있습니다. 일부 경우에. 그 경우가 드물다면 잊어 버리십시오. 빈번한 경우-항상 해당 경우에 DSL / vm을 확장 할 수 있습니다. 다른 모든 경우의 속도를 늦출 수 있습니다.
PS 프레임 워크는 DSL과 명령의 중간 단계입니다. 그리고 모든 중도 솔루션으로서 ... 이점이 아닌 결함을 결합합니다. 그들은 그렇게 안전하지도 않고 빠르지도 않습니다 :) 모든 트레이드 잭 하스켈을 살펴보십시오. 강력하고 단순한 ML과 유연한 메타 프롤로그 프롤로그 사이에 있습니다. 부울 전용 함수 / 조건자를 사용하여 Prolog를 Haskell로 볼 수 있습니다. Haskell에 대한 유연성이 얼마나 간단한 지 ...
왜 아무도 C #에서 선언적 프로그래밍 도구로 Attribute 클래스를 언급하지 않았는지 궁금합니다. 이 페이지의 일반적인 답변은 선언적 프로그래밍 도구로서 LINQ에 대해 이야기 한 것입니다.
Wikipedia에 따르면
일반적인 선언 언어에는 데이터베이스 쿼리 언어 (예 : SQL, XQuery), 정규식, 논리 프로그래밍, 기능 프로그래밍 및 구성 관리 시스템의 언어가 포함됩니다.
따라서 함수 구문 인 LINQ는 선언적인 방법이지만 구성 도구 인 C #의 Attribute 클래스도 선언적입니다. C # 속성 프로그래밍에 대한 간단한 개요
모바일 앱 개발 측면에서 또 다른 예를 추가하십시오. iOS 및 Android에는 앱의 UI를 정의 할 수있는 인터페이스 빌더가 있습니다.
이 빌더를 사용하여 그려진 UI는 본질적으로 선언적이며 컴포넌트를 끌어서 놓습니다. 실제 드로잉은 프레임 워크와 시스템에서 수행되고 수행됩니다.
그러나 전체 구성 요소를 코드로 그릴 수도 있으며 이는 본질적으로 필수적입니다.
또한 Angular JS와 같은 일부 새로운 언어는 UI를 선언적으로 디자인하는 데 중점을두고 있으며 동일한 지원을 제공하는 다른 언어도 많이 볼 수 있습니다. Java와 마찬가지로 Java Swing 또는 Java FX에서 기본 데스크탑 앱을 그리는 좋은 선언적 방법이 없지만 가까운 시일 내에는 그럴 수도 있습니다.
내 이해에서, 두 용어는 철학에 뿌리를두고 있으며 선언적이고 명령적인 종류의 지식이 있습니다. 선언적 지식은 진리의 주장, 수학 공리와 같은 사실의 진술입니다. 그것은 당신에게 무언가를 알려줍니다. 명령 적 또는 절차 적 지식은 무언가에 도달하는 방법을 단계별로 알려줍니다. 이것이 바로 알고리즘의 정의입니다. 그렇다면 컴퓨터 프로그래밍 언어와 영어를 비교하십시오. 선언적 문장은 무언가를 나타냅니다. 지루한 예제이지만 Java에서 두 숫자가 서로 같은지 여부를 표시하는 선언적 방법이 있습니다.
public static void main(String[] args)
{
System.out.print("4 = 4.");
}
반면 영어로 된 명령형 문장은 명령을 내리거나 일종의 요청을합니다. 명령형 프로그래밍은 명령 목록 일뿐입니다 (이 작업을 수행하십시오). 다음은 Java에서 사용자 입력을받는 동안 두 숫자가 서로 같은지 여부를 표시하는 필수 방법입니다.
private static Scanner input;
public static void main(String[] args)
{
input = new Scanner(System.in);
System.out.println();
System.out.print("Enter an integer value for x: ");
int x = input.nextInt();
System.out.print("Enter an integer value for y: ");
int y = input.nextInt();
System.out.println();
System.out.printf("%d == %d? %s\n", x, y, x == y);
}
기본적으로 선언적 지식 은 특정 요소를 건너 뛰어 해당 요소에 대한 추상화 계층을 형성합니다. 선언적 프로그래밍도 마찬가지입니다.