F# 이란 무엇인가요?
F# 이란 무엇인가요?
F# 은 간결하고(succinct) 견고하며(robust) 성능 좋은 코드를 쓰기 위한 범용 프로그래밍 언어예요.
F# 을 쓰면 군더더기 없고 자기 스스로 설명이 되는 코드를 작성할 수 있죠. 프로그래밍의 세부적인 지식보다는, 여러분이 풀고 싶은 문제 영역(problem domain) 에 집중할 수 있게 해 줘요.
그런데도 속도와 호환성을 희생하지 않아요. F# 은 오픈소스이고, 크로스 플랫폼이며, 다른 언어와도 잘 섞어 쓸 수 있어요(interoperable).
open System // Gets access to functionality in System namespace.
// Defines a list of names
let names = [ "Peter"; "Julia"; "Xi" ]
// Defines a function that takes a name and produces a greeting.
let getGreeting name = $"Hello, {name}"
// Prints a greeting for each name!
names
|> List.map getGreeting
|> List.iter (fun greeting -> printfn $"{greeting}! Enjoy your F#")
본문
F# 은 다양한 기능을 갖추고 있어요:
- 가벼운 문법 (lightweight syntax)
- 기본값이 불변(immutable by default)
- 타입 추론과 자동 일반화 (type inference and automatic generalization)
- 일급 함수 (first-class functions)
- 강력한 데이터 타입
- 패턴 매칭 (pattern matching)
- 비동기 프로그래밍 (async programming)
이 모든 기능의 전체 목록은 F# language guide 문서에 정리되어 있어요.
풍부한 데이터 타입 (Rich data types)
Records 같은 타입이나 Discriminated Unions 을 쓰면 여러분의 데이터를 그대로 표현할 수 있어요.
// Group data with Records
type SuccessfulWithdrawal =
{ Amount: decimal
Balance: decimal }
type FailedWithdrawal =
{ Amount: decimal
Balance: decimal
IsOverdraft: bool }
// Use discriminated unions to represent data of 1 or more forms
type WithdrawalResult =
| Success of SuccessfulWithdrawal
| InsufficientFunds of FailedWithdrawal
| CardExpired of System.DateTime
| UndisclosedFailure
F# 의 record 와 discriminated union 은 기본적으로 null 이 아니고, 불변이며, 비교 가능해요. 그래서 아주 쓰기 편해요.
함수와 패턴 매칭으로 얻는 정확성 (Correctness with functions and pattern matching)
F# 함수는 정의하기 쉬워요. 패턴 매칭 과 함께 쓰면, 컴파일러가 정확성을 강제해 주는 방식으로 동작을 정의할 수 있어요.
// Returns a WithdrawalResult
let withdrawMoney amount = // Implementation elided
let handleWithdrawal amount =
let w = withdrawMoney amount
// The F# compiler enforces accounting for each case!
match w with
| Success s -> printfn $"Successfully withdrew %f{s.Amount}"
| InsufficientFunds f -> printfn $"Failed: balance is %f{f.Balance}"
| CardExpired d -> printfn $"Failed: card expired on {d}"
| UndisclosedFailure -> printfn "Failed: unknown :("
F# 함수는 일급(first-class)이기도 해요. 즉 다른 함수의 인자로 넘기거나, 다른 함수의 반환값으로 돌려줄 수 있어요.
객체를 다루는 연산을 정의하는 함수 (Functions to define operations on objects)
F# 은 객체(object)를 완전히 지원해요. 데이터와 기능을 섞어 써야 할 때 특히 유용하죠. 객체를 다루는 F# 멤버(member)와 함수를 정의할 수 있어요.
type Set<'T when 'T: comparison>(elements: seq<'T>) =
member s.IsEmpty = // Implementation elided
member s.Contains (value) =// Implementation elided
member s.Add (value) = // Implementation elided
// ...
// Further Implementation elided
// ...
interface IEnumerable<'T>
interface IReadOnlyCollection<'T>
module Set =
let isEmpty (set: Set<'T>) = set.IsEmpty
let contains element (set: Set<'T>) = set.Contains(element)
let add value (set: Set<'T>) = set.Add(value)
F# 에서는 함수가 다루기 위한 일종의 타입으로 객체를 취급하는 코드를 자주 볼 수 있어요. generic interfaces, object expressions, 그리고 members 를 알맞게 사용하는 일은 규모가 큰 F# 프로그램에서 흔한 패턴이에요.
더 알아보기
더 넓은 F# 기능을 살펴보고 싶다면 F# Tour 문서도 확인해 보세요. F# 의 더 많은 기능을 천천히 소개해 줘요.