함수가 1등 시민(first-class citizen)
함수를 타입으로 지정하거나, 인자값으로 넘기거나, 리턴 값으로 받을 수 있다.
마치 함수도 객체처럼 변수나 함수의 인자, 리터럴하게 다룰 수 있다
는 것
심볼의 값이 변경되지 않는다
가변 변수를 사용하는 대신에 심볼에 값을 할당하면 그 값은 변하지 않음
→ 변수 값이 변경되는 경우 해당 변수가 가리키고 있는 주소의 값은 변하지 않고, 새로운 주소에 변경된 값을 넣고 그 주소를 바라보게 한다.
→ 원본은 변하지 않는다!
입력 값이 동일하면 결과 값이 동일하게 리턴되는 함수
순수 함수로 만들면 함수 외부에 값이나 객체를 참조하거나 의존적으로 동작하지 않기 때문에 참조 투명성을 가지고, 부작용이 없다.
부작용이 있는 함수는 입력 값이 동일해도 함수 외부에 값에 따라서 다른 값을 리턴한다.
let c = 100
func foo(a, b) {
return (a + b + c)
}
/// 항상 같은 인자가 주어져도 외부에서 C가 바뀌면 값이 달라진다.
클로저 표현식
{ (매개 변수) -> 리턴 타입 in
실행 구문
}
func doSomething(closure: () -> ()) {
closure()
}
doSomething(closure: { () -> () in
print("hello")
})
// "hello"
func doSomething2() -> () -> () {
return { () -> () in
print("hello4")
}
}
doSomething2()() // "hello4"
후행 클로저
doSomething(closure: { () -> () in
print("Hello!")
})
얘를
doSomething () { () -> () in
print("Hello!")
}
이렇게 표현할 수 있다. 게다가 파라미터가 클로저 하나의 경우 소괄호도 생략 가능하다.
클로저의 경량 문법
파라미터 형식과 리턴 형식을 생략할 수 있다.
doSomething(closure: { (a: Int, b: Int, c: Int) -> Int in
return a + b + c
})
⬇ 이렇게
doSomething(closure: { (a, b, c) in
return a + b + c
})
Parameter Name은 Shortand Argument Names(약식 인수)으로 대체하고, 이 경우 Parameter Name과 in 키워드를 삭제한다
doSomething(closure: {
return $0 + $1 + $2
})
// 단일 리턴문만 남을 경우 return도 생략 가능
doSomething(closure: {
$0 + $1 + $2
})
// 후행 클로저로 작성
doSomething() {
$0 + $1 + $2
}
// ()에 아무 값이 없다면 생략
doSomething {
$0 + $1 + $2
}
일단 양방향 연결리스트로 구현하고
불변성을 더 지키고 싶으면 단방향으로 바꾼 후 add를 맨 앞에 하고 나머지를 복사하는 식으로 해보는 시도를 해보자.
실제 함수가 호출하여 값에 접근할 때까지 계산하지 않음
함수처럼 동작하는 객체
값이 있을 수도 있고 없을 수도 있는 Context를 가지는 Functor