2020.01.06

‘좋은 걸 어떡해’··· 손이 가는 프로그래밍 일탈 10가지

Peter Wayner | InfoWorld
규칙을 어기면 약간의 스릴을 느낄 수 있다. 때로는 더 좋고 더 효율적인 코드를 작성할 수 있기도 하다.
 
ⓒ Image Credit : Getty Images Bank


우리 모두 해본 적이 있다. 엄마가 보지 않을 때 쿠키를 집어 들고, 저녁으로 와인을 좀 많이 마시고, 차를 애매한 곳에 잠깐 살짝 주차하는 것 등등 말이다. 종종 제한속도를 초과하기도 한다. 

그리고 맞다, 우리 개발자 모두는 프로그래밍의 기본적인 규칙들을 위반한 적 있다. 모두가 동의하는 규칙들이 걸리적거렸기에 우리 모두는 몰래 그렇게 하는 것을 좋아했다. 나쁜 코드를 입력하기도 하면서 우리는 살아왔다. 

그럼에도 불구하고 프로그래밍 신이 번개를 내리지는 않았으며, 데스크톱은 폭발하지 않았다. 사실, 우리 코드는 컴파일된 채 발송됐고, 고객들은 충분히 행복해 보였다.

왜냐하면 나쁜 프로그래밍은 예를 들어, 전기 울타리를 핥거나 호랑이의 꼬리를 잡아당기는 것과 같지 않기 때문이다. 대부분의 경우 잘 작동된다. 규칙은 방침이나 양식상의 제안인 경우가 더 많지, 반드시 따라야 하거나 죽음이 수반되는 융통성 없는 지침이 아니다. 

물론, 당신의 코드가 비웃음을 살 수도 있고, 어쩌면 공개적으로 조롱당할 수도 있다. 하지만 당신이 규칙을 어기고 있다는 사실은, 근엄한 사회적 관행을 살짝 뒤집는다는 유쾌한 스릴을 더해주기도 한다.

규칙을 어기는 것이 더 나은 경우도 있다. 코드가 더 깔끔하게 나온다. 심지어 더 빠르고 더 간단할 수도 있다. 규칙은 보통 너무 광범위한데, 숙련된 프로그래머라면 규칙을 어김으로써 코드를 개선할 수도 있다. 상사에게 자랑할 정도는 아닐지라도 가끔은 당신 방식대로 코딩하는 게 말이 된다. 

다음은 사람에 따라 도저히 납득할 수 없겠지만, 우리들 중 대부분이 성공적으로 그리고 즐겁게 자주 어기는 규칙 10가지다.

나쁜 프로그래밍 습관 No. 1 : 베끼기(Copying) 
학교에서는 분명히 금지된 행동이다. 단 직장에서는 그리 분명하지 않다. 차용하지 말아야 할 코드 블록이 좀 있기는 하다. 만약 독점 코드에서 나온 것이라면, 당신의 스택에 넣지 말아야 한다. 특히 저작권 메시지가 표시되어 있다면 더더욱 그렇다. 탐이 날지라도 자신만의 버전을 써야 한다. 그것이 회사가 당신에게 돈을 주는 이유 중 하나다. 

더 애매한 경우는 원작자가 공유하고 싶어할 때다. 아마도 그것은 온라인 프로그램 포럼 중 하나에 올라와 있을 것이다. 아마도 두어 가지 기능 차용을 허용하는 (BSD, MIT) 라이선스를 가진 오픈소스 코드일 터다. 이 행동을 막을 법적인 이유는 없다. 그리고 당신은 문제를 해결하라고 돈을 받는 것이지, 창조적 활동을 하라고 돈을 받는 것이 아니다.

대부분의 경우 베끼기의 장점은 강력하다. 약간의 주의만 기울이면 단점도 극복할 수 있다. 당신이 명망 있는 출처에서 얻은 코드에는 적어도 일정 고민의 결과물이 이미 적용되어 있었다. 원저자는 해결책을 찾다가 무언가를 발견했다. 루프 불변 및 데이터 흐름이 해결됐다.

까다로운 문제는 어떤 미발견 버그 또는 역할이나 기초 데이터에 대한 다른 가정들이 있는가 하는 것이다. 아마도 당신의 코드는 눌 포인터(null pointer)에 섞여 있을 것이다. 그럼에도 불구하고 만약 당신이 문제를 해결할 수 있다면, 그것은 당신의 상사가 두 프로그래머로부터 성과를 얻는 것과 같다. 그것은 협업 책상이 없을 뿐인 페어 프로그래밍(pair programming )이다.

나쁜 프로그래밍 습관 No. 2 : 논-펑셔널 코드(Non-functional code)
지난 10여 년간 펑셔널 패러다임(functional paradigm )이 발전해왔다. 일련의 기능 집합으로부터 당신의 프로그램을 구축하게 해주는 이 조수는, 어떻게 코드가 예전 방식의 변수와 루프보다 더 안전하고 버그가 없는지를 잘 보여준다. 이 모든 것이 프로그래머를 행복하게 만들 수 있다. 일부 사람들이 코드 리뷰와 풀 리퀘스트에 있어 논-펑서널 접근법을 비난하곤 하는 이유다. 

물론 그들이 옳을 수 있다. 하지만 가끔은 그냥 강력 접착 테이프 한 통을 꺼내야 할 때가 있다. 훌륭하게 설계되고 우아하게 계획된 코드는 고안 및 구축하고 나중에 탐색하는 데도 시간이 걸린다. 그 모든 레이어들은 복잡도를 더하고, 복잡도는 비싸다. 아름다운 펑셔널 코드를 개발하려면 미리 계획을 세우고 모든 데이터가 적절한 경로를 따라 전달되도록 해야 한다. 

때로는 손을 뻗어 변수를 바꾸는 것이 더 쉽다. 아마 설명하기 위해 코멘트로 붙일 것이다. 미래 세대들에게 전하는 장문의 사과를 더하는 코멘트에 더하는 것이, 올바른 방식으로 하기 위해 전체 시스템을 다시 설계하는 것보다 더 신속하다.

나쁜 프로그래밍 습관 No. 3 : 비표준적 띄어쓰기(Non-standard spacing)
소프트웨어에서 빈칸 대부분은 프로그램 작동에 큰 영향을 미치지 않는다. 파이썬(Python)과 같이 코드 블록을 나타내기 위해 띄어쓰기를 사용하는 몇 가지 언어를 제외하고서는 그렇다. 그럼에도 불구하고, 그것들을 유의미하고 중요하다고 주장하는 강박적인 프로그래머들이 있다. 

그 중 한 사람은 내가 ‘비표준 코드’를 쓰고 있다고 아주 심각한 말투로 내 상사에게 말한 적 있다. 내 죄가 무엇이었냐고? 이퀄 사인(equal sign) 양쪽에 빈칸을 두지 않음으로써 ‘ESLint space-infix-ops’ 규칙을 위반했다는 것이었다. 

개발자의 집중력은 제한적인 자원이다. 빈칸을 두는 것보다 더 심오하고 중요한 것에 대해 생각할 필요가 있다. 데이터베이스가 과부하 되는 것을 걱정하고 있을 수도 있다. 어쩌면 눌 포인터가 코드를 망가뜨리는 방법에 대해 걱정하고 있을지도 모른다. 사실 코드의 거의 모든 부분이 빈칸보다 더 중요하다. 참견하고 군림하기를 좋아하는 표준위원회가 이러한 빈칸이나 탭의 배치에 관한 규칙을 제정했다고 해도 말이다.

놀라운 것은 잘 정의된 린팅 규칙(linting rule)을 준수하도록 당신의 코드를 자동으로 다시 포맷해주는 몇 가지 좋은 도구들이 있다는 것이다. 사람이 이것에 대해 시간을 쓸 필요를 없애준다. 만약 그것이 그렇게 중요하다면, 도구를 실행시켜서 문제를 해결하면 된다.

나쁜 프로그래밍 습관 No. 4 : ‘고투’(goto) 사용
고투(goto)의 사용을 금지하는 관행은 여러 구조화된 프로그래밍 도구들이 존재하기도 전 시대로 거슬러 올라간다. 과거 프로그래머들이 루프를 만들거나 다른 루틴으로 점프하려면, ‘GOTO’를 입력한 다음 줄 번호를 입력해야 했다. 몇 년 후 컴파일러 팀들은 프로그래머들이 줄 번호 대신 스트링 레이블을 사용하도록 허용했다. 그 당시로서는 인기 기능이 새롭게 돌아온 것으로 여겨졌다.

하지만 곧 일부는 이 결과를 ‘스파게티 코드’라고 불렀다. 추후 이러한 코드를 읽고 실행 경로를 따라가기가 불가능했다. 그것은 영원히 뒤엉켜 있는 실타래였다. 에제르 디크스트라(Edsger Dijkstra)는 ‘유해한 것 같은 고투 진술서’(Goto Statement Considered Harmful) 라는 익살맞은 제목의 원고를 통해 그 명령어를 금지했다.

하지만 절대 분기(absolute branching)가 문제인 것은 아니다. 그러한 결과가 나온 것은 얽혀진 타래 때문이다. 교묘한 브레이크나 리턴은 그 위치에서 코드가 하고 있는 것에 대해 매우 분명한 진술을 제공할 수 있다. 때때로 사례 진술(case statement)에 고투를 추가하면 보다 적절하게 구성된 목록의 조건문 블록보다 더 간단하게 이해할 수 있는 것을 만들 수 있다.

반례들도 있다. 애플의 SSL 스택에 있는 ‘고투 실패’ 보안 구멍은 대표적인 사례 중 하나다. 하지만, 사례 설명과 루프의 몇몇 까다로운 문제를 피하려고 조심한다면, 우리는 독자들이 무슨 일이 일어나고 있는지 이해하기 쉽게 해주는, 훌륭하고 절대적인 점프를 삽입할 수 있다. 더 깨끗하고 모두에게(고투를 싫어하는 사람들을 제외) 더 기분 좋은 ‘브레이크’나 ‘리턴’을 넣을 수 있다.

나쁜 프로그래밍 습관 No. 5 : 유형을 선언하지 않기(Not declaring types)
타입드 랭기지(typed languages)를 좋아하는 데에는 이유가 있다. 각 변수의 데이터 유형에 대한 명확한 선언을 추가함으로써 더 좋고 더 버그가 없는 코드를 작성할 수 있다. 유형을 설명하기 위해 잠깐 멈추면, 코드가 실행되기 전에 컴파일러가 멍청한 오류를 표시하도록 하는데 도움이 된다. 고통스러울 수도 있지만 도움이 된다. 그것은 버그를 막는 조심스럽고 안전한 프로그래밍 접근법이다.

그러나 시대가 변했다. 더 최신의 컴파일러들 중 다수는 코드를 보고 유형을 추론할 만큼 똑똑하다. 그들은 변수가 ‘string’이나 ‘int’ 또는 다른 어떤 것이어야 한다는 것을 확신할 수 있을 때까지 코드를 분석할 수 있다. 그리고 이러한 추론된 유형이 정렬되지 않으면 컴파일러는 오류 플래그를 발생시킬 수 있다. 이를 통해 우리는 변수를 더 이상 타이핑할 필요가 없다.

이것은 이제 간단한 선언들을 생략함으로써 몇 개의 비트를 더 쉽게 저장할 수 있다는 것을 의미한다. 코드는 좀 더 깨끗해지며, 독자(the reader)는 보통 루프에 대한 a의 i라는 변수가 정수(integer)라는 것을 짐작할 수 있게 됐다.




2020.01.06

‘좋은 걸 어떡해’··· 손이 가는 프로그래밍 일탈 10가지

Peter Wayner | InfoWorld
규칙을 어기면 약간의 스릴을 느낄 수 있다. 때로는 더 좋고 더 효율적인 코드를 작성할 수 있기도 하다.
 
ⓒ Image Credit : Getty Images Bank


우리 모두 해본 적이 있다. 엄마가 보지 않을 때 쿠키를 집어 들고, 저녁으로 와인을 좀 많이 마시고, 차를 애매한 곳에 잠깐 살짝 주차하는 것 등등 말이다. 종종 제한속도를 초과하기도 한다. 

그리고 맞다, 우리 개발자 모두는 프로그래밍의 기본적인 규칙들을 위반한 적 있다. 모두가 동의하는 규칙들이 걸리적거렸기에 우리 모두는 몰래 그렇게 하는 것을 좋아했다. 나쁜 코드를 입력하기도 하면서 우리는 살아왔다. 

그럼에도 불구하고 프로그래밍 신이 번개를 내리지는 않았으며, 데스크톱은 폭발하지 않았다. 사실, 우리 코드는 컴파일된 채 발송됐고, 고객들은 충분히 행복해 보였다.

왜냐하면 나쁜 프로그래밍은 예를 들어, 전기 울타리를 핥거나 호랑이의 꼬리를 잡아당기는 것과 같지 않기 때문이다. 대부분의 경우 잘 작동된다. 규칙은 방침이나 양식상의 제안인 경우가 더 많지, 반드시 따라야 하거나 죽음이 수반되는 융통성 없는 지침이 아니다. 

물론, 당신의 코드가 비웃음을 살 수도 있고, 어쩌면 공개적으로 조롱당할 수도 있다. 하지만 당신이 규칙을 어기고 있다는 사실은, 근엄한 사회적 관행을 살짝 뒤집는다는 유쾌한 스릴을 더해주기도 한다.

규칙을 어기는 것이 더 나은 경우도 있다. 코드가 더 깔끔하게 나온다. 심지어 더 빠르고 더 간단할 수도 있다. 규칙은 보통 너무 광범위한데, 숙련된 프로그래머라면 규칙을 어김으로써 코드를 개선할 수도 있다. 상사에게 자랑할 정도는 아닐지라도 가끔은 당신 방식대로 코딩하는 게 말이 된다. 

다음은 사람에 따라 도저히 납득할 수 없겠지만, 우리들 중 대부분이 성공적으로 그리고 즐겁게 자주 어기는 규칙 10가지다.

나쁜 프로그래밍 습관 No. 1 : 베끼기(Copying) 
학교에서는 분명히 금지된 행동이다. 단 직장에서는 그리 분명하지 않다. 차용하지 말아야 할 코드 블록이 좀 있기는 하다. 만약 독점 코드에서 나온 것이라면, 당신의 스택에 넣지 말아야 한다. 특히 저작권 메시지가 표시되어 있다면 더더욱 그렇다. 탐이 날지라도 자신만의 버전을 써야 한다. 그것이 회사가 당신에게 돈을 주는 이유 중 하나다. 

더 애매한 경우는 원작자가 공유하고 싶어할 때다. 아마도 그것은 온라인 프로그램 포럼 중 하나에 올라와 있을 것이다. 아마도 두어 가지 기능 차용을 허용하는 (BSD, MIT) 라이선스를 가진 오픈소스 코드일 터다. 이 행동을 막을 법적인 이유는 없다. 그리고 당신은 문제를 해결하라고 돈을 받는 것이지, 창조적 활동을 하라고 돈을 받는 것이 아니다.

대부분의 경우 베끼기의 장점은 강력하다. 약간의 주의만 기울이면 단점도 극복할 수 있다. 당신이 명망 있는 출처에서 얻은 코드에는 적어도 일정 고민의 결과물이 이미 적용되어 있었다. 원저자는 해결책을 찾다가 무언가를 발견했다. 루프 불변 및 데이터 흐름이 해결됐다.

까다로운 문제는 어떤 미발견 버그 또는 역할이나 기초 데이터에 대한 다른 가정들이 있는가 하는 것이다. 아마도 당신의 코드는 눌 포인터(null pointer)에 섞여 있을 것이다. 그럼에도 불구하고 만약 당신이 문제를 해결할 수 있다면, 그것은 당신의 상사가 두 프로그래머로부터 성과를 얻는 것과 같다. 그것은 협업 책상이 없을 뿐인 페어 프로그래밍(pair programming )이다.

나쁜 프로그래밍 습관 No. 2 : 논-펑셔널 코드(Non-functional code)
지난 10여 년간 펑셔널 패러다임(functional paradigm )이 발전해왔다. 일련의 기능 집합으로부터 당신의 프로그램을 구축하게 해주는 이 조수는, 어떻게 코드가 예전 방식의 변수와 루프보다 더 안전하고 버그가 없는지를 잘 보여준다. 이 모든 것이 프로그래머를 행복하게 만들 수 있다. 일부 사람들이 코드 리뷰와 풀 리퀘스트에 있어 논-펑서널 접근법을 비난하곤 하는 이유다. 

물론 그들이 옳을 수 있다. 하지만 가끔은 그냥 강력 접착 테이프 한 통을 꺼내야 할 때가 있다. 훌륭하게 설계되고 우아하게 계획된 코드는 고안 및 구축하고 나중에 탐색하는 데도 시간이 걸린다. 그 모든 레이어들은 복잡도를 더하고, 복잡도는 비싸다. 아름다운 펑셔널 코드를 개발하려면 미리 계획을 세우고 모든 데이터가 적절한 경로를 따라 전달되도록 해야 한다. 

때로는 손을 뻗어 변수를 바꾸는 것이 더 쉽다. 아마 설명하기 위해 코멘트로 붙일 것이다. 미래 세대들에게 전하는 장문의 사과를 더하는 코멘트에 더하는 것이, 올바른 방식으로 하기 위해 전체 시스템을 다시 설계하는 것보다 더 신속하다.

나쁜 프로그래밍 습관 No. 3 : 비표준적 띄어쓰기(Non-standard spacing)
소프트웨어에서 빈칸 대부분은 프로그램 작동에 큰 영향을 미치지 않는다. 파이썬(Python)과 같이 코드 블록을 나타내기 위해 띄어쓰기를 사용하는 몇 가지 언어를 제외하고서는 그렇다. 그럼에도 불구하고, 그것들을 유의미하고 중요하다고 주장하는 강박적인 프로그래머들이 있다. 

그 중 한 사람은 내가 ‘비표준 코드’를 쓰고 있다고 아주 심각한 말투로 내 상사에게 말한 적 있다. 내 죄가 무엇이었냐고? 이퀄 사인(equal sign) 양쪽에 빈칸을 두지 않음으로써 ‘ESLint space-infix-ops’ 규칙을 위반했다는 것이었다. 

개발자의 집중력은 제한적인 자원이다. 빈칸을 두는 것보다 더 심오하고 중요한 것에 대해 생각할 필요가 있다. 데이터베이스가 과부하 되는 것을 걱정하고 있을 수도 있다. 어쩌면 눌 포인터가 코드를 망가뜨리는 방법에 대해 걱정하고 있을지도 모른다. 사실 코드의 거의 모든 부분이 빈칸보다 더 중요하다. 참견하고 군림하기를 좋아하는 표준위원회가 이러한 빈칸이나 탭의 배치에 관한 규칙을 제정했다고 해도 말이다.

놀라운 것은 잘 정의된 린팅 규칙(linting rule)을 준수하도록 당신의 코드를 자동으로 다시 포맷해주는 몇 가지 좋은 도구들이 있다는 것이다. 사람이 이것에 대해 시간을 쓸 필요를 없애준다. 만약 그것이 그렇게 중요하다면, 도구를 실행시켜서 문제를 해결하면 된다.

나쁜 프로그래밍 습관 No. 4 : ‘고투’(goto) 사용
고투(goto)의 사용을 금지하는 관행은 여러 구조화된 프로그래밍 도구들이 존재하기도 전 시대로 거슬러 올라간다. 과거 프로그래머들이 루프를 만들거나 다른 루틴으로 점프하려면, ‘GOTO’를 입력한 다음 줄 번호를 입력해야 했다. 몇 년 후 컴파일러 팀들은 프로그래머들이 줄 번호 대신 스트링 레이블을 사용하도록 허용했다. 그 당시로서는 인기 기능이 새롭게 돌아온 것으로 여겨졌다.

하지만 곧 일부는 이 결과를 ‘스파게티 코드’라고 불렀다. 추후 이러한 코드를 읽고 실행 경로를 따라가기가 불가능했다. 그것은 영원히 뒤엉켜 있는 실타래였다. 에제르 디크스트라(Edsger Dijkstra)는 ‘유해한 것 같은 고투 진술서’(Goto Statement Considered Harmful) 라는 익살맞은 제목의 원고를 통해 그 명령어를 금지했다.

하지만 절대 분기(absolute branching)가 문제인 것은 아니다. 그러한 결과가 나온 것은 얽혀진 타래 때문이다. 교묘한 브레이크나 리턴은 그 위치에서 코드가 하고 있는 것에 대해 매우 분명한 진술을 제공할 수 있다. 때때로 사례 진술(case statement)에 고투를 추가하면 보다 적절하게 구성된 목록의 조건문 블록보다 더 간단하게 이해할 수 있는 것을 만들 수 있다.

반례들도 있다. 애플의 SSL 스택에 있는 ‘고투 실패’ 보안 구멍은 대표적인 사례 중 하나다. 하지만, 사례 설명과 루프의 몇몇 까다로운 문제를 피하려고 조심한다면, 우리는 독자들이 무슨 일이 일어나고 있는지 이해하기 쉽게 해주는, 훌륭하고 절대적인 점프를 삽입할 수 있다. 더 깨끗하고 모두에게(고투를 싫어하는 사람들을 제외) 더 기분 좋은 ‘브레이크’나 ‘리턴’을 넣을 수 있다.

나쁜 프로그래밍 습관 No. 5 : 유형을 선언하지 않기(Not declaring types)
타입드 랭기지(typed languages)를 좋아하는 데에는 이유가 있다. 각 변수의 데이터 유형에 대한 명확한 선언을 추가함으로써 더 좋고 더 버그가 없는 코드를 작성할 수 있다. 유형을 설명하기 위해 잠깐 멈추면, 코드가 실행되기 전에 컴파일러가 멍청한 오류를 표시하도록 하는데 도움이 된다. 고통스러울 수도 있지만 도움이 된다. 그것은 버그를 막는 조심스럽고 안전한 프로그래밍 접근법이다.

그러나 시대가 변했다. 더 최신의 컴파일러들 중 다수는 코드를 보고 유형을 추론할 만큼 똑똑하다. 그들은 변수가 ‘string’이나 ‘int’ 또는 다른 어떤 것이어야 한다는 것을 확신할 수 있을 때까지 코드를 분석할 수 있다. 그리고 이러한 추론된 유형이 정렬되지 않으면 컴파일러는 오류 플래그를 발생시킬 수 있다. 이를 통해 우리는 변수를 더 이상 타이핑할 필요가 없다.

이것은 이제 간단한 선언들을 생략함으로써 몇 개의 비트를 더 쉽게 저장할 수 있다는 것을 의미한다. 코드는 좀 더 깨끗해지며, 독자(the reader)는 보통 루프에 대한 a의 i라는 변수가 정수(integer)라는 것을 짐작할 수 있게 됐다.


X