OCaml
Objective Caml
함수형, 명령형, 객체지향을 지원하는 ML 계열 언어
Objective Caml
함수형, 명령형, 객체지향을 지원하는 ML 계열 언어
OCaml(Objective Caml)은 ML(Meta Language) 계열의 범용 프로그래밍 언어로, 함수형, 명령형, 객체지향 패러다임을 모두 지원하는 다중 패러다임 언어입니다. 강력한 정적 타입 시스템과 자동 메모리 관리를 제공하면서도 네이티브 코드 컴파일을 통해 C/C++에 준하는 성능을 달성합니다.
OCaml은 프랑스 국립 정보학 자동화 연구소(INRIA)에서 개발되었습니다. 1996년 Xavier Leroy가 이끄는 팀이 Caml Light에 객체지향 기능을 추가하여 OCaml을 발표했습니다. 그 뿌리는 1973년 Robin Milner가 개발한 ML까지 거슬러 올라가며, 50년 이상의 학술 연구를 기반으로 발전해왔습니다.
OCaml의 핵심 특징은 Hindley-Milner 타입 추론과 대수적 데이터 타입(ADT), 그리고 패턴 매칭입니다. 프로그래머가 타입을 명시하지 않아도 컴파일러가 자동으로 추론하며, 패턴 매칭을 통해 복잡한 데이터 구조를 간결하고 안전하게 처리할 수 있습니다. 컴파일 타임에 대부분의 버그를 잡아내어 "컴파일이 되면 동작한다"라는 말이 있을 정도입니다.
실무에서 OCaml은 금융권과 대형 기술 기업에서 활발히 사용됩니다. Jane Street는 전체 거래 인프라를 OCaml로 구축하여 하루 수조 원의 거래를 처리하고 있으며, Meta(Facebook)는 Hack 언어 컴파일러와 Flow 타입 검사기를 OCaml로 개발했습니다. 또한 Rust 컴파일러의 초기 버전, Docker의 컨테이너 기술(MirageOS), 그리고 형식 검증 도구 Coq도 OCaml로 작성되었습니다.
OCaml의 기본 문법과 패턴 매칭을 보여주는 예제입니다.
(* 기본 함수 정의 - 타입 추론 *)
let square x = x * x
let add x y = x + y
(* 재귀 함수 - rec 키워드 필요 *)
let rec factorial n =
if n <= 1 then 1
else n * factorial (n - 1)
(* 대수적 데이터 타입 정의 *)
type shape =
| Circle of float (* 반지름 *)
| Rectangle of float * float (* 너비 * 높이 *)
| Triangle of float * float (* 밑변 * 높이 *)
(* 패턴 매칭으로 면적 계산 *)
let area shape =
match shape with
| Circle r -> Float.pi *. r *. r
| Rectangle (w, h) -> w *. h
| Triangle (b, h) -> 0.5 *. b *. h
(* Option 타입으로 안전한 나눗셈 *)
let safe_divide x y =
if y = 0 then None
else Some (x / y)
(* 리스트 처리 - 패턴 매칭 활용 *)
let rec sum_list = function
| [] -> 0
| head :: tail -> head + sum_list tail
(* 고차 함수 사용 *)
let numbers = [1; 2; 3; 4; 5]
let doubled = List.map (fun x -> x * 2) numbers
let total = List.fold_left (+) 0 numbers
(* 파이프 연산자로 가독성 향상 *)
let result =
numbers
|> List.filter (fun x -> x mod 2 = 0)
|> List.map (fun x -> x * x)
|> List.fold_left (+) 0
(* 레코드 타입 *)
type person = {
name: string;
age: int;
email: string option;
}
let alice = { name = "Alice"; age = 30; email = Some "alice@example.com" }
(* 모듈 시스템 *)
module Stack = struct
type 'a t = 'a list
let empty = []
let push x stack = x :: stack
let pop = function
| [] -> None
| x :: rest -> Some (x, rest)
end