openlang

아무도 부탁하지 않은 배열

CoffeeScript는 모든 함수에서 마지막 식을 반환하고, for 루프도 식입니다. 그래서 부수 효과만을 위해 쓴 루프로 끝나는 핸들러는, 매 반복의 값을 배열에 모아 반환하는 JavaScript로 컴파일됩니다. 그 배열은 아무도 읽지 않습니다. 문서는 그런 함수를 true나 null로 끝내라고 권했고, 저는 아무 효과도 없는 순수 JavaScript에서도 아직 끝에 null을 붙이다가 멈칫합니다.

이어지는 대화 4

서로의 근거를 따라
  1. 고유 링크

    ReScript도 마지막 식을 반환하지만 그런 배열은 만들지 않아요. 거기서는 for 루프의 타입이 unit이거든요. 블록 중간에 안 쓰인 값이 있으면 ignore로 감싸라는 경고가 나오는데, 그게 배우는 사람에게 뭘 가르치는지는 잘 모르겠어요.

  2. 고유 링크

    배열은 그나마 무해한 경우예요. 재미있는 건 핸들러의 마지막 줄이 하필 불리언일 때예요.

    핸들러를 addEventListener로 붙였다면 반환값은 무시되고, 루프든 비교든 거기서 나온 값은 그냥 버려져요. onclick에 대입했다면 false를 돌려주는 순간 기본 동작이 취소돼요. jQuery 핸들러라면 false가 전파까지 막아요. jQuery는 그걸 preventDefault()와 stopPropagation()을 함께 부른 것으로 처리하거든요. 그러니까 똑같이 컴파일된 return 하나가 어떤 구성에서는 잡음이고, 다른 구성에서는 안 넘어가는 링크고, 또 다른 구성에서는 부모가 끝내 듣지 못하는 클릭이 돼요.

    암묵적 반환을 안 쓰는 값이라고 표시하는 리팩터링 미리보기는 셋 중 둘에서 틀려요. 뭔가를 죽은 코드라고 부르기 전에 함수가 어디에 붙어 있는지부터 알려 줘야 해요.

  3. 고유 링크

    그쪽이 배열보다 훨씬 큰 사고를 쳤습니다(애초에 그런 조언이 생긴 이유의 절반쯤은 이것이었다고 봅니다. 끝에 붙인 null이나 true는 jQuery를 조용히 두지만 어쩌다 나온 false는 그렇지 않은데, 문서는 그 점을 끝내 분명히 적지 않았습니다). 단골 피해자는 토글이었습니다. @open = not @open으로 끝나는 클릭 핸들러는 return this.open = !this.open;으로 컴파일되고, 두 번에 한 번은 false를 돌려줍니다. 그러면 한 번 걸러 한 번씩 패널이 열리고 닫히면서 이벤트까지 삼켜 버립니다. 컴파일된 반환 줄을 읽기 전까지는 그냥 변덕스러운 토글처럼 보이고, 그 줄은 눈에서 미끄러지기 쉬운 줄입니다.

  4. 고유 링크

    일반 JavaScript에도 중괄호 없는 화살표 함수가 남아 있어요. useEffect(() => fetchList())는 React에 프로미스를 넘겨서 개발 모드 콘솔이 불평하고, useEffect(() => { fetchList() })는 undefined를 반환해요. 옛날에 끝에 붙이던 null이 하던 일이 대략 그거였어요.

같은 질문의 다른 갈래

  1. round(2.5)가 2라는 걸 학습자들은 안 믿는다

    학습자들은 자꾸 round(2.5)가 3일 거라고 짐작하는데, 제가 주로 쓰는 두 언어는 다 2라고 해요. Python은 정수 2를, Julia는 2.0을 줘요. 둘 다 동점을 짝수 쪽 이웃으로 보내서 round(0.5)는…

  2. 3 + 4 * 2가 14라는 건 쉬운 쪽이다

    Smalltalk을 처음 배우는 사람은 누구나 일찍 3 + 4 * 2를 만나고 그게 14라는 말을 들어요. 이항 메시지는 산술 우선순위 없이 왼쪽에서 오른쪽으로 가니까요. 이 부분은 한 번 보여 주면 기억에 남아요(정말 그냥…

  3. 옛 CoffeeScript를 손으로 옮기는 JavaScript 연습

    유행은 지났지만 생각보다 훨씬 잘 먹히는 연습이 있습니다. 배우는 사람에게 작고 오래된 CoffeeScript 파일을 하나 주고, 컴파일러를 돌리지 말고 현대 JavaScript로 다시 쓰게 하는 것입니다. 거의 모든 설탕…