function add(a, b) {
return a + b;
}
console.log(add(1, 2));
함수는 일련의 과정을 문으로 구현하고 코드블록 {}
로 감싸서 하나의 실행 단위로 정의한 것을 의미한다.
매개변수(parameter)
argument
)return value
) 라고 한다.
위의 예시에서는 a,b
는 매개변수 , a+b
는 반환값 , add(1,2)
에 쓰인 1,2
는 인수
에 해당한다.
함수는 정의를 통해 생성한다.
위에서 a,b
매개 변수를 더하여 a+b
값을 반환하도록 하는 함수를 function add
로 선언하였다.
함수는 선언하기만 해서 실행 되는 것이 아닌
함수를 호출하여 반환값을 받을 수 있다.
add(1,2)
를 통해 함수호출
을 하였다.
함수는 코드의 재사용 측면에서 매우 유용하다.
또한 동일한 코드 반복을 함수를 통해 재사용 하게 되면
코드의 유지 보수의 편의성을 높이고 코드의 신뢰성을 높이는 효과가 존재한다.
함수선언 시 함수의 이름을 적절히 내부 코드를 대표할 수 있도록 잘 선언해야 코드의 가독성
을 높일 수 있다.
자바스크립트의 함수는 객체 타입의 값이다. 그렇기 때문에 변수에 할당하듯 (리터럴) 함수 또한 함수 리터럴로 생성할 수 있다.
계속 헷갈린다
리터럴
은 값을 생성하기 위한 표기법으로 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법
var f = function add(a, b) {
return a + b;
};
console.log(f); // [function : add]
console.log(f(1, 2)); // 3
함수를 f
라는 리터럴로 생성하였다.
함수 리터럴의 구성 요소
함수 이름
var f = function (a, b) {
return a + b;
};
console.log(f); // [Function: add]
console.log(f(1, 2)); // 3
이름이 있는 함수를 기명함수
, 이름이 없는 함수를 무명함수
라고 한다.
매개 변수 목록
함수 몸체
{}
함수는 객체
이면서 일반 객체는 호출할 수 없지만 함수는 호출 할 수 있다는 차이점이 있다.
var a;
function hi() {
console.log('whats up');
}
a; // 아무일도 일어나지 않음
hi(); // whats up
함수 정의란 함수를 호출하기 이전에 인수를 전달받을 매개변수와 실행할 문, 반환할 값을 지정하는 방법을 의미한다.
정의 방식은 4가지가 존재한다.
function add(a,b){
return a+b
}
함수 선언문은 함수 리터럴과 형태가 동일하지만 _함수 리터럴은 함수 이름을 생략 할 수 있지만 함수 선언문은 함수 이름을 생략 할 수 없다. (위 예제에선 add
라는 이름을 설정하지 않으면 오류가 발생한다.)
함수 리터럴
var f = function(a,b){ return a+b; }
그 이유는 함수 선언문은 표현식이 아닌 문이기 때문이다.
넹 그게 무슨 말이죠 ?
표현식 vs 문
함수 선언문
은 말 그대로문
이다. 함수 선언문은 호이스팅에 영향을 받아 선언된 위치에서 코드가 실행되기 이전으로 끌어 올려진다.console.log(add(1, 2)); // 3 function add(a, b) { return a + b; }
add
함수는 호이스팅 되어 오류가 없이 실행이 가능하다.
함수 선언문은 호이스팅 될 객체 이름을 지정해주지 않으면 호이스팅이 되지 않는다.function(a, b) { return a + b; // SyntaxError: Function statements require a function name }
함수 표현식
은 이름이 없는무명 함수
나 이름이 있는기명 함수
를 함수 리터럴에 할당하는 것을 의미한다.var f = function (a, b) { return a + b; };
어차피 리터럴로 표현되기 때문에 함수에 이름이 있고 없고는 크게 상관이 없다.
다만 함수 리터럴은 함수 선언문에 비해서 호이스팅이 되지 않는다.
console.log(myFunction()); // 정상 동작
function myFunction() {
return "Hello, world!";
}
이건 오류가 안나고
console.log(myVariable); // undefined
var myVariable = "Hello, world!";
이거 오류가 난다. (엄밀히 말하면 오류는 아니고 할당이 안됐다.)
둘 다 호이스팅 된거긴 한데 어떤 차이일까?
함수
는 선언된다. function myFunction() {}
이 부분에서 myfunction
이란 객체에 {}
내부의 동작이 선언되어 호이스팅 된다.
객체
는 선언되고 할당된다. myvariable
이란 객체는 호이스팅 되어 undefined
가 나온다. 이후 console.log
문 이후에 Hello.wolrd
라는 문구가 선언이 된다.
함수는 호이스팅 될 때 코드 블록이 선언되고, 함수가 아닌 객체는 호이스팅 될 때 undefined
만 선언된다.
var add = function (a, b) {
return a + b;
};
함수 표현식
은 함수 선언문을 객체처럼 취급해 할당하는 것 처럼 보인다.
함수 표현식
에서 함수를 설정 할 때에는 함수의 이름을 무기명으로 해도 되고 유기명으로 해도 된다.
아니 ! 함수 선언문에서는 함수의 이름을 꼭 선언해야 하고 함수 표현식에서는 함수이름을 선언하지 않아도 되는 이유는 뭘까 ?
또 , 함수 선언문에서는 함수는 표현식이 아닌 문이기 때문에 객체에 할당 할 수 없다고 했는데 이 때는 된다.
왜지 ?
함수를 선언 할 때를 보면 function
으로 함수를 선언하고 , 이후 함수의 이름을 설정하고 , 매개 변수 설정, 함수 몸체와 그 안에 반환값을 설정한다.
자바스크립트 엔진이 함수를 설정하는 소스코드를 읽을 때 function
을 만나면 함수 몸체를 참조 할 임의의 객체를 생성한다.
이 때 함수의 이름이 설정되었을 때에는 이전에 설정한 임의의 객체(현재 함수 몸체를 가리키고 있는)를 함수의 이름으로 설정한다.
그리고 순서대로 함수 몸체와 설정된 반환값을 임의의 객체가 가리키고 있게 한다.
만약 함수의 이름을 설정하지 않았을 때는 임의의 객체가 함수 몸체를 가리키고 있지만, 우리는 그 임의의 객체에 접근 할 방법이 없다.
그래서 !
함수를 내가 객체에 할당 시키지 않는 함수 선언문의 경우에는 임의의 객체를 사용자가 접근 할 수 있도록 이름을 설정해줘야 한다. 그래서 함수 선언문에서는 함수의 이름을 필수적으로 사용해야 한다.
function (a, b) {
return a + b;
} // SyntaxError: Function statements require a function name
하지만 함수 표현식에서는 이름이 없어도 되는 이유는, 자바스크립트 엔진에서 만든 임의의 객체를 함수에 할당해주기 때문에 함수의 이름을 작성하지 않아도 된다.
var f = function add(a, b) {
return a + b;
};
console.log(f(1, 2)); // 3
console.log(add(1, 2)); // ReferenceError: add is not defined
위 코드에서는 f
라는 객체는 함수 이름이 add
인 객체를 가리키고 있다.
위에서 설명했던 내용인 함수의 이름은 함수 몸체 내에서만 참조 할 수 있는 식별자라고 하였기 때문에
함수 이름이 add
라고 하더라도 함수 몸체 밖에서는 add
를 찾을 수 없다.
왜냐면 함수의 몸체는 add
가 아닌 f
가 가리키고 있으니까 말이다.
자바스크립트 엔진은 함수선언문과 함수 리터럴을 어떻게 구분할까 ?
자바스크립트는 함수를 설정한 소스 코드가 피연산자로서 사용되었는지를 통해 함수가 객체로서 설정되었는지, 아니면 선언문으로 설정되었는지를 확인한다.
함수 선언문의 경우엔=
연산자가 존재하지 않기 때문에 함수 선언문임을 판단하고 함수 이름으로 객체를 설정한다.
함수 표현식의 경우엔 할당 연산자인=
가 들어갔기 때문에 함수 표현식임을 판단하고 할당된 객체에 함수를 설정한다.
그러한 이유로 함수 선언문의 경우엔 연산자가 들어가면 함수 표현식으로 판단한다.그렇기 때문에 객체를 설정해줘야 한다.(function add(a, b) { return a + b; }); console.log(add(1, 2)); // ReferenceError: add is not defined
함수 선언문으로 설정하고
()
를 사용하였드니, 자바스크립트 엔진이 함수 표현식인줄 알고 임의의 객체의 이름을add
로 설정하지 않고 객체만 생성해두었다.
이는(function ... )
을 가리키고 있는 객체가 설정되지 않았기 때문에 실행이 되지 않느다.
그러한 이유로 함수 표현식의 호이스팅은 변수 호이스팅과 같다.
함수 선언문의 경우엔 할당 될 때
function
으로 생성된 임의의 객체를 함수 이름으로 설정해두는 것이 호이스팅 되지만
함수 표현식의 경우엔 임의의 객체를 생성하기만 하지, 함수를 객체에 할당하는 선언 과정은 호이스팅 되지 않는다.
ES6에서는 함수선언은 함수 실행 이전에 정의 되어야하기 때문에 함수 선언문보다 함수 표현식을 지향해야 한다고 말했다.
var add = new Function('a', 'b', 'return a + b');
var add = (x, y) => x + y;
ES6 에서 도입된 화살표 함수는 function 키워드 대신 화살표 (fat arrow)를 사용해 좀 더 간략한 방법으로 함수르 선언 할 수 있다.
화살표 함수는 항상 익명 함수로 정의한다.
함수를 호출 할 때에는 함수 명 (혹은 할당 받은 객체 명) 과 소괄호, 그리고 소괄호 안에 매개변수를 통해 인수를 전달한다.
인수는 값으로 평가 될 수 있는 표현식이어야 한다.
매개변수는 함수 몸체 내부에서는 변수와 동일하게 취급된다.
매개변수에 인자를 설정해주면, 함수 몸체 내에서 암묵적으로 매개 변수를 undefined 로 초기화 하고, 인자를 통해 매개 변수에 받은 인자를 할당한다.
매개 변수는 함수 몸체 내부에서만 참조할 수 있고 함수 몸체 외부에서는 참조할 수 없다.
자바스크립트엔진은 매개변수 개수와 인수의 개수가 일치하는지 체크하지 않는다.
일반적으로는 매개변수 개수와 인수의 개수가 동일해야 하겠지만
function add(a, b, c) {
return a + b + c;
}
console.log(add(1, 2)); // NaN
매개변수 수보다 적은 인수를 넣어도 오류가 나지 않고 함수가 실행된다.
그 이유는 인수를 전달받지 못한 매개변수 c
는 undefined
로 선언 되어 있기 때문이다.
수와 undefined 를 더하려고 하니 NaN값이 return 된다.
반대로 인수의 개수가 더 많다면 ?
function add(a, b, c) {
return a + b + c;
}
console.log(add(1, 2, 3, 4)); // 6
인수의 개수가 더 많을 때에는 매개 변수 수보다 많은 인수를 무시하고 함수 몸체 내부의 코드를 실행한다.
function add(a, b) {
return a + b;
}
console.log(add(1, 2)); // 3
console.log(add('h', 'i')); // hi
console.log(add('h', 1)); //h1
위 코드는 수를 더해주는 코드처럼 보이지만 문자열이 들어와도 더하기 연산을 시행한다.
그 이유는 자바스크립트 엔진은 암묵적 타입 변환을 통해 들어온 매개 변수의 타입을 변경하기도 하고
가장 근본적으로 자바스크립트는 변수의 타입을 미리 설정해두지 않기 때문이다.
이를 해결하기 위해 함수 몸체 내부에 조건문을 달거나 단축 평가를 통해 조절해야 한다.
매개 변수의 개수는 자바스크립트에서 엄격하게 제한하고 있지는 않지만
함수의 매개변수는 코드를 이해하는데 방해되는 요소이므로 이상적인 매개 변수 개수는 0개이며 적을 수록 좋다.
이상적인 함수는 한가지 일만 해야 하며 가급적 작을 수록 좋다.
그렇기 때문에 함수 내부에 매개 변수를 다양하게 넣어야 한다면, 객체를 인수로 받아 사용하도록 하자.
객체를 인수로 받게 되면 객체 내부의 프로퍼티 키값만 엄격히 설정 잘 되어 있고 함수 몸체 내부에서 프로퍼티 키를 유용하게 사용한다면 가독성 측면에서 좋다.
반환문은 꼭 값으로 표현되는 표현식을 사용해야 한다.
만약 반환문에 표현식을 사용하지 않을 경우엔 undefined
가 설정되며
반환문과 표현식 사이에 줄바꿈이 있으면 세미클론 자동 삽입 기능으로 인해 의도치 않은 결과가 발생한다.
function add(a, b) {
return;
a + b;
}
console.log(add(1, 2)); // undefined
위에서 매개변수의 수가 많을 때에는 객체로 전달하는 것이 가독성에 좋다고 했다.
하지만 이는 치명적인 단점이 존재하는데
함수 몸체 내부에서 진행된 변경 사항이 인수로 제공한 객체에도 적용된다는 점이다.
객체를 할당 받을 때에는 객체의 값을 참조하는 것이 아닌, 객체가 가리키고 있는 주소를 참조한다고 했다.
function changeValue(obj) {
obj['name'] = 'lee';
}
var value = { name: 'kim' };
changeValue(value);
console.log(value); // { name: 'lee' }
이런 문제를 원천 봉쇄 하기 위해서는 원객체의 방어적 복사를 통해 깊은 복사등을 이용, 새로운 객체를 생성하고 재할당을 통해 교체 해야한다.
함수의 정의와 동시에 즉시 호출되는 함수를 즉시 실행 함수 (IIFE (Immediately Invoked Function Expression)
) 이라고 한다.
즉시 실행 함수는 단 한번만 호출되며 다시 호출 할 수 없다.
(function () {
console.log('hello');
})();
이렇게 사용한다.
함수 선언을 ()
로 먼저 감싸줌으로 인해 함수 선언문이 아닌 함수 표현식임을 자바스크립트 엔진에게 알린다.
그러면 (function ... )
으로 생성된 함수 리터럴을 ()
밖에 존재하는 ()
를 통해 호출할 수 있다.
재사용이 불가능한 이유는 생성된 함수 리터럴을 가리키고 있는 객체가 존재하지 않기 때문이다.
익명 함수로 설정하는 이유는 함수 리터럴에서는 함수의 이름이 의미가 없기 때문이다.
(function sayHello() {
console.log('hello');
})();
sayHello(); // ReferenceError: sayHello is not defined
즉시 실행 함수도 매개변수를 설정하고, 반환 하는 것이 가능하다.
console.log(
(function add(a, b) {
return a + b;
})(1, 2)
); // 3
재귀 함수는 자기 자신을 호출하는 함수를 의미한다.
예를 들어 팩토리얼의 경우를 생각해보자
팩토리얼은 수와 !로 표기하며 이 있을 때 값을 의미한다.
function factorial(n) {
if (n === 1) {
return 1;
}
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
다음처럼 시행한다.
n이 도달하면 1을 반환하고 n이 2이상일 경우엔 n * factorial(n-1) 을 반환한다.
이렇게 재귀함수는 재귀를 중단하는 탈출 조건을 설정해줘야 한다.
함수는 함수가 호출되면 함수 콜 스택에 함수가 들어가며, 반환값이 return 되는 순간 콜 스택에서 제거된다.
위 코드를 시행하면 함수 콜스택의 변화가 어떻게 되는지 확인해보자
초기 호출:
factorial(5) 호출
현재 스택: factorial(5)
첫 번째 재귀 호출 [factorial(5)]
factorial(5)에서 return 5 * factorial(4) 호출
factorial(4) 호출
현재 스택: factorial(5) -> factorial(4)
두 번째 재귀 호출
factorial(4)에서 return 4 * factorial(3) 호출
factorial(3) 호출
현재 스택: factorial(5) -> factorial(4) -> factorial(3)
세 번째 재귀 호출:
factorial(3)에서 return 3 * factorial(2) 호출
factorial(2) 호출
현재 스택: factorial(5) -> factorial(4) -> factorial(3) -> factorial(2)
네 번째 재귀 호출:
factorial(2)에서 return 2 * factorial(1) 호출
factorial(1) 호출
현재 스택: factorial(5) -> factorial(4) -> factorial(3) -> factorial(2) -> factorial(1)
나머지 호출들이 순차적으로 종료되고 값을 반환하며 스택에서 제거된다.
최종적으로 스택이 완전히 비워진다.
만일 중단 지점을 정해주지 않으면 콜스택에 무수한 재귀 함수들이 쌓이고, 콜스택의 용량보다 많은 재귀 함수들이 쌓이면 스택이 터지는 stack overflow
가 발생한다.
// 중단 지점을 설정하지 않은 재귀함수 코드
function factorial(n) {
return n * factorial(n - 1);
}
console.log(factorial(5)); // RangeError: Maximum call stack size exceeded
중첩 함수는 함수 내부에 정의된 함수를 의미한다.
다른 말로 내부 함수라고 정의하기도 한다. 이 때 내부 함수 밖에 존재하는 함수를 외부 함수라 부른다.
중첩 함수는 외부 함수의 내부에서만 호출 할 수 있으며 일반적으로 중첩 함수는 자신을 포함하는 외부 함수를 돕는 헬퍼 함수 역할을 한다.
function sumAndMultiply(a, b, c) {
function sum(x, y) {
return x + y;
}
function multiply(x, y) {
return x * y;
}
return multiply(sum(a, b), c);
}
console.log(sumAndMultiply(1, 2, 3));
하지만 함수 선언을 함수 내부에서 하는 경우엔 단점이 존재한다.
외부 함수를 시행 할 때 마다 함수를 선언해야 하기 때문에 속도가 오래 걸린다?
내 생각엔 이럴줄 알았는데 아니라고 한다.
자바스크립트 엔진은 함수가 선언되는 시점, 선언된 함수는 일반적으로 메모리에 캐시되어 재사용되며, 컴파일 하는 단계에서 자동으로 최적화 해주기 때문에 괜찮다고 한다.
function sum(x, y) {
return x + y;
}
function multiply(x, y) {
return x * y;
}
function sumAndMultiply(a, b, c) {
return multiply(sum(a, b), c);
}
console.log(sumAndMultiply(1, 2, 3));
다음처럼 내부 함수를 외부함수로 선언해준 후 사용하는 것이 바람직하다.
벨로그의 자바스크립트와 관련된 글을 읽다보면 콜백 함수를 자주 접할 수 있었는데
그게 뭔가 했드니 이번 기회에 배울 수 있었다.
내가 만약 어떤 수 n 이 주어졌을 때 n부터 1까지 프린트 하는 함수를 만들고 싶다고 해보자
그런데 홀수 일 때만 프린트 하는 함수도 같이 곁들인 ..
function printAll(n) {
for (let i = n; i > 0; i--) {
console.log(i);
}
}
function printOdds(n) {
for (let i = n; i > 0; i--) {
if (i % 2) console.log(i);
}
}
printAll(5); // 5 4 3 2 1
printOdds(5); // 5 3 1
두 함수 모드 n 부터 1까지 반복한다라는 공통점을 가지고 있으나 반복문 내부의 실행 방식이 다르다.
이는 공통점이 있음에도 불구하고 함수의 일부분만 다르기 때문에 매번 함수를 새롭게 정의해야 한다.
이 문제는 공통 로직은 미리 정의해두고 경우에 따라 변경되는 로직은 추상화
해서 함수 외부에서 함수 내부로 전달 하는 것이다.
function logAll(x) {
console.log(x);
}
function logOdds(x) {
if (x % 2) console.log(x);
}
function repeat(n, f) {
for (let i = n; i > 0; i--) {
f(i);
}
}
// 모두를 log 시키는 logAll 함수를 인자로 설정
repeat(5, logAll); // 5 4 3 2 1
// 홀수만 log 시키는 logOdds 함수를 인자로 설정
repeat(5, logOdds); // 5 3 1
repeat
를 선언 할 때 매개 변수 f
에는 함수를 인자로 받도록 해두고 함수 내부에선 인자로 받은 f
를 실행 시키게 하였다.
이후 조건에 따른 함수들을 logAll , logOdds
로 둬서 인자로 넘겨주었다.
이처럼 함수의 매개변수를 통해 다른 함수 내부의 인자로 전달 되는 함수를 콜백 함수 (callback function
) 이라고 하며, 매개 변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수를 고차 함수 (Higher-Order Function , HOF
) 라고 한다.
고차함수는 인자로 받은 콜백 함수를 자신의 일부분으로 실행 될 때 마다 합성한다.
정리하자면, 콜백 함수는 고차 함수에 의해 호출되며 고차함수는 필요에 따라 콜백함수에 인자를 전달 할 수 있다.
만약 콜백 함수가 고차 함수 내부에만 호출되면 콜백 함수를 익명 함수 리터럴로 정의하면서 고차로 고차 함수에 전달 하는 것이 일반적이다.
(콜백 함수가 외부에서 사용되거나 재사용되지 않는 경우엔 선언해둘 필요가 없다.)
repeat(5, function (i) {
if (i % 2) {
console.log(i);
}
});
다음처럼 익명 함수 표현식으로 logOdds
에 굳이 할당 안시키고 한 번만 사용 할것이라면 고차함수 호출 시 콜백 함수를 선언하여 사용 하는 것이 일반적이다.
function(i) {...}
는 () 안에 존재하기 때문에 함수 표현식으로 자바스크립트 엔진이 해석, 함수 리터럴로 만들기 때문에 인자로 줄 수 있다.
콜백 함수는 비동기 처리에 활용되는 중요한 패턴이다.
예 ? 나중에 더 배우겠지
document.getElementById('myButton').addEventListener('click', function () { console.log('button cliked!'); });
다음처럼 id
가 myButton
이 클릭 되었을 때 버튼이 클릭되었다는 문구를 로그 하는 익명 함수 리터럴을 인자로 주는 듯 말이다.
배열 고차 함수에도 유용하게 사용된다.
// map
var res = [1, 2, 3].map(function (item) {
return item * 2;
});
console.log(res); // [2,4,6]
// filter
var res = [1, 2, 3].filter(function (item) {
return item % 2;
});
console.log(res); // 1,3
// reduce
var res = [1, 2, 3].reduce(function (acc, curr) {
return acc + curr;
});
console.log(res); // 6
이후 다른 챕터에서 깊게 배우겠지만 배열에다가 다양한 기능을 하는 익명 함수 리터럴을 이용해서 원하는 배열을 설정 할 수 있다.
reduce 는 누적합을 구하는 함수로 acc (누적합) 과 curr (배열의 현재값) 을 계속 더해주어 누적한 값을 구하는 함수이다.
함수형 프로그래밍에서는 어떤 외부상태에 의존하지도 않고 변경하지도 않는, 부수효과가 존재하지 않는 함수를 순수 함수 (pure function
) 라 하고, 외부 상태에 의존학거나 외부 상태를 변경하는, 즉 부수효과가 있는 함수를 비순수 함수 (impure function
)이라 한다.
var count = 3;
function decrease(n) {
return --n;
}
decrease(count);
console.log(count); // 3
count = decrease(count);
console.log(count); // 2
다음처럼 decrease
는 n
이란 매개 변수에 인자를 전달 받아 함수 내부에서 매개 변수의 값을 변경하여 할당 후 반환한다.
이러한 행위는 반환한 객체를 지정해주지 않으면 전달 했던 인자의 값엔 변화가 없고 , 인자의 값을 변화 시키기 위해선 순수 함수의 반환 값을 인자에 재할당 해줘야 한다.
순수 함수는 매개 변수를 1개 이상 받아야 한다. 만약 매개변수를 받지 않은 순수 함수는 항상 같은 값을 return 하기 때문에 상수와 다름 없다.
var count = 3;
function decrease() {
return --count;
}
decrease();
console.log(count);
비순수 함수는 매개 변수를 설정하지도, 인수를 전달받지도 않고 함수 외부에 존재하는 변수에 접근하여 함수 외부의 값을 변경하는 모습을 볼 수 있다.
함수가 외부 상태를 변경하면 상태 변화를 추적하기 어렵기 때문에 변경을 지양하는 순수 함수를 사용하도록 하자
함수형 프로그래밍이란 순수함수와 보조함수의 조합을 통해 외부 상태를 변경하는 부수 효과를 최소화 해서
객체의 값이 변화를 최소화 하는, 불변성을 지향하는 프로그래밍 패러다임이다.
로직 내에 존재하는 조건문과 반복문을 제거해서 복잡성을 해결하며, 변수 사용을 억제하거나 생명 주기를 최소화 하여 상태 변경을 피해 오류를 최소화하는 것을 목표로 한다.
자바스크립트는 멀티 패러다임 언어이므로 객체 지향 프로그래밍뿐만 아니라 함수형 프로그래밍을 적극적으로 활용하고 있다.