[ Essay - Technology ] 바이브 코딩의 허와 실

이미지
지금 우리는 가히 AI 시대라는 패러다임의 전환에 시대에 살고 있다고 해도 과언이 아니다. 특히, IT 업계에서 대다수의 작업량을 차지하는 프로그래밍의 영역에서 생성 AI를 이용한 생산성 향상의 가능성이 보이면서 어느 분야보다 가장 빠르게 괄목적인 성과를 이루고 있는듯 하다. 고작 몇 년전에는 커서에 의해 프로그래밍을 AI에게 프로그래밍을 위임하는 것이 더 나을 수 있다는 것이 어느정도 증명되면서, 작년에는 Claude Code의 영향으로 인해 이러한 이슈가 좀 더 가속화되지 않았나 싶다. 이러한 굉장히 빠르게 이루어지고 있는 생성형 AI 솔루션의 발달은 개발자의 종말론을 더더욱 부각시키면서 업계 전반이 큰 변화를 겪고 있는 것으로 보인다. 특히 이러한 변화 속에서 “프로그래밍을 몰라도 생성형 AI만 있으면 제품을 만들 수 있다”는  주장도 자연스럽게 힘을 얻고 있다. 최근에는 Saas 솔루션은 종말할 것이라는 다소 파격적인 이야기도 들리는 것으로 보면 소프트웨어 업계가 큰 격변의 시기가 온것임에는 틀림 없어 보인다. 허(虛): 빠르게 만들 수 있다는 환상 이런 상황에서 가장 주목받는 주장들은 서론에서 언급했다시피 ‘프로그래밍을 알지 못한다고 하더라도  생성형AI를 이용하면 빠르게 제품을 개발이 가능하다’라는 주장이고, 실제로 이는 어느 정도 타당성이 있어 보인다. 정말로 움직이는 결과물을 단 몇초 만에 보여주기 때문이다. 하지만, 이러한 ‘빠르게 제품 개발 가능하다’는 주장의 가장 큰 맹점이 있는데 개발자의 존재 이유가 단순한 제품이나 기능개발에 있지 않다는 점이다. 만약, AI를 통해 그럴듯 한 솔루션을 만들었다고 치자. 이것에 얼마만큼의 비지니스성과 지속가능성이 있을까? 예컨대 AI에게 넷플릭스나 트위터, 인스타그램과 같은 페이지를 만들어달라고 요청한다면, 아마 실제로 그럴듯 하게 만들어 줄 것 이다. 이러한 인기 서비스들은 토이 프로젝트로 다루기 쉽고, 하나의 트렌드로 자리 잡아 관련 자료를 찾기도 어렵지 않다. 코드 또한 깃허브에 충분...

[ React, JavaScript ] 함수형 컴포넌트 정의에 대해: function 정의, const 정의(Arrow Function)



서론


React에서 컴포넌트를 새로 작성한다고 가정해보자.

이 때 가장 먼저해야 하는 것은 
어떤 형식으로든 메인 함수를 정의하는 것 부터 시작할 것 이며

이와 동시에 하단에 이를 export 할 때, 
디폴트로 설정한다는 코드를 작성하게 될 것이다.

아래와 같이 말이다.

function NewComponet(){
  return <div>null</div>;
}

export default NewComponet;

나는 React를 배울 때, 
위와 같은 방식으로 배웠기 때문에 항상 위와 같은 방식을 선호 했다.

하지만, 개발자라면 모두 느끼고 있듯이
코딩 스타일이라는 것이 일부 다를 수 있다는 것을 가장 잘 알 것이다.

가장 대표적으로 중괄호를 어떻게 쓰느냐를 예를 들 수 있다.

function NewComponet()
{
  return <div>null</div>;
}

export default NewComponet;
중괄호 스타일 1

function NewComponet(){
  return <div>null</div>;
}

export default NewComponet;
중괄호 스타일 2

재미있게도 나는 실무를 하면서 이런 선언 방식이 
사람에 따라 두 가지 방식으로 정의하는 것을 발견했다.

정의 방법은 아래와 같다.

첫 번째, function 정의 
두 번째, const 정의

무엇이 다를까 매우 흥미롭다.

이번에는 이 두 가지 정의 방법에 대해 알아보고
이에 대한 차이점에 대해 
그리고 이런 정의 방법에 따라 퍼포먼스 문제를 
야기 할 수 있는지에 대해 이야기를 나누어 보자.

함수형 컴포넌트 정의에 대해 : 정의 예


먼저 이 두 가지 방법을 한눈에 보기 위해 
두 가지 정의 코드를 먼저 살펴보자.

function NewComponet(){
  return <div>null</div>;
}

export default NewComponet;
function에 의한 정의


const NewComponet = () => {
  return <div>null</div>;
}

export default NewComponet;
const에 의한 정의

눈으로 볼 때, 
이 두 가지 정의 방법의 차이는 
앞에 붙는 명령어와 화살표(Arrow)가 들어가 있느냐의 차이로 보인다.

여기까지는 매우 명쾌하다.

이 두 가지 방법은 같은 코드를 작성 했다고 가정했을 때 
정확히 동일한 동작을 할까?

결론 부터 말하면, 
당연히 이 두 가지 정의 방법은 동일한 동작을 하지 않는다.

const 정의(Arrow Function): ES 6


먼저 const 에 의한 정의에 대한 이야기 부터 시작해보자.

나는 앞의 명령어를 가져와서 
편하게 const에 의한 정의라고 말했지만,

사실 이를 나타내는 공식적인 단어가 있는데
화살표 함수(Arrow Function)라는 단어이다.

커뮤니케이션의 혼란을 야기 할 수 있기 때문에
이 후 부터는 화살표 함수나 Arrow Function으로 부르도록 하겠다.

어쨋든, 
이 화살표 함수는 ES6에서 추가된 정의 방식이다.

ES6은 ECMAScript 6의 약자로,
ECMAScript의 6번째 버전을 말한다.
2015년에 공개되었기 때문에 ECMAScript 2015라고도 알려져 있다.

여기서 ECMAScript란 웹 페이지에 대해 
서로 다른 브라우저 간의 호환성(상호 운영성,interoperability)을 
보장하기 위한 JavsScript 스탠다드를 말한다.

즉, React의 정의 방식이라고 말하기 보다는
모체가되는 JavaScript의 정의 방식,
더 정확히는 ES6에서 추가된 정의 방식이라고 보는 것이 정확하다.

이 화살표 함수는 아래와 같은 특징을 가진다.

const 정의(Arrow Function)의 특징 : this와 arguments의 구문(Lexical)


화살표 함수(Arrow Function)의 경우
자신만의 this와 arguments를 가지지 않으며,
화살표 함수 바깥의 상위 함수의 값을 가진다.

어찌 보면 정의된 상위 함수 내부의 this를 
전역화를 한다고 생각한다면 편할지도 모르겠다.

반대로 말하면
Function에 의한 정의의 경우
자신만의 this와 arguments를 가진다고 볼 수 있다.

예를 살펴보자.


var PrintNameDefArrow = function() {
  console.log("this.name value: ",this.name);
  return () => {
    name = "Change Name";
    return console.log("this.name value: ",this.name)
  }
}
PrintNameDefArrow.call({ name: 'Jonh Kim' })()
첫 번째 예: 화살표 함수에 의한 정의


var PrintNameDefFunc= function() {
  //var _this = this
  console.log("this.name value: ",this.name);
  return function () {
    name = "Change Name";
    return console.log("this.name value: ",this.name)
  }
}
PrintNameDefFunc.call({ name: 'John Kim' })()
두 번째 예: Function에 의한 정의

위의 예를 보고 천천히 생각해보자.
온라인 컴파일러에 코드를 돌리기전에 
가지고 있는 정보를 바탕으로 결과를 예측해보자.

화살표 함수는 자신만의 this와 arguments를 가지고 있지 않다를 잘 기억하고
다시 한번 살펴보자.


var PrintNameDefArrow = function() {
  console.log("this.name value: ",this.name);
  return () => {
    name = "Change Name";
    return console.log("this.name value: ",this.name)
  }
}
PrintNameDefArrow.call({ name: 'Jonh Kim' })()
첫 번째 예: 화살표 함수에 의한 정의

화살표 함수는 자신의 this와 arguments를 가지지 않기 때문에 
화살표 함수 내부에서 name의 값을 변경하려고 해도 값이 변경되지 않을 것이다.

즉, 콘솔에는 Jonh Kim이 출력될 수 밖에 없다.

두 번째 예로 넘어가 보자.

Function에 의한 정의는 자신만의 this와 arguments를 가지는 것을 잘 기억하고
아래의 예를 다시 한번 살펴보자.

var PrintNameDefFunc= function() {
  console.log("this.name value: ",this.name);
  return function () {
    name = "Change Name";
    return console.log("this.name value: ",this.name)
  }
}
PrintNameDefFunc.call({ name: 'John Kim' })()
두 번째 예: Function에 의한 정의

Function에 의한 정의는 자신만의 this와 arguments를 가지기 때문에
function 내부의 값이 Change Name으로 새롭게 정의 될 것이다.

즉, Chnage Name이 출력 된다.

첫 번째 예와 두 번째 예를 동시에 컴퍼일러에서 돌리면 
아래와 같은 결과가 나온다.


여기서 한 가지 의문점이 생길 수 있다.

Function에 의한 정의 

이 경우 상위 함수 내부에 this를 담는 변수를 생성하고,
이를 통해 조작 하면 된다.

예는 아래와 같다.

var PrintNameDefFunc= function() {
  var _this = this;
  console.log("this.name value: ",this.name);
  return function () {
    name = "Change Name";
    return console.log("this.name value: ",_this.name)
  }
}
PrintNameDefFunc.call({ name: 'John Kim' })()

이에 대한 결과는 아래와 같다.




.

const 정의(Arrow Function)의 특징 : new 키워드를 통한 객체 생성 불가


var Foo1 = function(){
  console.log("Foo1 function");
}

var Foo = () => {
  console.log("Foo function");
};

var foo1 = new Foo1();
var foo = new Foo();

화살표 함수의 경우,
new 키워드를 사용 할 수 없기 때문에
위의 코드를 실행 하면 Foo1은 객체가 정상적으로 foo1에 들어가는 반면
Foo는 foo에 저장할 수 없기 때문에 아래와 같이 컴파일 에러가 발생한다.


마치며


지금 까지 해서 function 정의, const 정의(Arrow Function)에 대한 이야기를 해봤다.

아무래도 화살표 함수의 첫 번째 특징이 가장 중요하기 때문에 
대부분의 내용을 첫 번째 특징에 대해 작성하는데 할애 하였다.

왜냐하면 첫 번째 특징 이외는 
대부분 컴파일러에서 잡아주기 때문이다. 

비지니스 로직 작성에서 이를 정확히 작성하지 않는다면
잘 알지 못한다면 치명적인 버그가 발생하기 때문에 
기억해야 한다면 첫 번째 특징만 기억하고  
넘어간다면 큰 무리는 없을 것으로 보인다.

이외의 특징은 참고란의 URL을 참고하길 바란다.




참고 :



이 블로그의 인기 게시물

[ Web ] 서버 사이드(Sever Side) ? 클라이언트 사이드(Client Side)? 1 [서론, 클라이언트 사이드(Client Side)]

[ Web ] 웹 애플리케이션 아키텍처 (Web Application Architecture)

[ Web ] 웹 애플리케이션 서버 아키텍처의 정의 및 유형 ( Define and Types of Web Application Server Architecture )