가드 (컴퓨터 과학)
컴퓨터 프로그래밍에서 가드(guard)는 불린식으로, 실행이 해당 분기에서 계속되려면 참으로 평가되어야 한다. 어떤 프로그래밍 언어를 사용하든, 가드 절, 가드 코드 또는 가드 문은 실행 중 오류를 피하기 위해 사용되는 무결성 선행 조건 검사이다.
가드 절이라는 용어는 종종 이름 없는 코딩 관행을 명명된 소프트웨어 디자인 패턴으로 체계화한 켄트 벡에게 귀속되는 소프트웨어 디자인 패턴이다. 이 기술을 사용하는 관행은 적어도 1960년대 초반으로 거슬러 올라간다. 가드 절은 일반적으로 프로시저의 시작 부분에 추가되며, 예외적인 경우를 미리 처리하여 나머지 프로시저를 "보호"한다고 말한다.
용례
[편집]전형적인 예는 처리하려는 참조가 널(null)이 아닌지 확인하여 널 포인터 실패를 피하는 것이다.
다른 용도로는 멱등법칙을 위한 불린 필드를 사용하는 것(따라서 후속 호출은 NOP임)이 있다. 예를 들어 폐기 패턴에서와 같다.
public String foo(String username) {
if (username == null) {
throw new IllegalArgumentException("Username is null.");
}
// Rest of the method code follows here...
}
중첩이 적은 더 평탄한 코드
[편집]가드는 서브루틴에서 조기 종료를 제공하며, 구조적 프로그래밍에서 흔히 사용되는 편차로, 한 단계의 중첩을 제거하고 더 평탄한 코드를 만든다.[1] `if guard { ... }`를 `if not guard: return; ...`로 대체한다.
가드 절을 사용하는 것은 코드 개선을 위한 리팩토링 기술이 될 수 있다. 일반적으로 중첩이 적을수록 코드가 단순해지고 인지적 부담이 줄어들기 때문에 좋다.
예를 들어, 파이썬에서:
# 이 함수는 가드 절이 없다
def f_noguard(x):
if isinstance(x, int):
#code
#code
#code
return x + 1
else:
return None
# 가드 절이 있는 동일한 함수. 대부분의 코드가 들여쓰기가 적어 읽고 이해하기 쉽다
def f_guard(x):
if not isinstance(x, int):
return None
#code
#code
#code
return x + 1
다른 예는 C로 작성되었다.
// 이 함수는 가드 절이 없다
int funcNoGuard(int x) {
if (x >= 0) {
//code
//code
//code
return x + 1;
} else {
return 0;
}
}
// 가드 절이 있는 동일한 함수
int funcGuard(int x) {
if (x < 0) {
return 0;
}
//code
//code
//code
return x + 1;
}
용어
[편집]이 용어는 APL, 하스켈, 클린, 얼랭, 오컴, 프로멜라, OCaml, 스위프트,[2] 버전 3.10부터의 파이썬, 그리고 스칼라 프로그래밍 언어에서 특정 의미로 사용된다. 매스매티카에서는 가드를 제약 조건이라고 부른다. 가드는 Guarded Command Language의 기본 개념으로, 정형 기법의 언어이다. 가드는 패턴 매칭을 강화하여 구조가 일치하더라도 패턴을 건너뛸 수 있는 가능성을 제공하는 데 사용될 수 있다. 조건문의 불린식도 일반적으로 가드의 이 정의에 부합하지만 조건이라고 불린다.
수학
[편집]다음 하스켈 예시에서 가드는 각 "|"와 "=" 쌍 사이에 나타난다.
f x
| x > 0 = 1
| otherwise = 0
이는 해당 수학적 표기법과 유사하다.
이 경우 가드는 "if" 및 "otherwise" 절에 있다.
여러 가드
[편집]여러 개의 병렬 가드가 있는 경우, 일반적으로 위에서 아래로 시도되며, 먼저 통과한 가드의 분기가 선택된다. 사례 목록의 가드는 일반적으로 병렬이다.
그러나 하스켈의 리스트 캄프리헨션에서는 가드가 직렬이며, 그 중 하나라도 실패하면 리스트 요소는 생성되지 않는다. 이는 별도의 가드들을 논리곱으로 결합하는 것과 동일하지만, 가드들 사이에 다른 리스트 캄프리헨션 절이 있을 수 있다는 점이 다르다.
진화
[편집]1963년 CPL에 이미 존재했던 간단한 조건식은 첫 번째 부분식에 가드를 가지고 있으며, 첫 번째 부분식을 사용할 수 없는 경우 사용할 다른 부분식을 가지고 있다. 이를 작성하는 몇 가지 일반적인 방법은 다음과 같다.
(x>0) -> 1/x; 0 x>0 ? 1/x : 0
두 번째 부분식이 더 간단한 조건식일 수 있다면, 마지막으로 통과하기 전에 시도할 더 많은 대안을 제공할 수 있다.
(x>0) -> 1/x; (x<0) -> -1/x; 0
1966년 ISWIM은 의무적인 폴스루(fall-through) 경우가 없는 조건식 형태를 가졌으며, 따라서 가드를 선택 개념과 분리했다. ISWIM의 경우, 대안 중 어느 것도 사용할 수 없으면 값은 미정의로 간주되었고, 이는 값으로 계산되지 않는 것으로 정의되었다.
SASL (1976)의 "소형화된 버전"[3]인 KRC는 "가드"라는 용어를 사용한 최초의 프로그래밍 언어 중 하나였다. 이 언어의 함수 정의는 여러 절을 가질 수 있었고, 적용할 절은 각 절 뒤에 오는 가드를 기반으로 선택되었다.
fac n = 1, n = 0
= n * fac (n-1), n > 0
가드 절의 사용과 "가드 절"이라는 용어는 켄트 벡이 체계화한 1990년대 스몰토크 관행으로 거슬러 올라간다.[1]
1996년, Dyalog APL은 가드가 유일한 제어 구조인 대안적인 순수 함수형 스타일을 채택했다.[4] 다음 APL 예제는 입력 숫자의 패리티를 계산한다.
parity←{
2∣⍵ : 'odd'
'even'
}
패턴 가드
[편집]패턴에 부착된 가드 외에도, 패턴 가드는 가드의 맥락에서 패턴 매칭을 사용하는 것을 지칭할 수 있다. 효과적으로, 패턴의 일치는 통과를 의미하는 것으로 간주된다. 이 의미는 사이먼 페이튼 존스가 1997년 4월에 A new view of guards라는 제목으로 하스켈에 대한 제안에서 도입되었고, 그 제안의 구현에 사용되었다. 이 기능은 패턴의 가드에 패턴을 사용할 수 있는 기능을 제공한다.
확장 하스켈의 예:
clunky env var1 var2
| Just val1 <- lookup env var1
, Just val2 <- lookup env var2
= val1 + val2
-- ...other equations for clunky...
이는 다음과 같이 읽힌다: "환경과 두 변수에 대한 클렁키는, 환경에서 변수 조회가 값을 생성하는 경우, 값들의 합이다. ..." 리스트 캄프리헨션에서처럼 가드는 직렬이며, 그 중 하나라도 실패하면 분기는 취해지지 않는다.
같이 보기
[편집]- 어설션
- 가드 명령어 언어, 비결정적 조건문을 기반으로 하는 프로그래밍 언어
- 가드 서스펜션
- 아이버슨 괄호
- 논리적 조건
- 센티넬 노드, 데이터 구조의 끝을 나타내는 객체
- Switch 문
각주
[편집]- ↑ 가 나 Beck, Kent (1997). 〈Guard Clause〉. 《Smalltalk Best Practice Patterns,》. 178–179쪽.
- ↑ Cook, Nate. “guard & defer”. 《NSHipster》. 2016년 2월 26일에 확인함.
- ↑ Turner, D. A. “Some History of Functional Programming Languages” (PDF).
- ↑ Scholes, John. “Direct Functions in Dyalog APL” (PDF).
외부 링크
[편집]- Guard - Free On-Line Dictionary of Computing - FOLDOC, 데니스 하우 (편집자).
- Guard Clause, 위키위키웹
- The Haskell 98 Report, 챕터 3 표현식.
- The Mathematica Book, 섹션 2.3.5 패턴에 제약 조건 넣기
- The Glorious Glasgow Haskell Compilation System User's Guide, 버전 6.4, 섹션 7.3.2. 패턴 가드