6. 함수 만들고 호출하기

  • 함수형 언어는 함수를 일급 객체로 다룬다.
  • 평범한 한글은 함수형 언어이다.
  • 당연한 말이지만, 사용자가 함수를 정의할 수 있고 이를 호출할 수 있다.

초간단 함수

  • 함수는 [함수 몸통] ㅎ 과 같은 모양으로 만든다.
  • 아래에 첫 번째 함수가 있다.
ㄹ ㅎ
▶️
<Closure created at depth 0>
  • 놀라지 마시라! '<Closure created at depth 0>'는 에러 메시지가 아니라 함수 객체 하나가 만들어졌다는 뜻이다.
  • 'depth 0'은 코드 실행의 가장 꼭대기라는 뜻이다. C 언어라면 전역 변수를 선언하는 그 영역이다.
  • 위의 함수는 3 이라는 객체를 내놓는 함수이다.
    • 💡
      함수가 결괏값을 return 하는 것을 '반환하다' 등으로 표현하고 있으나, 평범한 한글에서는 '내놓는다'로 포현한다. 이 쪽이 훨씬 알아듣기 쉽다.
  • 다른 언어와는 달리, 평범한 한글에서 함수를 만들 때는 세 가지 없는 것이 있다.
      1. 함수 이름
      1. 필요한 인수의 개수
      1. 인수의 매개 변수 이름
 
  • 위의 함수를 호출해보자.
ㄹ ㅎ ㅎㄱ
▶️
3
  • 기본 함수를 호출할 때와 같이 ㅎ[인수의 개수] 꼴을 사용한다.
  • 평범한 한글은 함수를 만들 때가 아니라 호출할 때 인수의 개수를 표시한다.
  • ㄹ ㅎ은 3을 반환하는 함수이고 필요한 인수가 없으므로 ㄹ ㅎ ㅎㄱ 으로 호출하면 3을 반환한다.
  • 평범한 한글의 함수는 반드시 한 개의 객체를 내놓는다.
 
ㄴㄱ ㄹ ㅎ ㅎㄴ
▶️
3
  • ㄹ ㅎ 함수에 -1(ㄴㄱ)을 인수로 넘겨서 호출(ㅎㄴ)해도 상관이 없다. 어차피 ㄹ ㅎ 함수는 자신이 넘겨 받은 인수로 아무 일도 하지 않고 그냥 3을 내놓을 뿐이다.

한 개의 인수를 받는 함수

👉
목표: 받은 인수를 제곱하는 함수를 만들자.
  • 간단하게 시작하자. 숫자 3을 제곱하는 함수를 만들고 호출해보자.
ㄹ ㄷ ㅅㅎㄷ ㅎ ㅎㄱ
▶️
9
  • 위의 함수에 3을 인수로 전달해서 호출해보자.
ㄹ ㄹ ㄷ ㅅㅎㄷ ㅎ ㅎㄴ
▶️
9
  • ㄹ ㄷ ㅅㅎㄷ ㅎ 함수는 인수를 가지고 아무 일도 하지 않기 때문에 넘겨준 인수 3은 필요가 없다.
 
  • 평범한 한글에서 인수를 다루려면 을 사용한다. ('인수'라고 기억하자) 오~~ 드디어 의 쓰임을 알 수 있게 되었다~~~!
    • 함수에서 넘겨받은 인수로 어떤 일을 하기 위해서는 [인수 번호] ㅇ[함수 번호] 꼴을 사용한다.
    • 인수 번호첫 번째 인수가 0, 두 번째 인수가 1,... 처럼 증가한다.
    • 함수 번호기본적으로 0을 사용한다. 중첩된 함수를 사용할 때는 달라질 수 있다. ⇒ 함수가 받은 첫 번째 인수는 ㄱ ㅇㄱ, 두 번째 인수는 ㄴ ㅇㄱ,... 처럼 표현한다.
 
  • 첫 번째 인수를 제곱하는 함수는 다음처럼 만들고 호출할 수 있다.
ㄹ ㄱ ㅇㄱ ㄷ ㅅㅎㄷ ㅎ ㅎㄴ ㅁ ㄱ ㅇㄱ ㄷ ㅅㅎㄷ ㅎ ㅎㄴ ㄱㄴㄱ ㄱ ㅇㄱ ㄷ ㅅㅎㄷ ㅎ ㅎㄴ ㄱㅂㅈㄴㄱ ㄱ ㅇㄱ ㄷ ㅅㅎㄷ ㅎ ㅎㄴ
▶️
9 16 64 1000000
  • ㄱ ㅇㄱ 자리에 함수에서 넘겨받은 인수가 들어온다. ㄷ ㅅㅎㄷ ㅎ 함수의 부분을 ㄱ ㅇㄱ 으로 바꾸기만 한 것이다. 코드가 길다고 겁먹지 마시길!
  • ㄱ ㅇㄱ ㄷ ㅅㅎㄷ ㅎ 함수에 차례대로 3(), 4(), 8(ㄱㄴㄱ), 1000(ㄱㅂㅈㄴㄱ)를 인수로 넘겨서 호출(ㅎㄴ)하는 데 성공했다! 목표 달성!
 

두 개의 인수를 받는 함수

 
👉
목표: 첫 번째 인수와 두 번째 인수를 더하는 함수를 만들자.
  • 언제나 처음에는 간단하게 시작하자.
ㄹ ㅂ ㄹ ㅂ ㄷㅎㄷ ㅎ ㅎㄷ
▶️
8
  • 첫 번째 인수는 ㄱ ㅇㄱ으로, 두 번째 인수는 ㄴ ㅇㄱ으로 쓸 수 있다.
ㄹ ㅂ ㄱ ㅇㄱ ㄴ ㅇㄱ ㄷㅎㄷ ㅎ ㅎㄷ
▶️
8
  • ㄱ ㅇㄱㄴ ㅇㄱ을 한 덩어리로 생각하면 함수를 이해하기가 훨씬 쉽다.
  • 방금 만든 함수를 이용해서 여러 가지 수를 더해 보자.
기나긴 카누 그에게 낚이고 타협도 흔했다. 가가멜 스머프 그에게 낚이고 타협도 흔했다. 톰과 제리 그에게 낚이고 타협도 흔했다. 사과 배 그에게 낚이고 타협도 흔했다. 별나라 공주들 그에게 낚이고 타협도 흔했다. 반팔티 청바지 그에게 낚이고 타협도 흔했다. 슬리퍼 반바지 그에게 낚이고 타협도 흔했다. 태정태세 문단세 그에게 낚이고 타협도 흔했다.
▶️
0 614 -33 -1 389 668 843 -2854
💡
모든 은 그 앞에 공백이 있는 것과 없는 것을 동일하게 본다. 평범한 한글로 작문을 할 때는 위의 특성을 꼭 기억해 두자.
 
  • 실행 환경을 초기화했을 때 나오는 명 문장! 날마다 날마다 늘어간 기억과 더하던 후회다
  • 이 문장은 왜 322를 결괏값으로 내놓을까?
  • 문장을 구성하는 글자들을 평범한 한글의 기본 조각으로 만들어 보자.
ㄴㅁㄷ ㄴㅁㄷ ㄴㅇㄱ ㄱㅇㄱ ㄷㅎㄷ ㅎㅎㄷ
▶️
322
  • 위의 코드는 두 번째와 첫 번째 인수를 더하는 함수에 ㄴㅁㄷ (161)을 두 번 인수로 넘겨준다. 이 멋진 명 문장도 이제 우리는 해석할 수 있게 되었다.

함수를 인수로 전달하기

  • 평범한 한글은 함수형 언어이다. 그래서 함수는 일급 객체로 취급한다.
  • 모든 객체는 함수에 인수로 전달할 수 있다.
  • 함수도 다른 함수에 인수로 전달할 수 있다.
  • 함수 본체를 건드리지 않고 전달하는 인수에 따라서 다르게 행동하도록 만들 수 있다.
 
ㄱㅇㄱ ㄴㅇㄱ ㄷㅎㄷ ㅎ ㄹ ㅂ ㄱㅇㄱ ㅎㄷ ㅎ ㅎㄴ
▶️
8
  • 첫 번째 줄은 첫 번째 인수(ㄱㅇㄱ)와 두 번째 인수(ㄴㅇㄱ)를 더하는(ㄷㅎㄷ) 함수()이다.
  • 두 번째 줄은 3()과 5()를 첫 번째 인수(ㄱㅇㄱ)로 넘어온 함수에 넘겨서 호출(ㅎㄷ)하는 함수()이다. 이 함수를 호출(ㅎㄴ)하면 첫 번째 줄의 함수(ㄱㅇㄱ ㄴㅇㄱ ㄷㅎㄷ ㅎ)에 3과 5를 넘겨서 호출한다.
  • 이를 이용하면 두 번째 줄을 바꾸지 않고 첫 번째 줄의 함수만 바꾸어서 다른 행동을 할 수 있다.
 
ㄱㅇㄱ ㄴㅇㄱ ㄱㅎㄷ ㅎ ㄹ ㅂ ㄱㅇㄱ ㅎㄷ ㅎ ㅎㄴ ㄱㅇㄱ ㄴㅇㄱ ㅅㅎㄷ ㅎ ㄹ ㅂ ㄱㅇㄱ ㅎㄷ ㅎ ㅎㄴ ㄱㅇㄱ ㄴㅇㄱ ㄴㄱ ㄱㅎㄷ ㄷㅎㄷ ㅎ ㄹ ㅂ ㄱㅇㄱ ㅎㄷ ㅎ ㅎㄴ
▶️
15 243 -2
  • 세 토막의 코드는 각각 첫 번째 줄의 함수 를 인수로 받아서 3과 5의 인수를 전달해서 호출한다.
  • 첫 번째 토막은 첫 번째와 두 번째 인수를 곱하는 함수이다. 3과 5를 곱하면 결과는 15.
  • 두 번째 토막은 첫 번째 인수를 두 번째 인수로 거듭제곱하는 함수이다. 3의 5제곱은 243.
  • 세 번째 토막은 첫 번째 인수 를 두 번째 인수로 빼준다. 3에서 5를 빼면 -2.
 
  • '평범한 한글'은 함수형 언어이다. 그래서 함수는 평범한 한글에서 굉장히 중요한 객체이다.
  • 처음에는 평범한 한글의 함수가 굉장히 낯설어보이겠지만 코드를 여러 번 짜다 보면 익숙해질 수 있다.
 

'평범한 한글'도 코드?

  • 실행 환경에 평범한 한글을 입력하면 놀랍게도 실행이 된다!
평범한 한글
▶️
-45
  • 위의 코드가 왜 -45인지 살펴보려면 중성과 종성을 제거하고, 예사소리로 바꾸면 된다.
ㅂㅂ ㅎ ㅎㄱ
  • ㅂㅂ는 10진수로 변환하면 -45이다. 결국 평범한 한글-45를 내놓는 함수를 호출하는 코드였다.
 
💡
함수와 클로저(closures) '평범한 한글'의 함수는 이름이 없다. 다른 언어에서는 이와 같이 이름이 없는 함수를 '클로저', '람다', '블록'처럼 다양한 이름으로 부르고 있다. 평범한 한글의 기본 함수는 편이상 정수 리터럴을 함수의 이름처럼 할당해서 호출하고 있다. ㄹ ㅂ ㄷ ㅎㄷ에서 은 3이고, 결과적으로 ㄷ ㅎㄷ 는 3을 초훌하는 것이다. 마찬가지로 곱하기는 0()을 호출하는 것이다. 결과적으로 평범한 한글의 모든 함수는 이름이 없다고 생각하면 된다. 그렇다면 다른 언어들에서처럼 함수를 만들고 나중에 반복해서 사용할 수 있을까? 물론 가능하다. 단지 함수의 이름을 호출하는 것이 아니라, 함수를 다른 함수에 인수로 전달하여 ㄱ ㅇㄱ이나 ㄴ ㅇㄱ 처럼 인수로 호출하면 된다.