ML (프로그래밍 언어)
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
ML은 1970년대 초 로빈 밀너 등에 의해 개발된 프로그래밍 언어이다. LCF 정리 증명기의 메타 언어로 설계되었으며, 강력한 타입 시스템을 갖춘 언어로 발전했다. 값 호출 평가 전략, 일급 함수, 가비지 컬렉션, 정적 타이핑, 형식 추론, 대수적 데이터 형식, 패턴 매칭, 예외 처리 등 다양한 기능을 제공하며, 부작용을 허용하는 불순 함수형 언어이다. ML은 언어 설계 및 조작, 생물 정보학, 금융 시스템 등 다양한 분야에서 활용된다. 주요 방언으로는 Standard ML, OCaml, F# 등이 있다.
더 읽어볼만한 페이지
- ML 프로그래밍 언어 계열 - OCaml
OCaml은 ML 계열의 함수형 프로그래밍 언어로서 클래스 기반 객체 지향 프로그래밍 기능을 지원하며, 강력한 타입 시스템, 타입 추론, 꼬리 재귀 최적화 등의 특징을 가진다. - ML 프로그래밍 언어 계열 - F 샤프
F#은 .NET 플랫폼에서 실행되는 크로스 플랫폼, 오픈 소스 프로그래밍 언어로서 함수형, 명령형, 객체 지향 프로그래밍을 지원하며 데이터 분석, 웹 개발, 앱 개발 등 다양한 분야에서 활용된다. - 패턴 매칭 프로그래밍 언어 - AWK
AWK는 1977년에 개발된 텍스트 처리 및 프로그래밍 언어로, 유닉스 환경에서 텍스트 처리를 위해 설계되었으며 정규 표현식 처리 기능을 통해 텍스트 분석, 데이터 추출, 보고서 생성 등 다양한 작업을 수행한다. - 패턴 매칭 프로그래밍 언어 - 하스켈
하스켈은 해스켈 커리의 이름을 딴 순수 함수형 프로그래밍 언어로, 여러 함수형 언어 통합 노력의 결과로 탄생하여 느긋한 계산법, 패턴 매칭, 타입 클래스, 모나드 등의 특징을 가지며 GHC가 표준 구현체로 사용된다.
| ML (프로그래밍 언어) - [IT 관련 정보]에 관한 문서 | |
|---|---|
| 기본 정보 | |
![]() | |
| 종류 | 다중 패러다임 프로그래밍 언어 |
| 개발 | 로빈 밀너, 에든버러 대학교 |
| 발표 | 1973년 |
| 타이핑 | 형 추론, 정적 타이핑, 강한 타이핑 |
| 방언 | OCaml, Standard ML, F# |
| 영향을 준 언어 | ISWIM |
| 영향을 받은 언어 | Clojure Coq Cyclone C++ Elm F# F* Haskell Idris Kotlin Miranda Nemerle OCaml Opa Erlang Rust Scala Standard ML |
2. 역사
ML은 1970년대 초 에든버러 대학교에서 로빈 밀너 등에 의해 개발되었으며,[4] 그 구문은 ISWIM에서 영감을 받았다. ML은 LCF 정리 증명기의 증명 전술을 개발하기 위해 고안되었다.
2. 1. 개발 배경
1970년대 초, 데이비드 스코트가 제안한 PPLAMBDA라는 논리 체계를 이용하여, 로빈 밀너는 Logic for Computable Functions영어(LCF)라는 증명 검사 및 자동 정리 증명 시스템을 구현했다. 1973년에 시작된 에든버러 LCF 프로젝트에서, 증명 과정을 함수로 기술하기 위한 메타 언어로서 개발된 것이 ML의 시초이며, 강력한 형식 시스템을 갖춘 언어로 설계되었다.[4]2. 2. 발전 과정
ML은 1970년대 초 에든버러 대학교에서 로빈 밀너 등에 의해 개발되었으며,[4] 그 구문은 ISWIM에서 영감을 받았다. 역사적으로 ML은 LCF 정리 증명기의 증명 전술을 개발하기 위해 고안되었다. 1975~76년에 에든버러 대학교에서 에든버러 LCF와 ML이 구현되었다. 1980년대 이후, 범용 프로그래밍 언어로서 다수의 기능과 라이브러리가 추가되었다.오늘날 ML 계열에는 Standard ML (SML), OCaml 및 F# 등 여러 언어가 있다. ML의 아이디어는 Haskell, Cyclone, Nemerle,[5] ATS, Elm과 같은 다른 많은 언어에 영향을 미쳤다.[6]
3. 언어 사양
ML은 값 호출 평가 전략, 일급 함수, 가비지 컬렉션을 통한 자동 메모리 관리, 매개변수 다형성, 정적 타이핑, 형식 추론, 대수적 데이터 형식, 패턴 매칭, 예외 처리 기능을 제공한다.[2] 정적 스코핑 규칙을 사용한다.[2]
ML은 부작용을 허용하기 때문에 순수 함수형 프로그래밍 언어인 Haskell과 달리 '불순' 함수형 언어라고 할 수 있다.[3] 대부분의 프로그래밍 언어와 마찬가지로 ML은 조급한 계산을 사용하지만, 클로저를 사용하여 느긋한 계산을 달성할 수 있다.
ML은 자동 정리 증명 시스템에서 증명 과정을 함수로 기술하기 위한 메타 언어로서 탄생했다.[4] 구문은 ISWIM의 영향을 받았다. 형 추론은 ML을 통해 프로그래머에게 널리 알려진 기능으로, 명시적으로 형을 선언하지 않아도 데이터 사용 방식으로부터 인자나 함수의 반환형을 자동으로 추론해 준다.
표준(혹은 방언)으로 Standard ML (SML)이 있으며, 그 구현에는 Standard ML of New Jersey영어 (SML/NJ) 등이 있다. 표준 이외의 사양[8] 구현으로는 OCaml 등이 있다. 각 구현의 상세 사양은 서로 다르며, 각 구현에서의 사양을 각각의 ML 방언으로 간주하기도 한다.
3. 1. 연산자
- +, -, *: 덧셈, 뺄셈, 곱셈
- /: 실수 나눗셈, div: 정수 나눗셈, mod: 나머지
- :: : 리스트에 요소 추가, @: 리스트의 결합
- ^: 문자열 연결, if~then~else: if문 (3항 연산자 취급)
3. 2. 함수 정의
ML에서 함수는 `fun` 키워드를 사용하여 정의한다. 함수의 이름, 매개변수, 그리고 함수의 본체를 지정하는 방식으로 정의된다.예를 들어, 팩토리얼을 계산하는 함수는 다음과 같이 정의할 수 있다.
```sml
fun fac 0 = 1
| fac n = n * fac (n - 1)
```
이 코드는 `fac`이라는 이름의 함수를 정의한다. 이 함수는 0을 인자로 받으면 1을 반환하고, 다른 정수 `n`을 인자로 받으면 `n * fac (n - 1)`을 반환한다. 여기서 `|` 기호는 패턴 매칭을 사용하여 함수의 동작을 여러 경우로 나누어 정의하는 데 사용된다.
ML은 함수의 자료형을 자동으로 추론하지만, 다음과 같이 명시적으로 자료형을 지정할 수도 있다.
```sml
fun fac (0 : int) : int = 1
| fac (n : int) : int = n * fac (n - 1)
```
함수의 인자는 괄호로 둘러싸지 않고 공백으로 구분한다.
ML에서는 함수 정의 순서가 중요하다. 함수가 정의될 때 평가가 이루어지기 때문이다.
상호 재귀 호출을 구현하려면 `and` 키워드를 사용하여 함수들을 함께 정의해야 한다. 예를 들어, 리스트에서 홀수 번째 요소와 짝수 번째 요소를 번갈아 반환하는 `take`와 `skip` 함수는 다음과 같이 정의할 수 있다.
```ml
fun take(nil) = nil
| take(x::xs) = x::skip(xs)
and skip(nil) = nil
| skip(x::xs) = take(xs);
3. 3. 예제
함수형 프로그래밍에서 Hello world와 같은 예로 팩토리얼 계산 코드가 있다. 순수 ML로 작성된 팩토리얼 코드는 다음과 같다.```sml
fun fac 0 = 1
| fac n = n * fac (n-1);
```
이 코드는 팩토리얼을 기본적인 경우(base case)가 하나 있는 재귀 함수로 정의하며, 수학 교과서의 팩토리얼 정의와 유사하다. ML 코드는 문법과 계산 방식 면에서 수학적 언어와 닮아있다.
위 코드에서 자료형 명시는 생략 가능하다. 자료형을 제거하면 코드는 다음과 같이 더 간결해진다.
```sml
fun fac 0 = 1
| fac n = n * fac(n-1);
```
함수 인자가 괄호로 둘러싸여 있지 않고 공백으로 구분됨을 알 수 있다. 두 번째 줄은 ML의 패턴 매칭을 보여준다. 함수 fac은 인자가 0이면 1을 반환하고, 나머지 경우에는 두 번째 줄을 실행하여 0이 될 때까지 fac을 재귀적으로 호출한다.[7]
ML의 함수 정의는 `fun (함수명)(인수) = (내용);`으로 표기하며, 하스켈과 유사한 패턴 매칭이 있다. 복수의 패턴은 가드 표기 `|`를 구분자로 한다.
ML에서 함수 평가는 함수가 정의될 때 이루어지므로, 함수 정의 순서를 무시할 수 없다. 예를 들어:
```ml
fun a(x) = b(x-1) + x;
fun b(x) = x * x;
```
위와 같은 코드는 `b`가 `a`보다 먼저 정의되어야 한다. 그러나 이 경우 재귀 호출 구현이 불가능하므로, ML에서는 `and`로 두 함수를 연결하여 이를 해결한다.
```ml
fun take(nil) = nil
| take(x::xs) = x::skip(xs)
and skip(nil) = nil
| skip(x::xs) = take(xs);
```
위 코드는 `take`가 리스트의 홀수 번째 요소를, `skip`이 짝수 번째 요소를 반환하도록 한다.
3. 3. 1. 팩토리얼
함수형 프로그래밍의 Hello world라고 할 만한 것은 팩토리얼을 계산하는 코드이다. ML로는 다음과 같이 표현할 수 있다.```sml
fun fac (0 : int) : int = 1
| fac (n : int) : int = n * fac (n - 1)
```
이 코드는 팩토리얼을 재귀 함수로 설명하며, 단일 종료 기본 사례를 갖는다. 이것은 수학 교과서에서 찾을 수 있는 팩토리얼의 설명과 유사하다.
위 코드에서 자료형을 명시하는 부분을 제거하고 다시 작성하면 다음과 같다.
```sml
fun fac 0 = 1
| fac n = n * fac (n - 1)
```
이 함수는 ML 프로그래밍의 중요한 부분인 패턴 매칭에 의존한다. 함수 fac은 인자가 0이면 1을 반환한다. 다른 모든 경우에는 두 번째 줄을 실행하여 0에 도달할 때까지 fac을 재귀적으로 계속 호출한다.[7]
ML의 함수 정의는 `fun (함수명)(인수) = (내용);`으로 표기한다. 하스켈과 유사한 패턴 매칭이 있다. 복수의 패턴은 가드 표기 `|`를 구분자로 한다.
예시로 계승 함수를 구하는 프로그램을 아래에 나타낸다.
```ml
fun factorial(1) = 1
| factorial(n) = n * factorial(n-1);
3. 3. 2. 리스트 반전
다음 함수는 리스트의 요소를 ''반전''시킨다. 더 정확히 말하면, 주어진 리스트와 비교하여 요소가 반대 순서로 정렬된 새 리스트를 반환한다.```sml
fun reverse [] = []
| reverse (x :: xs) = (reverse xs) @ [x]
```
이 `reverse`의 구현은 정확하고 명확하지만, 실행에 2차 시간이 소요되어 비효율적이다. 이 함수는 선형 시간 내에 실행되도록 다시 작성할 수 있다.
```sml
fun 'a reverse xs : 'a list = List.foldl (op ::) [] xs
```
이 함수는 매개변수 다형성의 한 예이다. 즉, 요소가 어떤 유형이든 관계없이 리스트를 소비하고 동일한 유형의 리스트를 반환할 수 있다.
ML의 함수 정의는 `fun (함수명)(인수) = (내용);`으로 표기한다. 하스켈과 유사한 패턴 매칭이 있다. 복수의 패턴은 가드 표기 `|`를 구분자로 한다.
ML에서의 함수의 평가는 함수가 정의될 때 이루어진다. 이 때문에 ML에서는 함수 정의의 순서를 무시할 수 없다.
3. 3. 3. 모듈
ML은 대규모 프로젝트와 라이브러리를 구성하기 위한 모듈 시스템을 갖추고 있다. 모듈은 시그니처 파일과 하나 이상의 구조 파일로 구성된다. 시그니처 파일은 구현될 API를 지정하는데, 이는 C 헤더 파일이나 자바 인터페이스 파일과 유사하다. 구조는 시그니처를 구현하며, C 소스 파일이나 자바 클래스 파일과 비슷하다. 예를 들어, 다음은 산술 시그니처와 유리수를 사용하여 이를 구현한 것이다.```sml
signature ARITH =
sig
type t
val zero : t
val succ : t -> t
val sum : t * t -> t
end
```
```sml
structure Rational : ARITH =
struct
datatype t = Rat of int * int
val zero = Rat (0, 1)
fun succ (Rat (a, b)) = Rat (a + b, b)
fun sum (Rat (a, b), Rat (c, d)) = Rat (a * d + c * b , b * d)
end
```
`use` 명령을 통해 인터프리터로 가져올 수 있다. 구현과의 상호 작용은 시그니처 함수를 통해서만 가능하다. 예를 들어, 이 코드를 통해서는 'Rat' 데이터 객체를 직접 생성할 수 없다. 'structure' 블록은 외부로부터 모든 구현 세부 정보를 숨긴다.
ML의 표준 라이브러리는 이러한 방식으로 모듈로 구현되어 있다.
4. 주요 방언
ML 계열에는 Standard ML(SML), OCaml, F# 등 여러 언어가 있다. 이 중 가장 두드러진 세 가지는 Standard ML, OCaml, F#이다.[4] 각 방언은 고유한 특징과 구현을 가지고 있으며, 상세 사양은 구현마다 다르다. 표준 이외의 사양[8]을 가진 구현으로는 OCaml 등이 있으며, 각 구현에서의 사양을 각각의 ML 방언으로 간주하기도 한다.
4. 1. Standard ML (SML)
ML의 표준 방언으로 Standard ML(SML)이 있으며, 그 구현에는 Standard ML of New Jersey영어(SML/NJ)나 도호쿠 대학 전기 통신 연구소 오호리 연구실에서 개발을 진행하고 있는 SML#[7] 등이 있다. 표준 이외의 사양[8]의 구현으로는 OCaml 등이 있다. 상세 사양은 구현마다 다르며, 각 구현에서의 사양을 각각의 ML 방언으로 간주하는 경우도 있다.SML의 상세 내용과 그 구현 목록은 Standard ML을 참조할 것.
참조
[1]
논문
A theory of type polymorphism in programming
1978
[2]
서적
Commentary on Standard ML
The MIT Press
1991
[3]
서적
Concepts of Programming Languages
Addison-Westley
1999
[4]
웹사이트
From LCF to HOL: a short history
http://www.cl.cam.ac[...]
2007-10-11
[5]
간행물
Programming language for "special forces" of developers
http://nemerle.org/A[...]
Nemerle Project Team
2021-01-24
[6]
서적
Seven More Languages in Seven Weeks
The Pragmatic Programmers, LLC
2014
[7]
웹사이트
SML#プロジェクト
http://www.pllab.rie[...]
[8]
문서
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com
