F 샤프

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

F#은 강력한 형식의 함수형 프로그래밍 언어로, 마이크로소프트에서 개발되었다. 다양한 버전으로 출시되었으며, 2005년에 처음 등장하여 .NET 프레임워크를 지원해왔다. F#은 함수형, 명령형, 객체 지향 프로그래밍을 지원하며, 람다 함수, 클로저, 패턴 매칭, 대수적 데이터 형식, 튜플, 리스트 컴프리헨션, 모나드 패턴 등 다양한 기능을 제공한다. 또한, 단위 측정, 메타프로그래밍, 에이전트 프로그래밍을 지원하며, 웹, 크로스 플랫폼 앱, 분석 프로그래밍, 스크립팅 등 다양한 분야에서 활용된다. F#은 OCaml과 호환되며, 오픈 소스 커뮤니티를 통해 지속적으로 발전하고 있다.

F 샤프 - [IT 관련 정보]에 관한 문서
기본 정보
이름F#
설계자돈 사이미, 마이크로소프트 리서치
개발자마이크로소프트, F# 소프트웨어 재단
출시일2005년, 버전 1.0
최신 버전9.0
최신 버전 출시일2024년 11월 12일
형식 체계정적, 강한, 추론
웹사이트F# 공식 웹사이트
F# 마이크로소프트 공식 웹사이트
위키책F# 프로그래밍
파일 확장자.fs, .fsi, .fsx, .fsscript
특징
프로그래밍 패러다임다중 패러다임: 함수형, 명령형, 객체 지향, 에이전트 지향, 메타 프로그래밍, 반사, 병행
영향 받은 언어C#, Erlang, 하스켈, ML, OCaml, Python, Scala
영향을 준 언어C#, Elm, F*, LiveScript
구현체
플랫폼크로스 플랫폼: .NET 프레임워크, Mono
라이선스
라이선스MIT
📚 더 읽어볼만한 페이지
  • 2002년 개발된 프로그래밍 언어 - 시스템베릴로그
    SystemVerilog는 Verilog를 확장한 하드웨어 기술 및 검증 언어로서, 객체 지향 프로그래밍, 제약 기반 난수 생성, 어설션 등의 고급 검증 기능을 제공하여 하드웨어 설계 및 검증의 효율성을 높인다.
  • 2002년 개발된 프로그래밍 언어 - 아이오 (프로그래밍 언어)
    아이오는 스티브 데코르테가 2002년에 개발한 순수 객체 지향 및 프로토타입 기반의 프로그래밍 언어로서, 코드-애즈-데이터, 호모이코닉 특징과 액터 모델 기반의 동시성, 코루틴, 메타 프로그래밍 등의 고급 기능을 제공한다.
  • ML 프로그래밍 언어 계열 - OCaml
    OCaml은 ML 계열의 함수형 프로그래밍 언어로서 클래스 기반 객체 지향 프로그래밍 기능을 지원하며, 강력한 타입 시스템, 타입 추론, 꼬리 재귀 최적화 등의 특징을 가진다.
  • ML 프로그래밍 언어 계열 - ML (프로그래밍 언어)
    ML은 1970년대 초에 개발된 프로그래밍 언어로, 강력한 타입 시스템, 일급 함수, 가비지 컬렉션, 정적 타이핑 등의 기능을 제공하며 다양한 분야에서 활용된다.
  • 마이크로소프트 리서치 - 마이크로소프트 코그니티브 툴킷
  • 마이크로소프트 리서치 -

2. 역사

마이크로소프트 리서치(Microsoft Research)의 Don Syme영어 등이 2002년부터 OCaml을 기반으로 F# 개발을 시작했다. F#의 F는 함수형 프로그래밍 언어(Functional programming language) 및 System F에서 유래했다. 앤드류 케네디(Andrew Kennedy)는 단위 측정 설계에 기여했다.

F#은 OCaml에서 많은 요소를 물려받은 함수형 및 객체 지향의 멀티 패러다임이다. 형 안전하며 형 추론 기능을 가진다. 하지만 오버로딩을 지원하기 때문에 OCaml이 가진 형 추론의 완전성을 잃었다. C# 및 Visual Basic .NET 등 .NET 언어와 상호 운용성이 있으며, .NET 클래스 라이브러리의 이용 및 개발이 가능하다. Mono 및 Xamarin을 이용한 Android 애플리케이션 개발도 지원된다. 이전에는 실버라이트를 이용한 Windows Phone 7 애플리케이션 개발도 지원되었다.

F#의 개발 환경은 Visual Studio의 유료 버전 제품 (또는 무료 Community 에디션)에 Visual F#으로 포함되어 있으며, Express 에디션에서 사용할 수 있는 무료 도구 배포도 이루어지고 있다. Visual F# Tools 4.1에서 Roslyn (compiler)영어를 지원하게 되었다. 또한, Mono 및 .NET Core 환경용으로 F# 컴파일러가 이식되었기 때문에, macOS나 리눅스 등에서도 F# 프로그램의 개발 및 실행이 가능하다.

OCaml 호환 표준 라이브러리를 갖추고 있으며, F#과 OCaml 모두에서 컴파일할 수 있는 코드를 작성하는 것도 가능하다. 그러나 클래스 구문 등은 F#과 OCaml에서 다르다.

2.1. 버전

👆
좌우로 밀어서 보기
F#
버전
언어 명세날짜플랫폼런타임
1.x2005년 5월Windows.NET 1.0 - 3.5
2.0[http://fsharp.org/specs/language-spec/index.html#f-20 2010년 8월]2010년 4월리눅스, macOS, Windows.NET 2.0 - 4.0, Mono
3.0[http://fsharp.org/specs/language-spec/index.html#f-30 2012년 11월]2012년 8월리눅스, macOS, Windows;
자바스크립트, GPU
.NET 2.0 - 4.5, Mono
3.1[http://fsharp.org/specs/language-spec/index.html#f-31 2013년 11월]2013년 10월리눅스, macOS, Windows;
자바스크립트, GPU
.NET 2.0 - 4.5, Mono
4.0[http://fsharp.org/specs/language-spec/index.html#f-40 2016년 1월]2015년 7월
4.1[http://fsharp.org/specs/language-spec/index.html#f-41 2018년 5월]2017년 3월리눅스, macOS, Windows,
자바스크립트, GPU
.NET 3.5 - 4.6.2, .NET, Mono
4.52018년 8월리눅스, macOS, Windows,
자바스크립트, GPU
.NET 4.5 - 4.7.2, .NET Core SDK 2.1.400
4.62019년 3월리눅스, macOS, Windows,
자바스크립트, GPU
.NET 4.5 - 4.7.2, .NET Core SDK 2.2.300
4.72019년 9월리눅스, macOS, Windows,
자바스크립트, GPU
.NET 4.5 - 4.8, .NET Core SDK 3.0.100
5.02020년 11월리눅스, macOS, Windows,
자바스크립트, GPU
.NET SDK 5.0.100
6.02021년 11월리눅스, macOS, Windows,
자바스크립트, GPU
.NET SDK 6.0.100
7.02022년 11월리눅스, macOS, Windows,
자바스크립트, GPU
.NET SDK 7.0.100
8.02023년 11월리눅스, macOS, Windows,
자바스크립트, GPU
.NET SDK 8.0.100

2.2. 언어 발전

F#는 개방형 개발 및 엔지니어링 프로세스를 사용한다. 언어 진화 과정은 F# 소프트웨어 재단과 함께 언어 설계를 위한 생각하는 독재자(BDFL)인 돈 심(Don Syme)이 마이크로소프트 리서치(Microsoft Research)에서 관리한다. 과거 F# 언어 버전은 마이크로소프트(Microsoft)와 마이크로소프트 리서치(Microsoft Research)에서 폐쇄형 개발 프로세스를 사용하여 설계했다.

F#는 2010 에디션에 Visual Basic (.NET) 및 C#과 동일한 수준(옵션)으로 처음 포함되었으며, 이후 모든 에디션에 남아 있어 언어의 광범위한 사용과 지원이 이루어지고 있다.

F#는 영국 케임브리지에 있는 마이크로소프트 리서치에서 시작되었다. 이 언어는 원래 돈 심에 의해 설계 및 구현되었으며, F# 팀에서는 F가 "Fun"(재미)을 의미한다고 한다. 앤드류 케네디(Andrew Kennedy)는 단위 측정 설계에 기여했다. Visual Studio용 Visual F# 도구는 마이크로소프트에서 개발했다. F# 소프트웨어 재단은 마이크로소프트 Visual F# 도구 팀에서 제공하는 오픈 소스 컴파일러 구현을 통합하여 F# 오픈 소스 컴파일러 및 도구를 개발했다.

👆
좌우로 밀어서 보기
F# 버전 요약
F# 버전추가된 기능
1.0
2.0
3.0
3.1
4.0
4.1
4.5
4.6
4.7
5.0
6.0
7.0
8.0

3. 문법

F#은 OCaml을 계승한 언어로, OCaml과 호환되는 장황 구문 (verbose syntax영어)과 파이썬과 같은 오프사이드 규칙을 사용한 경량 구문 (lightweight syntax영어)의 두 종류 구문을 사용할 수 있다. 표준 설정에서는 경량 구문이 활성화되어 있다. F#은 타입을 자동으로 유추하는 강력한 형식 지정 언어이다.

3.1. F# 함수의 형태

함수형 프로그래밍의 "Hello World"라고 할 만한 것은 팩토리얼을 계산하는 코드이다. F#으로는 다음과 같이 표현할 수 있다.


let rec fact n =
match n with
| 0 -> 1
| _ -> n * fact (n-1);;


이 코드는 팩토리얼을 재귀 함수로 정의한 것이다. 일반적으로 함수를 정의할 때는 `let`을 쓰고, 재귀함수를 정의할 때는 `let rec`와 같이 명시한다. 함수의 마지막에는 두 개의 세미콜론으로 끝마침을 해 준다.

위 함수 정의는 수학 교과서에서 볼 수 있는 팩토리얼의 정의와 비슷하다. F# 코드는 문법과 계산 방식의 측면에서 수학적 언어와 닮았다.

F#은 자동으로 타입을 유추한다. 위의 `fact` 함수는 `(int -> int)` 타입, 즉 정수를 인자로 받아 또 다른 정수를 반환하는 함수이다.

두 번째 줄에서 F#의 또 다른 중요한 특성인 패턴 매칭을 볼 수 있다. 패턴 매칭은 `match ... with ...`와 같이 표현한다. 함수 `fact`는 인자가 0이면 1을 반환하고, 아니면 두 번째 케이스를 실행하여 0에 도달할 때까지 `fact`을 재귀적으로 계속 호출한다. 패턴 매칭에서 `_`는 디폴트 케이스를 의미한다.

3.2. 개선된 팩토리얼 함수

fsharp
#light

let factorial n =
let rec fac a x =
match x with
| k when k < 1 -> 1I
| k when k = 1 -> a
| v -> fac (a * (bigint x)) (x - 1)
fac 1I n
```

팩토리얼 함수는 지수 함수보다 훨씬 빠르게 커지므로 큰 정수 계산이 가능해야 하고, 재귀 호출 함수의 성능도 고려해야 한다. 큰 정수의 곱셈 계산을 위해 팩토리얼 값은 `bigint` 타입을 사용하고, 함수의 인자는 `int` 타입을 사용한다. `bigint` 타입 리터럴은 `int` 타입 리터럴 끝에 `I`를 붙여 표현한다. (예: `4`는 `int` 타입, `4I`는 `bigint` 타입). `int` 타입을 `bigint` 타입으로 변환하려면 `bigint x`와 같이 표현식 왼쪽에 `bigint`를 붙인다.

위의 `factorial` 함수는 `(int -> bigint)` 타입의 함수이다. 함수 안에서 재귀 호출 함수 `fac`을 정의하는 중첩 구조로 되어 있다. `fac` 함수의 첫 번째 인자 `a`는 재귀 호출 과정에서 계산된 이전 단계의 팩토리얼 값을 저장하는 상태 역할을 한다.

예를 들어 4! 계산 과정은 다음과 같다.

* fac 1I 4
* => fac (4I) 3
* => fac (12I) 2
* => fac (24I) 1
* => 24I

이 코드는 5000!을 계산할 때도 스택 오버플로우를 걱정할 필요가 없다. F# 언어는 패턴 매칭(match)에 의한 재귀 호출이 상태에 의한 호출이기 때문이다. 이러한 재귀 호출을 꼬리 재귀 호출이라고 한다.

4. 언어 개요

F#은 함수형 프로그래밍객체 지향 프로그래밍을 모두 지원하는 함수 우선 언어이다. C#에서 사용할 수 있는 객체 지향 기능을 지원하면서, 함수형 프로그래밍 언어에서 일반적으로 발견되는 많은 기능을 갖춘 강력한 형식 지정 언어이다. 이러한 기능을 통해 F# 프로그램은 완전한 함수형 스타일로 작성될 수 있으며, 함수형 스타일과 객체 지향 스타일을 혼합하여 사용할 수도 있다.

2002년부터 마이크로소프트 리서치(Microsoft Research)의 Don Syme영어 등이 OCaml을 기반으로 개발을 시작했다. OCaml에서 많은 요소를 물려받은 함수형 및 객체 지향의 멀티 패러다임 프로그래밍 언어이다. 형 안전성을 가지며, 형 추론 기능을 갖추고 있다. 하지만 오버로딩을 지원하기 때문에 OCaml이 가진 형 추론의 완전성은 잃었다.

C# 및 Visual Basic .NET 등 .NET 언어와 상호 운용성이 있으며, .NET 클래스 라이브러리의 이용 및 개발이 가능하다. Mono 및 Xamarin을 이용한 Android 애플리케이션 개발도 지원된다. F#의 F는 Functional programming language(함수형 프로그래밍 언어) 및 System F에서 유래했다.

4.1. 함수형 프로그래밍

F#은 객체 지향 프로그래밍 기능을 지원하는 동시에, 함수형 프로그래밍에서 주로 사용되는 여러 기능을 갖춘 강력한 형식 지정 언어이다. F# 프로그램을 완전한 함수형 스타일로 작성하거나, 함수형 스타일과 객체 지향 스타일을 혼합하여 사용할 수 있다.

F#에서 지원하는 함수형 기능은 다음과 같다.

* 모든 것은 표현식이다.
* 형식 추론(힌들리-밀너 형식 추론 사용)
* 일급 함수
* 포획 의미론(클로저 등)을 가진 익명 함수
* 불변 변수 및 객체
* 지연 평가 지원
* 고차 함수
* 중첩 함수
* 커링
* 패턴 매칭
* 대수적 데이터 형식
* 튜플
* 리스트 컴프리헨션
* 모나드 패턴 지원 (컴퓨테이션 표현식이라고 함)
* 꼬리 재귀 최적화

F#은 즉시 평가를 사용하며, 경우에 따라 지연 평가를 사용하는 표현식 기반 언어이다. `if` 표현식, `try` 표현식 및 루프를 포함한 F#의 모든 문은 정적 형식을 가진 구성 가능한 표현식이다. 값을 반환하지 않는 함수와 표현식은 `unit` 반환 형식을 갖는다. F#은 `let` 키워드를 사용하여 값을 이름에 바인딩한다. 예를 들어,
```fsharp
let x = 3 + 4
```
는 값 `7`을 이름 `x`에 바인딩한다.

새로운 형식은 `type` 키워드를 사용하여 정의된다. 함수형 프로그래밍을 위해 F#은 튜플, 레코드, 구별된 유니온, 리스트, 옵션결과 형식을 제공한다. 튜플n개의 값 집합을 나타내며, 여기서 n ≥ 0이다. 값 n은 튜플의 항수라고 한다. 3-튜플은 `(A, B, C)`로 표시되며, 여기서 A, B, C는 서로 다른 형식의 값일 수 있다. 튜플은 실행 시에 값의 수가 설계 시점에 알려지고 일정하게 유지될 때만 값을 저장하는 데 사용할 수 있다.

레코드는 데이터 멤버의 이름이 지정된 형식이다. 레코드 정의의 예는 다음과 같다.
```fsharp
type R =
{ Name : string
Age : int }
```
레코드는 `let r = { Name="AB"; Age=42}`와 같이 생성할 수 있다. `with` 키워드는 `{ r with Name="CD"}`와 같이 레코드의 복사본을 만드는 데 사용되며, `r`을 복사하고 `Name` 필드의 값을 변경하여 새 레코드를 생성한다(마지막 예제에서 생성된 레코드가 `r`로 명명되었다고 가정).

구별된 유니온 형식은 형식 안전 버전의 C 유니온이다. 예를 들어,
```fsharp
type A =
| UnionCaseX of string
| UnionCaseY of int
```
유니온 형식의 값은 각 유니온 케이스에 해당할 수 있다. 각 유니온 케이스가 전달하는 값의 형식은 각 케이스의 정의에 포함된다.

리스트 형식은 `head::tail` 표기법(`::`는 cons 연산자) 또는 `[item1; item2; item3]`과 같은 약식을 사용하여 표현되는 불변의 연결 리스트이다. 빈 리스트는 `[]`로 작성된다. 옵션 형식은 `Some(x)` 또는 `None` 선택 항목이 있는 구별된 유니온 형식이다. F# 형식은 제네릭일 수 있으며, 제네릭 .NET 형식으로 구현된다.

F#은 람다 함수와 클로저를 지원한다. F#의 모든 함수는 일급 값이며 불변이다. 함수는 커리 될 수 있다. 일급 값이므로 함수는 다른 함수의 인수로 전달될 수 있다. 다른 함수형 프로그래밍 언어와 마찬가지로 F#은 `>>` 및 `<<` 연산자를 사용하여 함수 합성을 허용한다.

F#은 값을 생성하는 코드를 통해 시퀀스 `seq { ... }`, 리스트 `[ ... ]` 또는 배열 `[| ... |]`을 정의하는 시퀀스 표현식을 제공한다. 예를 들어,
```fsharp
seq { for b in 0 .. 25 do
if b < 15 then
yield b*b }
```
는 0에서 25까지의 숫자 범위에서 숫자를 필터링하여 0에서 14까지의 숫자의 제곱 시퀀스를 형성한다. 시퀀스는 생성기이다. 즉, 값은 필요에 따라 생성된다(즉, 지연 평가됨). 반면 리스트와 배열은 즉시 평가된다.

F#은 패턴 매칭을 사용하여 값을 이름에 바인딩한다. 패턴 매칭은 구별된 유니온에 액세스할 때도 사용된다. 유니온은 패턴 규칙에 대해 값 일치되며, 일치가 성공하면 규칙이 선택된다. F#은 또한 확장 가능한 패턴 매칭 형태인 액티브 패턴을 지원한다. 예를 들어, 형식에 대한 일치하는 여러 방법이 존재할 때 사용된다.

F#은 컴퓨테이션 표현식이라고 하는 구성 가능한 계산을 정의하기 위한 일반적인 구문을 지원한다. 시퀀스 표현식, 비동기 계산 및 쿼리는 특정 종류의 컴퓨테이션 표현식이다. 컴퓨테이션 표현식은 모나드 패턴의 구현이다.

4.2. 명령형 프로그래밍

F#은 다음과 같은 명령형 프로그래밍 기능을 지원한다.

* `let` 키워드를 사용한 값 바인딩.
* `unit` 반환 형식을 가진 함수 및 표현식.
* 튜플, 레코드, 구별된 유니온, 리스트, 옵션, 결과 형식.
* `::` (cons 연산자) 또는 `[item1; item2; item3]` 표기법을 사용한 불변 연결 리스트.
* `seq { ... }`, `[ ... ]`, `[| ... |]`를 사용한 시퀀스 표현식 (생성기는 지연 평가되고, 리스트와 배열은 즉시 평가됨).
* 패턴 매칭을 통한 값 바인딩 및 구별된 유니온 접근.
* 컴퓨테이션 표현식 (모나드 패턴 구현)을 통한 구성 가능한 계산 정의.
* `async{ ... }`를 사용한 비동기 프로그래밍 지원 (비동기 워크플로우).
* .NET 작업 직접 생성, 사용 및 반환 지원 (버전 6.0부터).

4.3. 객체 지향 프로그래밍

F#은 다른 공용 언어 기반 (CLI) 언어와 마찬가지로 객체 지향 프로그래밍을 통해 CLI 형식을 사용할 수 있다. F#은 C#에서 사용할 수 있는 객체 지향 기능을 지원한다.

2002년부터 마이크로소프트 리서치(Microsoft Research)의 Don Syme영어 등이 OCaml을 기반으로 개발을 시작했다.

4.4. 비동기 프로그래밍

F#은 비동기 워크플로우를 통해 비동기 프로그래밍을 지원한다. 비동기 워크플로우는 `async{ ... }` 내의 일련의 명령으로 정의된다. 다음은 그 예이다.

```fsharp
let asynctask =
async { let req = WebRequest.Create(url)
let! response = req.GetResponseAsync()
use stream = response.GetResponseStream()
use streamreader = new System.IO.StreamReader(stream)
return streamreader.ReadToEnd() }
```

`let!`은 오른쪽에 있는 표현식(응답 가져오기)이 비동기적으로 수행되어야 하지만 결과가 사용 가능할 때만 흐름이 계속되어야 함을 나타낸다. 즉, 코드 블록의 관점에서 볼 때 응답을 가져오는 것은 차단 호출과 같지만, 시스템의 관점에서 볼 때 스레드는 차단되지 않으며 이 스레드에 필요한 결과가 나올 때까지 다른 흐름을 처리하는 데 사용될 수 있다.

async 블록은 `Async.RunSynchronously` 함수를 사용하여 호출할 수 있다. 여러 async 블록은 `async` 객체 목록을 사용하는 `Async.Parallel` 함수를 사용하여 병렬로 실행할 수 있다. (예제에서 `asynctask`는 async 객체이다.) 이 함수는 목록의 작업을 병렬로 실행하기 위해 다른 async 객체를 생성한다. 결과 객체는 `Async.RunSynchronously`를 사용하여 호출된다.

F#의 제어 역전은 이 패턴을 따른다.

버전 6.0부터 F#은 .NET 작업을 직접 생성, 사용 및 반환하는 것을 지원한다.

```fsharp
open System.Net.Http
let fetchUrlAsync (url:string) = // string -> Task
task {
use client = new HttpClient()
let! response = client.GetAsync(url)
let! content = response.Content.ReadAsStringAsync()
do! Task.Delay 500
return content
}

// Usage
let fetchPrint() =
let task = task {
let! data = fetchUrlAsync "https://example.com"
printfn $"{data}"
}
task.Wait()

4.5. 병렬 프로그래밍

F#은 `Async.Parallel`, `Async.Start` 등의 함수를 통해 병렬 프로그래밍을 지원한다. F# 표준 라이브러리의 `Array.Parallel` 함수형 프로그래밍 연산자, `System.Threading.Tasks` 작업 프로그래밍 모델, .NET 스레드 풀 등을 사용할 수 있다. F# 코드를 GPU 코드와 같은 대체 병렬 실행 엔진으로 동적 변환하는 기능도 지원한다.

4.6. 단위 측정

F# 타입 시스템은 숫자 값에 대한 단위 검사를 지원한다.

F#에서는 미터나 킬로그램과 같은 단위(측정)를 부동 소수점, 부호 없는 정수 및 부호 있는 정수 값에 할당할 수 있다. 이를 통해 컴파일러는 이러한 값을 포함하는 산술 연산이 차원적으로 일치하는지 확인할 수 있으며, 예를 들어 길이를 시간에 실수로 더하는 것과 같은 일반적인 프로그래밍 실수를 방지할 수 있다.

단위(측정) 기능은 F# 타입 추론과 통합되어 사용자 코드에서 최소한의 타입 주석만 필요로 한다.

```fsharp
[] type m // 미터
[] type s // 초

let distance = 100.0 // float
let time = 5.0 // float
let speed = distance/time // float

[] type kg // 킬로그램
[] type N = (kg * m)/(s^2) // 뉴턴
[] type Pa = N/(m^2) // 파스칼

[] type days
let better_age = 3u // uint
```

F# 정적 타입 검사기는 컴파일 시간에 이 기능을 제공하지만, 단위는 컴파일된 코드에서 지워진다. 결과적으로 런타임에 값의 단위를 결정하는 것은 불가능하다.

4.7. 메타프로그래밍

F#은 사용자 정의 도메인 특화 언어를 F# 언어 내에 임베딩하기 위해, 특히 계산식(computation expressions)을 통해 메타프로그래밍의 몇 가지 형태를 허용한다.

F#은 런타임 메타프로그래밍을 위한 기능인 쿼테이션(quotations)을 포함한다. 쿼테이션 표현식은 F# 표현식의 추상 구문 트리 표현으로 평가된다. 마찬가지로, `[<ReflectedDefinition>]` 특성으로 레이블된 정의도 쿼테이션 형태로 액세스할 수 있다. F# 쿼테이션은 F# 코드를 자바스크립트GPU 코드로 컴파일하는 것을 포함하여 다양한 용도로 사용된다. 쿼테이션은 F# 코드 표현식을 프로그램의 다른 부분에서 사용할 데이터로 나타내면서도 구문적으로 올바른 F# 코드여야 한다.

F# 3.0은 F# 타입 공급자라고 불리는 정적으로 확장 가능한 타입 생성을 통해 컴파일 시점 메타 프로그래밍 형태를 도입했다. F# 타입 공급자는 F# 컴파일러와 도구가 컴파일 시간에 필요에 따라 컴파일러에 타입 정보를 제공하는 구성 요소로 확장될 수 있도록 한다. F# 타입 공급자는 Freebase 지식 그래프를 포함하여 확장 가능한 방식으로 연결된 정보 소스에 강력한 형식으로 액세스하는 데 사용되어 왔다.

F# 3.0에서 F# 쿼테이션 및 계산 표현식 기능이 결합되어 LINQ 쿼리를 구현한다. 타입 공급자, 쿼리 및 강력한 형식의 함수형 프로그래밍의 조합을 정보 풍부 프로그래밍이라고 한다.

4.8. 에이전트 프로그래밍

F#은 경량 비동기 에이전트의 메모리 내 구현을 통해 액터 프로그래밍 모델의 변형을 지원한다. 다음은 F# 코드로 에이전트를 정의하고 2개의 메시지를 게시하는 예시이다.

```fsharp
type Message =
| Enqueue of string
| Dequeue of AsyncReplyChannel>

// 문자열 목록에 대한 동시 접근 제공
let listManager = MailboxProcessor.Start(fun inbox ->
let rec messageLoop list = async {
let! msg = inbox.Receive()
match msg with
| Enqueue item ->
return! messageLoop (item :: list)

| Dequeue replyChannel ->
match list with
| [] ->
replyChannel.Reply None
return! messageLoop list
| head :: tail ->
replyChannel.Reply (Some head)
return! messageLoop tail
}

// 빈 목록으로 루프 시작
messageLoop []
)

// 사용법
async {
// 몇 개의 문자열 인큐
listManager.Post(Enqueue "Hello")
listManager.Post(Enqueue "World")

// 문자열을 디큐하고 처리
let! str = listManager.PostAndAsyncReply(Dequeue)
str |> Option.iter (printfn "Dequeued: %s")

}
|> Async.Start

5. 개발 도구

* 비주얼 스튜디오는 마이크로소프트에서 제공하는 Visual F# 도구를 설치하여 F# 프로젝트를 만들고, 실행하고, 디버깅하는 데 사용할 수 있다. Visual F# 도구에는 F# 코드를 작성하면서 실행할 수 있는 비주얼 스튜디오에서 호스팅되는 대화형 콘솔이 포함되어 있다. 비주얼 스튜디오 for Mac 또한 F# 프로젝트를 완벽하게 지원한다.
* 비주얼 스튜디오 코드는 [http://ionide.io/ Ionide 확장]을 통해 F#을 완벽하게 지원한다.
* F#은 모든 텍스트 편집기로 개발할 수 있다. 이맥스와 같은 편집기에서 특별히 지원된다.
* JetBrains Rider는 2019.1 릴리스부터 F# 코드 개발에 최적화되었다.
* LINQPad는 버전 2.x부터 F#을 지원해 왔다.

6. 응용 분야

F#은 범용 프로그래밍 언어이다. 2010년대에 F#은 C#의 최적화된 대안으로 자리매김했으며, F#의 스크립팅 능력과 모든 마이크로소프트 제품과의 상호 언어 호환성은 개발자들 사이에서 인기를 얻게 했다.

6.1. 웹 프로그래밍

SAFE 스택(https://safe-stack.github.io/)은 웹 애플리케이션 개발을 위한 엔드투엔드 F# 스택이다. 서버 측에서는 ASP.NET Core를 사용하고, 클라이언트 측에서는 [https://fable.io Fable]을 사용한다.

또 다른 엔드투엔드 F# 옵션으로는 WebSharper 프레임워크가 있다.

6.2. 크로스 플랫폼 앱 개발

F#은 iOS 및 안드로이드용 앱을 개발하기 위해 https://visualstudio.microsoft.com/xamarin/ 비주얼 스튜디오 툴즈 포 자마린과 함께 사용할 수 있다. https://github.com/fsprojects/Fabulous Fabulous 라이브러리는 보다 편리한 함수형 인터페이스를 제공한다.

6.3. 분석 프로그래밍

F#은 특히 정량적 금융 프로그래밍, 에너지 거래 및 포트폴리오 최적화, 머신 러닝, 비즈니스 인텔리전스페이스북에서의 소셜 게임 등에 사용된다.

2010년대에 F#은 C#의 최적화된 대안으로 자리매김했다. F#의 스크립팅 능력과 모든 마이크로소프트 제품과의 상호 언어 호환성은 개발자들 사이에서 인기를 얻게 했다.

6.4. 스크립팅

F#은 주로 데스크톱 대화형 인터프리터(REPL) 스크립팅을 위해 스크립팅 언어로 사용될 수 있다.

7. 오픈 소스 커뮤니티

F# 오픈 소스 커뮤니티에는 F# 소프트웨어 재단깃허브의 F# 오픈 소스 그룹이 포함되어 있다. 주요 오픈 소스 F# 프로젝트는 다음과 같다.

* https://fable.io/ Fable - 바벨 기반의 F#에서 Javascript로 변환하는 컴파일러.
* https://fsprojects.github.io/Paket/ Paket - NuGet 저장소를 사용할 수 있지만 중앙 집중식 버전 관리가 가능한 .NET용 대체 패키지 관리자.
* https://fake.build/ FAKE - F# 친화적인 빌드 시스템.
* https://github.com/giraffe-fsharp/Giraffe Giraffe - ASP.NET Core용 기능 지향 미들웨어.
* https://suave.io/ Suave - 경량 웹 서버 및 웹 개발 라이브러리.

8. 호환성

F#은 펀터, 객체, 다형적 변형 등을 제외한 OCaml의 큰 하위 집합으로 작성된 프로그램을 직접 컴파일할 수 있는 "ML 호환 모드"를 지원한다. OCaml 호환 표준 라이브러리를 갖추고 있어 F#과 OCaml 양쪽에서 컴파일 가능한 코드를 작성할 수 있다. 그러나 클래스 구문 등은 F#과 OCaml에서 다르다.

9. 예제

fsharp
// 간단한 Hello World 프로그램
printfn "Hello World!"
```

```fsharp
// 레코드 형식 정의. 레코드는 기본적으로 변경할 수 없으며 구조적 동등성으로 비교
type Person = {
FirstName: string
LastName: string
Age: int
}

// 레코드의 인스턴스 생성
let person = { FirstName = "John"; LastName = "Doe"; Age = 30 }
```

```fsharp
// 이름과 나이, 그리고 두 개의 변경 불가능한 속성을 갖는 생성자를 가진 Person 클래스.
/// 형식 정의에 대한 문서화 주석
type Person(name : string, age : int) =
member x.Name = name
member x.Age = age

/// 클래스 인스턴스화
let mrSmith = Person("Smith", 42)
```

팩토리얼 함수 예제:

```fsharp
/// 패턴 일치 표현식 사용
let rec factorial n =
match n with
| 0 -> 1
| _ -> n * factorial (n - 1)

/// 단일 인수 함수의 경우 (패턴 일치 함수):
let rec factorial = function
| 0 -> 1
| n -> n * factorial (n - 1)

/// fold 및 범위 연산자 사용
let factorial n = [1..n] |> Seq.fold (*) 1
```

반복 예제:

```fsharp
/// 'for' 루프를 사용한 반복
let printList lst =
for x in lst do
printfn $"{x}"

/// 고차 함수를 사용한 반복
let printList2 lst =
List.iter (printfn "%d") lst

/// 재귀 함수 및 패턴 일치를 사용한 반복
let rec printList3 lst =
match lst with
| [] -> ()
| h :: t ->
printfn "%d" h
printList3 t
```

피보나치 수 예제:

```fsharp
/// 피보나치 수 공식
[]
let fib n =
let rec g n f0 f1 =
match n with
| 0 -> f0
| 1 -> f1
| _ -> g (n - 1) f1 (f0 + f1)
g n 0 1

/// 다른 접근 방식 - 피보나치 수의 게으른 무한 시퀀스
let fibSeq = Seq.unfold (fun (a,b) -> Some(a+b, (b, a+b))) (0,1)

// 짝수 피보나치 출력
[1 .. 10]
|> List.map fib
|> List.filter (fun n -> (n % 2) = 0)
|> printList

// 동일한 내용, 목록 표현식 사용
[ for i in 1..10 do
let r = fib i
if r % 2 = 0 then yield r ]
|> printList
```

샘플 Windows Forms 프로그램:

```fsharp
// Windows Forms 라이브러리 열기
open System.Windows.Forms

// 창을 만들고 몇 가지 속성을 설정.
let form = new Form(Visible=true, TopMost=true, Text="Welcome to F#")

// 폼에 텍스트를 표시할 레이블 만들기
let label =
let x = 3 + (4 * 5)
new Label(Text = $"{x}")

// 폼에 레이블 추가
form.Controls.Add(label)

// 마지막으로 폼 실행
[]
Application.Run(form)
```

비동기 병렬 프로그래밍 샘플 (병렬 CPU 및 I/O 작업):

```fsharp
/// 간단한 소수 감지기
let isPrime (n:int) =
let bound = int (sqrt (float n))
seq {2 .. bound} |> Seq.forall (fun x -> n % x <> 0)

// 비동기 워크플로우를 사용
let primeAsync n =
async { return (n, isPrime n) }

/// 여러 스레드를 사용하여 m과 n 사이의 소수 반환
let primes m n =
seq {m .. n}
|> Seq.map primeAsync
|> Async.Parallel
|> Async.RunSynchronously
|> Array.filter snd
|> Array.map fst

// 테스트 실행
primes 1000000 1002000
|> Array.iter (printfn "%d")

본 사이트는 AI가 위키백과와 뉴스 기사, 정부 간행물, 학술 논문 등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.

하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.