F# 자세한 구문
F# 자세한 구문 (Verbose Syntax)
F#에는 많은 구문 구성에 두 가지 형태가 있어요. 하나는 자세한 구문(verbose syntax)이고, 다른 하나는 간결한 구문(lightweight syntax)입니다. 자세한 구문은 그렇게 흔하게 쓰이지는 않지만, 들여쓰기에 덜 민감하다는 장점이 있어요. 반면에 간결한 구문은 더 짧고, begin, end, in 같은 추가 키워드 대신 들여쓰기로 구성의 시작과 끝을 알려줍니다. 기본 구문은 간결한 구문이에요. 이번 주제에서는 간결한 구문이 꺼져 있을 때의 F# 구성 구문을 설명해요. 자세한 구문은 항상 켜져 있기 때문에, 간결한 구문을 켜더라도 일부 구성에는 자세한 구문을 그대로 쓸 수 있습니다.
본문
구문 구성 표 (Table of Constructs)
아래 표는 두 형태 사이에 차이가 있는 F# 언어 구성의 간결한 구문과 자세한 구문을 보여줍니다. 표에서 꺾쇠 괄호(<>)는 사용자가 직접 채워 넣는 구문 요소를 감싸요. 각 구성 안에서 쓰이는 구문에 대한 더 자세한 내용은 각 언어 구성의 문서를 참고해 주세요.
| 언어 구성 | 간결한 구문 (Lightweight syntax) | 자세한 구문 (Verbose syntax) |
|---|---|---|
| 식(표현식) 결합 | <expression1><expression2> |
<expression1>; <expression2> |
| 중첩 let 바인딩 | let f x =let a = 1let b = 2x + a + b |
let f x =let a = 1 inlet b = 2 inx + a + b |
| 코드 블록 | (<expression1><expression2>) |
begin<expression1>;<expression2>;end |
| for...do | for counter = start to finish do... |
for counter = start to finish do...done |
| while...do | while <condition> do... |
while <condition> do...done |
| for...in | for var in start .. finish do... |
for var in start .. finish do...done |
| do | do... |
do...in |
| 레코드 | type <record-name> ={<field-declarations>}<value-or-member-definitions> |
type <record-name> ={<field-declarations>}with<value-or-member-definitions>end |
| 클래스 | type <class-name>(<params>) =... |
type <class-name>(<params>) =class...end |
| 구조체 | [<StructAttribute>]type <structure-name> =... |
type <structure-name> =struct...end |
| 판별 공용체 | type <union-name> =| ...| ......<value-or-member definitions> |
type <union-name> =| ...| ......with<value-or-member-definitions>end |
| 인터페이스 | type <interface-name> =... |
type <interface-name> =interface...end |
| 개체 식 | { new <type-name>with<value-or-member-definitions><interface-implementations>} |
{ new <type-name>with<value-or-member-definitions>end<interface-implementations>} |
| 인터페이스 구현 | interface <interface-name>with<value-or-member-definitions> |
interface <interface-name>with<value-or-member-definitions>end |
| 형식 확장 | type <type-name>with<value-or-member-definitions> |
type <type-name>with<value-or-member-definitions>end |
| 모듈 | module <module-name> =... |
module <module-name> =begin...end |
핵심만 정리해 볼게요
표를 쭉 보면 공통 패턴이 보여요. 자세한 구문이 들여쓰기 대신 키워드를 직접 쓴다는 것, 그것이 핵심이에요. 코드 블록은 begin과 end로 열고 닫고, for...do, while...do, for...in 같은 반복 루프는 끝에 done을 붙이고, 레코드·판별 공용체·형식 확장처럼 멤버 정의가 붙는 구성은 with와 end를 써요. 그리고 모듈은 begin/end로 감싸요.
여기서 재미있는 점은, 자세한 구문이 항상 켜져 있다는 거예요. 그러니까 간결한 구문을 기본으로 쓰다가, 특정 구성에서만 자세한 구문을 섞어 써도 문제가 없습니다. 들여쓰기가 꼬이기 쉬운 상황이라면 자세한 구문으로 명시적으로 블록을 열고 닫는 편이 오히려 안전하죠.