원글: https://bocoup.com/weblog/javascript-developers-watch-your-language
Illustration by Matt McLaughlin.
2021년 8월 21일 오전 9시 18분. 당신은 막 아침을 먹었다. 당신은 Omni Consumer Products의 웹 유지 보수를 담당하고 있다. 한 시간 뒤 당신의 마지막 변경이 적합성 테스트에서 부적합 판정을 받았음을 발견했고, 이 문제는 "RedactSelect"의 버그로 발견되었다. 이는 당신이 사용하는 오픈소스 "multiselect" 웹 컴포넌트다. 이 컴포넌트는 업데이트 된 지 1년은 넘은 것 처럼 보이고, 성숙하고 안정적이라 생각되었다. 당신은 속으로 '문제없어, fork 해서 고쳐야겠군.'이라고 생각하고 고치기 시작했다.
코드가 조금 생소했다. 코드 내부에서는 당신에게는 익숙지 않은 @
심볼을 사용했는데, private field 처럼 보였다. 당신은 그럴 리 없다고 생각했다. 왜냐면 ES2020에서는 #
로 사용되고 있었기 때문이다. 그 후 프로젝트의 빌드 프로세스를 확인하는 도중 구식의 내장 트랜스 파일러를 발견했다.
당신은 그 후로 몇시간 동안 "barbel 6.17.0 private field syntax" 등을 여러 검색어로 검색했다. 한번 이런 문법과의 문제를 다루기 시작하면 트랜스 파일러의 버그 리포트들 사이에서 허덕이게 된다. 해당 버전은 특정 상황일 때 미묘한 버그를 발생시키는 코드들이 포함되어있었고, 불행히도 버그는 major 버전에서 고쳐지지 않았다. 이것이 "RedactSelect"와 맞지 않았다.
지금은 저녁 7시 3분이다. 당신은 아직도 당신의 로봇 개에게 먹이를 주지 않았고, 사이버 쓰레기를 치우지 않았다. 당신은 살을 조금 빼야겠다고 생각했고, 아침에 새로운 컴포넌트를 찾아봐야겠다고 생각했다. 몇 달 후 호환성 관련 버그 리포트가 올라왔다.
여러분은 내가 고집이 센 늙은이라고 생각할지 모른다. 언어의 새로운 기능들을 추가 할 때 내가 내 동료들보다 보수적이라는 것은 동의하지만 그렇다고 내가 까다로운 사람이라 생각하진 않는다. 나는 TC-39멤버들과 함께 최신 기능들로 Test262 확장을 진행했다. 그때 위원회의 새로운 연간 배포 스케줄과 지루한 수용 과정이 배포의 역사적 접근으로서 놀라운 진보라고 생각했다. 제안서가 완성되면서 사양 작성자, 플랫폼 구현자 응용 프로그램 개발자가 공동 작업을 할 수 있도록 설계된 다양한 stage를 거친다. 제안서가 진행되는 단계는 아래와 같다.
* stage 1 : 위원회가 문제 공간, 해결책과 교차 관심사를 조사하는 기간임을 의미한다.
* stage 2 : 위원회가 기능이 개발되어 표준에 포함되기를 기대하는 것을 의미한다.
* stage 3 : 해결이 완료되었으며 앞으로 남은 작업이 구현 경험, 주요 사용법, 외부 피드백 없이 진행될 수 있다.
* stage 4 : 가까운 표준 개정 버전에 추가될 예정임을 의미한다.
필자는 산업적인 측면에서, 우리가 분리된 각 단계의 의미를 완벽히 받아들이지 못했다는 게 걱정된다.
Babel 프로젝트는 실험적인 JavaScript 기능을 사용하여 코드를 작성하는 것을 매우 쉽게 만들었다. 두 개의 모듈을 설치하는 것만으로 switch
문과 for..of
루프와 같은 표준 구문처럼 do
표현 식을 작성할 수 있다. 놀랍도록 낮은 장벽으로 인해 많은 개발자가 일회용 실험에서 오픈 소스 라이브러리에 이르는 초기 단계의 기능을 도입하여 그들의 사업을 운영하는 응용 프로그램의 수준에 이르게 되었다.
위원회는 새로운 기능을 사용할 시기와 방법에 대한 권고를 제시하지만, 많은 개발자가 궁금한 사항은 과연 "npm에서 플러그인을 사용할 수 있습니까?"일 것이다. 필자는 최근 보스턴에서 열린 JavaScript 사용자 그룹 회의를 떠올렸다. 발표자는 다음과 같은 질문을 했다.
"ES2016에 도입된 기능을 누구나 알고 있습니까?"
"함수 데코레이터요~" 라고 청중은 대답했다.
"사실 그것은 ES2016에 포함되지 않았습니다. ES2017에 포함되는 것조차도 논쟁의 여지가 있죠."
"아, ES2016에서 destructuring 할당을 도입했습니다."
"아닙니다. destructuring 바인딩은 ES2015에서 표준화되었습니다."
여러분은 제가 조금 학문적이라고 생각할 수도 있을 것이다. 어쩌면 다른 사람들도 이런 기술의 동향을 알고 있어야 한다고 기대하는 것이 조금 건방져 보일 수 있다... 하지만 제안서의 단계의 연관성을 얕보면 두 가지 문제에 직면하게 된다.
첫째는, 진화하는 플랫폼 위에 언어를 구축하다보면 시간이 지나면서 우리는 기반 구조를 분해한다는 것이다. 필자는 Barbel이라는 이름의 반의어적 가치를 알리고 싶다. (여러 프로젝트에서 차용하게되어 잠재적으로 매우 혼동될 수 있다)
이것은 새로운 문제가 아닌, 이미 우리가 겪고 있는 문제다. 수백만의 웹사이트에 배포된 라이브러리 JQuery를 한번 떠올려 보자. 2016년 6월 까지는 표준이 아닌 promise가 포함되어 있었다. 그런데도 우리는 받아들여도 괜찮은 것처럼 여겼다.
하지만 언어 수준에서 이런 명세 위반이 발생하면 문제의 영향은 더욱 심각해진다. 디버그하기 더 어렵고, 우리가 사용하는 라이브러리의 코드의 문법 문제를 발생시키기도 한다.
TC-39는 연구자, 런타입 개발자뿐만 아니라 JS Foundation, Tilde, Bocoup, Shape Security 그룹 원 들의 동의에 의해 운영된다. 결과적으로 합의는 이상적인 설계뿐만 아니라 실제 산업의 현실에 의해 이루어지게 된다. 저번 달의 진행 과정 일부를 예로 한번 살펴보자:
Dave Herman : 디자인 제약 : - CJS에서 명명 된 내보내기를 가져올 수 있어야합니다 - [ECMAScript 모듈을로드하는 데 require 함수를 사용하여] 동기적으로 [반환]해야 합니다.
Jeff Morrison : 이러한 기술 요구 또는 생태계 요구 사항이 있습니까?
James Snell : 이 내용은 생태계에서 요구합니다. Barbel은 이미 지원하고 있으며, 기존 사용자들은 코드를 변경하지 않기를 원할 것입니다. 만약 저희가 그것이 작동하지 않는다고 말하면, 우리는 도입을 고려하지 않을 것입니다.
이것은 사용자의 기대가 얼마나 위원회가 결정하기 힘들게 만다는지를 보여준다. 제안된 확장 기능에 대한 시스템을 구축하고 배포하는 것이 많을수록 표준 기관이 설계를 수정하는 것은 더 어려워진다. 한 가지만 기억하도록 하자. : Stage 4까지는 "완료"되지 않은 것이다! 극단적으로 최종 설계가 web reality의 영향을 받아 차선책을 택할 수 있다. 명세 전반에 걸친 다양한 불규칙성 들은 이런 원인에 의해 발생 된 것을 알 수 있다.
이러한 위협은 우리가 초기 단계의 제안을 공동으로 채택하는 범위에서만 예측할 수 있다. 우리 업계가 보수적인 압박을 가한다면, 우리는 이런 문제에 대해 걱정할 필요가 없다.
우리는 ECMA에 의해 공식적으로 비준되지 않은 구문을 사용하지 않는다고 응답할 지도 모른다. 즉, "ES20XX가 발표될 때까지는 ES20XX 기능을 사용하지 않을 거야."라고 말이다. 이 경우 모든 프로젝트의 모든 코드가 항상 표준을 완벽하게 준수 할 것이므로 코드 조각화나 설계 프로세스 줄이기에 대해 걱정할 필요가 없다.
하지만 누군가가 표준이 아닌 기능을 사용하지 말자는 제안을 할지라도, 나는 그 의견에 동의하지 않을 것이다. 구현 피드백은 설계 과정의 중요한 부분이므로 반드시 실험이 필요하다.
예를들어, V8 및 Spidermonkey와 같은 런타임은 구문 분석을 수행하고 (플래그 뒤에 있지만) 실험 구문을 실행해야한다;Babel과 Traceur와 같은 트랜스파일러는 실험 구문을 번역해야한다;응용 프로그램 개발자는 실험 구문을 사용하여 코드를 작성해야 한다.
위와 같은 아름다운 여러 개념을 연마하는 것이 자바스크립트를 더 재미있게 만들어주는 것이다.
우리는 각 제안의 현재 "단계"에 대한 인식을 키우고 그 상태의 민감성에 대해 훈련해야 한다. 그렇게 되면 우리는 ECMAScript의 발전에 효과적이고 책임감있게 참여할 수 있다. 이 과정은 약간의 미묘함이 필요하므로 단호하고 빠른 규칙들을 정의 할 순 없지만, 몇 가지 일반적인 제안을 할 수 있다.
* stage 2 이하 : 개인 실험을 위해 남겨둔 여분이다. 명확하게 "unstable" 이름표가 붙은 브랜치에서의 실험은 안전하지만, 규모가 큰 프로젝트의 경우 변경 시 더 많은 리팩토링이 필요할 수 있다. (`Object.observe`가 [궁극적으로 철회되기 전](https://mail.mozilla.org/pipermail/es-discuss/2015-November/044684.html)에 이 단계로 나아 갔다는 것을 기억하라.) 여러분의 경험을 ['es-discuss 메일링 리스트'](https://esdiscuss.org/) 또는 제안서의 이슈 트래커에 공유하자.
* stage 3 : 중요하지 않은 프로덕션 코드의 구현에 사용하자. 더욱 현실적인 환경에서의 당신의 경험을 통해 실험적인 코드의 새로운 결점을 발견 할수 있다. 만약 결점이 발견된다면 즉시 공유하길 바란다. 아직 명세가 정확히 결정된 것이 아니므로 큰 프로젝트에서 사용하는 것에 대해서는 신중히 고민해야 한다.
* stage 4 : 원하는 대로 사용하라. 이 제안은 효과적으로 표준화되었고, 형식적 절차만 남아있다. 피드백을 주는 것도 좋지만 효과적이지 않을 수 있다.
각 단계는 서로 모호하며 고집이 센 사람들은 아무 도움도 주지 않을 것을 필자도 알고 있다. 그래도 이 전략에는 바로 피드백이 가장 중요한데, 초기 단계 제안을 실험하는 개발자들은 프로세스에 참여하여 피드백을 줄 책임이 있다는 것을 염두에 두자.
자 이제 실험을 시작해보자 : 함수를 바인딩하고, 메소드를 장식하고, promise를 취소해보자. 초기 제안의 실험을 통해 여러분의 호기심을 충족시키고 피드백을 제공하길 바란다. 하지만 아직 표준화 되지 않은 기능들로 당신의 다음 제품을 구현하는 것은 다시 한번 깊게 생각해보아야 한다.