'Expected to return a value in arrow function'과 FP의 불변성 개념

급식·2025년 3월 18일

Javascript

목록 보기
3/3
post-thumbnail

소스 코드를 분석하다가 이런 에러를 만났다.

문제가 되는 부분은 대강 아래와 같았는데,

const plans = [
	['plan1-1', 'plan1-2', ... , 'plan1-last'],
  	['plan2-1', 'plan2-2', ... , 'plan2-last'],
    ...
];

plans.map(plan => {
	plan = plan.pop();
});

이렇게 고쳐주면 일단은 조용해진다.

plans.map(plan => (plan = plan.pop()));

참고로 plan.pop() 뒤에 있던 세미콜론이 빠졌는데, map 함수는 두 가지 방법으로 쓸 수 있기 때문에 그렇다.

첫째 방식은 함수의 body 부분, 그러니까 유효한 코드 블럭을 통째로 넘겨주는 방식이고 둘째는 을 넣어주는 방식인데, 위에서 고친 방식은 두번째 방식이다. 그래서 좀 어색하긴 하지만 아래와 같이 소괄호를 생략해도 된다.

plans.map(plan => plan = plan.pop());

분석

VSC는 왜 경고 메시지를 날렸나,,!

그건 Array.prototype.map()의 시그니처를 보면 된다. 직접 가서 보는게 좋지만 귀찮아 할 것 같아서 대신 옮긴다.

보면 알겠지만 map의 역할은 배열의 각 요소에 대해 callbackFn이 적용된 요소들로 구성된 새 배열을 반환하는 것이다.

plans.map(plan => {
	plan = plan.pop();
    // return plan; // 이게 빠짐!
});

그렇기 때문에 위에서 인자로 전달된 화살표 함수에 return 문이 없어 에러가 난 것이라 할 수 있다.

어?

일단 이상한게, Array.prototype.pop()

  1. 기존 배열에서 마지막 요소를 빼고
  2. 빠진 값을 반환

하는 두 가지 역할을 수행한다.

근데 인자로 주어진 화살표 함수 안에서는 plan의 마지막 값을 빼고 그 값을 해당 지역 변수에 재할당하고 있다. 지역 변수이기 때문에 plan은 각 iteration step이 끝날 때마다 날아가므로 위의 두 작업 중 1번에 해당되는 side effect만 외부에 적용된다. (call by reference)

또한 화살표 함수가 아무 것도 반환하지 않기 때문에 저 plans.mapconsole.log를 찍으면 [undefined, undefined, ...]가 나올 것이다. 반환된 배열을 쓰는 코드가 없어서 undefined로만 구성된 배열이 반환되어도 문제가 없기는 하다 일단은.

뭔가 이상하지만 아마 코드를 쓴 사람은 plan의 마지막 요소가 빠진

[
	['plan1-1', 'plan1-2', ... ],
	['plan2-1', 'plan2-2', ... ],
  ...
]

plans에 할당되었으므로 '음 됐따!' 하고 넘어갔을 것이다.

'됐따!'가 쌓여서 한 파일에 이렇게 무더기로 에러가 나왔다.

맞다고는 안했다.

일단 돌아가게 만드는 것도 참 중요하지만, 설계 의도에 맞게 쓰는 것도 그만큼 중요하다.

map은 고차 함수인 Map을 JS에 녹인 것으로, 함수형 프로그래밍의 뿌리인 순수 함수불변성을 항상 생각해야 한다.

그게 안지켜진 위 코드는 문법적으로는 맞을지 몰라도, map 함수 안에서 사이드 이펙트가 발생한 시점부터 함수형 프로그래밍을 했다고 보기는 어려운 것이다. map 함수가 사이드 이펙트를 발생시키지 않도록 짠다면 아래와 같을 것이다.

const updatedPlans = plans.map(plan => plan.slice(0, -1));

이렇게 짜면 원본인 plans의 각 요소에 대한 변경이 없으므로 사이드 이펙트로 인한 버그는 걱정 안해도 된다.


이거 리액트 코드에서 무더기로 발견한 이슈인데,, 이런 간단한 코드에서부터 문제가 보이기 시작하니까 프로그램 실행 흐름이 여기저기 비동기적으로 꼬여있는 jsx쪽 코드 분석하기가 진짜 빡셀 것 같다.

어딘들 그렇겠지만 불변성 개념의 비중이 큰 프론트엔드 쪽 공부하거나 코드를 쓸 때는 이런거 꼬오오옥 좀,, 그냥 넘어가지 말고 공부하고 짰으면 좋겠다,,, 제발,,,,,,,,,,

profile
그래 다 먹고 살자고 하는 건데,, 🥹

0개의 댓글