함수 캡처(Function captures)
Gleam은 익명 함수를 간단히 작성할 수 있는 문법을 제공합니다. 하나의 인자를 받아 즉시 다른 함수에 넘기는 익명 함수를 짧게 표현하는 방식입니다.
`fn(a) { some_function(..., a, ...) }`는 `some_function(..., _, ...)`으로 쓸 수 있습니다. 여기서 밑줄 `_`은 인자의 자리 표시자(placeholder)이며, `fn(a) { ... }`에서의 `a`와 동일합니다.
```rust
pub fn main() {
// 이 두 문장은 동일합니다
let add_one_v1 = fn(x) { add(1, x) }
let add_one_v2 = add(1, _)
echo add_one_v1(10)
echo add_one_v2(10)
}
fn add(a: Int, b: Int) -> Int {
a + b
}
```

제네릭 함수(Generic functions)
지금까지의 함수는 각 인자마다 정확히 하나의 타입만을 받을 수 있었습니다.
앞서 살펴본 twice 함수(고차 함수 예제)는 오직 Int를 인자로 받고 반환하는 함수에만 사용할 수 있었습니다. 이는 지나치게 제한적입니다. 함수와 초기 값이 호환된다면, 어떤 타입에도 사용할 수 있어야 합니다.
이를 위해 Gleam은 제네릭(Generic), 즉 매개변수 다형성(parametric polymorphism)을 지원합니다.
구체적 타입 대신 타입 변수(type variable)를 사용합니다. 이는 함수 호출 시 실제로 사용되는 구체적 타입으로 대체됩니다. 타입 변수는 소문자로 작성합니다.
타입 변수는 `any` 같은 무제한 타입이 아니라, 함수가 호출될 때마다 특정 타입으로 고정됩니다. 아래 예제에서 `twice(10, exclaim)`을 주석 해제하면, 동시에 `Int`와 `String` 타입을 혼용했기 때문에 컴파일 오류가 발생합니다.
```rust
pub fn main() {
let add_one = fn(x) { x + 1 }
let exclaim = fn(x) { x <> "!" }
// 잘못된 예시: Int와 String은 같은 타입이 아님
// twice(10, exclaim)
// 여기서는 타입 변수가 Int로 대체됨
echo twice(10, add_one)
// 여기서는 타입 변수가 String으로 대체됨
echo twice("Hello", exclaim)
}
// `value`라는 이름의 타입 변수가 여러 번 같은 타입을 가리킴
fn twice(argument: value, my_function: fn(value) -> value) -> value {
my_function(my_function(argument))
}
```
파이프라인(Pipelines)
여러 함수를 차례대로 호출하면서 결과를 다음 함수에 넘기고 싶을 때가 많습니다. 일반적인 함수 호출 문법으로는 코드를 안쪽에서부터 바깥쪽으로 읽어야 해서 가독성이 떨어질 수 있습니다.
Gleam의 파이프 연산자(`|>`)는 이런 문제를 해결하여 코드를 위에서 아래로 자연스럽게 읽을 수 있게 해줍니다. Elixir family의 꽃이죠.
파이프 연산자는 왼쪽 표현식의 결과를 오른쪽 함수의 인자로 전달합니다.
먼저 왼쪽 값을 오른쪽 함수의 첫 번째 인자로 넣을 수 있는지 확인합니다. 가능하다면 `a |> b(1, 2)`는 `b(a, 1, 2)`가 됩니다. 그렇지 않으면 오른쪽이 함수로 평가된 뒤 그 결과에 왼쪽 값을 적용합니다.
Gleam 코드는 보통 함수의 첫 번째 인자 자리에 “주제(subject)” 값을 두는 식으로 작성합니다. 이렇게 하면 파이프 사용이 자연스러워집니다. 만약 다른 위치에 값을 전달해야 한다면, 함수 캡처 문법을 사용하여 원하는 위치에 인자를 삽입할 수 있습니다.
파이프라인 중간에서 디버깅 출력이 필요하다면 `|> echo`를 사용하면 됩니다.
```rust
import gleam/io
import gleam/string
pub fn main() {
// 파이프 연산자 없이
io.println(string.drop_start(string.drop_end("Hello, Joe!", 1), 7))
// 파이프 연산자 사용
"Hello, Mike!"
|> string.drop_end(1)
|> string.drop_start(7)
|> io.println
// 함수 캡처로 순서 조정
"1"
|> string.append("2")
|> string.append("3", _)
|> io.println
}
```
문서 출처: Gleam 공식 문서 “Documentation / Installing Gleam”, https://gleam.run/documentation/
라이선스: Apache License, Version 2.0 (https://github.com/gleam-lang/gleam)
'Programming Languages > Gleam' 카테고리의 다른 글
| [Gleam 언어 강좌] Case, variable/string/list pattern (0) | 2025.10.03 |
|---|---|
| [Gleam 언어 강좌] label, doc comments, deprecation (0) | 2025.10.02 |
| [Gleam 언어 강좌] 함수, 고차 함수, 익명함수 (0) | 2025.09.30 |
| [Gleam 언어 강좌] block, list, constant (0) | 2025.09.29 |
| [Gleam 언어 강좌] discard, 타입 애노테이션, 타입 별칭, 타입 임포트 (0) | 2025.09.28 |