캡챠 이야기

요 근래부터 이 블로그에도 국내외 광고 스팸 댓글이 급증하고 있어서 대책이 좀 필요한 것 같다.
옛날에는 외국 발 스팸 트랙백이 아주 가끔 걸리는 듯했는데 요즘은 트랙백은 없고 그냥 닥치고 쓰레기 댓글뿐이다.
일단 영어만 들어있는 텍스트는 무조건 차단하고, 요주의 키워드와 IP는 블랙리스트로 등록해 추가로 차단하고 있는데도 가끔은 그런 필터를 통과한 놈들이 게시되곤 한다. 그런 건 내가 보이는 족족 수동으로 제거하는 중이다.

옛날에 제로보드 시절엔 비로그인 사용자가 댓글/답변을 올릴 때 캡챠를 입력하게 하는 플러그인 내지 소스 추가 패키지가 있어서 본인 역시 제로보드 게시판을 운영할 땐 그걸 유용하게 썼었다. PHP 코드만 돌아가는 게 아니라 리눅스용 실행 파일이 서버에서 실행되어 캡챠 이미지(PNG)를 실시간으로 생성해 냈다.
TextCube용으로도 그런 플러그인이 없을 리는 없겠지. 조만간 도입해야 할지도 모르겠다.

여기서 캡챠란 무엇인지 모르시는 분을 위해 설명하자면..
사용자가 서버로 보내는 게시물 내지 회원가입 신청이 봇/매크로/오토 같은 컴퓨터가 생성한 게 아니라 진짜 사람이 하는 게 맞음을 입증하기 위해, 사람만이 판독할 수 있게 비비 꼬아 놓은 랜덤하고 이상한 글자· 그림이 의미하는 값을 입력받는 인증 장치를 말한다.
gotcha!와 비슷한 어감 때문에 좀 얍삽하다는 심상이 느껴지는데, CAPTCHA는 나름 영단어 이니셜이다.

기계가 인식할 수 없는 이미지를 기계가 생성해 낼 수 있을까?
패턴인식 기술의 발달로 인해 어지간히 허술한 캡챠를 기계가 인식하여 뚫는 기술도 발달하고, 그에 맞서.. 진짜 사람조차 인식 못 할 정도로 난해하지 않으면서 적당히 기계만 엿먹이기에 충분할 정도로 어려운 캡챠를 생성하는 기술을 개발하는 것도 만만찮은 수준이다.

(첨언하자면, 오늘날은 무질서로부터 질서를 도로 찾아서 복구하는 기술이 매우 경이로운 수준이다.
물리적으로 어지간히 손상을 준 하드디스크로부터도 최대한 데이터를 복구해 낸다거나, 심각하게 BLUR된 이미지로부터도 놀라울 수준으로 원래 이미지를 복원한다거나. 캡챠를 뚫는 것도 그런 맥락에서 살펴볼 수 있을 듯하다.)

도스 시절에 '맥스'라는 유사 채팅 프로그램이 있었는데 혹시 기억하는 분 계시는지?
얼굴이 안 보이는 공간에서 어떤 사람이 상대방과 채팅을 했는데, 대화 상대가 패턴이 뻔한 '봇'이 아니라 진짜 사람이 맞는지를 같은 사람이 분간할 수 없었다면 그 대화를 생성한 AI는 '튜링 테스트'를 통과했다고 간주된다.
그런데 캡챠는 역으로 컴퓨터가 이 입력이 진짜 사람이 맞는지를 판단하는 것이므로, 일종의 '역방향 튜링 테스트'에 가까운 셈이다.

스팸 게시물을 막기 위해 도박, 성 등 여러 불건전한 분야의 금지어들을 지정해 놓은 게시판이 많다.
그런데 게시물에 금지어가 우연히 포함되었다고 해서 아무 설명도 없이 없이 글의 등록을 거부하면..
진짜 사람이 그런 거부를 당했을 때 그 사람을 굉장히 화나게 만들 수 있다.

또한 반대로 'xxx는 금지어입니다'라고 매번 친절하게 알려 주면.. 스패머들은 그 피드백 결과를 바탕으로 금지어만 교묘하게 피해가는 스팸 게시물을 만들어 뿌리게 된다. 이 역시 딜레마다.

따라서 둘을 절충하는 방법으로는...
일단은 캡챠 같은 거 없이 깔끔하게 글을 접수한 뒤,
본문이 금지어가 포함돼 있거나 특정 패턴을 만족하여 광고글로 의심되면... 그때는 금지어 같은 광고글 의심 판정 근거를 노출하는 대신, 가만히 캡챠만 좀 입력해 보라고 friendly하게 추가 요청을 하는 게 바람직하지 않은가 싶다. 한 마디로 말해 선패턴 후캡챠 전략인 것이다.

그게 익명 사용자에게 당장 깔끔한 첫인상을 주며,
사용자가 댓글을 올리지 않고 그냥 글을 읽기만 하는데도 복잡한 이미지 프로세싱이 필요한 캡챠를 매번 생성하는 것보다 서버 부담도 줄이는 일거양득 방법일 것이다.

특정 패턴이란 굳이 단어가 아니어도 되고 NLP 기술이 아니어도 된다. 지나치게 URL 링크가 많은 글, 특수문자가 한글과 너무 지저분하게 뒤죽박죽 섞여 있는 글만 찾아도 된다. 이 정도만 돼도 스패머가 제아무리 금지어 필터를 피하려고 잔머리를 굴린들 광고글 따위는 모조리 걸러낼 수 있다.

사이버 공간에서 이런 광고 댓글 스패머는 국제 민폐요 인터넷 트래픽을 좀먹는 공해덩어리 떨거지들이다.
하지만 겨우 얘네들 때문에 게시판을 회원만 글을 올릴 수 있게 바꾼다거나, 심지어 누가 올려 놓은 글은 관리자가 일일이 사전 검열(?)한 뒤에야 공개 게시한다거나 하는 건.. 빈대 잡으려다 초가삼간 다 불태우는 수준의 극단적인 짓일 것이다. 아무쪼록 인간과 기계의 경계를 허물기도 하고 강화하기도 하는 기술의 발달이 절실하다.

이미 널리 알려져 있기도 하겠지만, 캡챠로부터 유래된 재미있는 발상이 있다.
포털 사이트 같은 델 가입할 때, OCR 프로그램이 제대로 인식하지 못한 어떤 책 스캔 이미지 조각에 든 문자열을 캡챠하고 같이 입력하게 한다. 그래서 캡챠를 맞게 입력한 여러 사람들이 동일한 이미지 조각에 대해 일치하는 문자열을 입력했다면, 그 이미지에 담긴 텍스트는 그게 맞다고 데이터를 수집하는 것이다.

캡챠 타이핑과 동시에 real-world 캡챠도 같이 타이핑하여 전세계 네티즌들이 힘을 합쳐 문헌의 전산화(?)에 기여하게 하는 것이다. 일명 '리캡챠 프로젝트'라고 한다. 구글, 페이스북, 아마존 등 세계 유수의 사이트들이 리캡챠 엔진을 활용 중이라고 한다.

Posted by 사무엘

2014/08/16 08:22 2014/08/16 08:22
, ,
Response
No Trackback , 7 Comments
RSS :
http://moogi.new21.org/tc/rss/response/996

가끔은 컴퓨터라는 물건이 발명된 지가 아직 100년도 채 안 됐다는 게 도저히 믿어지지 않을 때가 있다. 세상을 이렇게 완전히 180도 뒤바꿔 놓은 기계가 역사가 그렇게도 짧다니! 그 내력이 최소한 전화기나 자동차의 역사 정도는 될 법도 해 보이지만 실제로는 그렇지 않다. 하긴, 텔레비전이 컴퓨터보다 약간 더 일찍 발명된 정도다.

오늘날의 컴퓨터와 비슷한 컨셉이라도 탑재된 물건이 최초로 등장한 시기는 아무리 일찍 잡아도 2차 세계 대전 이후이다. 전자식+2진법+튜링 완전+프로그램 내장형 같은 기본 중의 기본 단서만 추가해 줘도 시기는 더 늦어진다. 그리고 그것마저도 덩치와 성능은 오늘날 우리가 쓰는 노트북과 스마트폰하고는 차마 비할 바가 못 됨은 주지의 사실이다.

컴퓨터가 2차 세계 대전 이후의 산물이라는 건, 다시 말해 단군의 후손들이 역사상 컴퓨터라는 걸 접한 시기는 오로지 '대한민국' 시대가 유일하다는 뜻이다. 일제 강점기나 조선 시대엔 그런 거 없었다. 그러니, 세계의 컴퓨터 역사뿐만 아니라 그 컴퓨터를 처음으로 우리나라에 도입하고 전산망을 개설한 선구자들의 전설의 레전드를 공부해 보는 것도 전산/컴공 전공자이든 비전공자이든 흥미로운 경험이 될 것이다.

우리나라에는 이 분야의 거장으로 성 기수 박사(1934-), 전 길남 박사(1943-)가 있다. 난 성 박사는 고등학교 때 어느 인터넷 사이트를 통해 아주 아주 대단한 분이라고 우연히 알게 됐다. 전 박사는 알지도 못하다가 대학에 진학해서야 내가 다니는 학교의 학과에 소속돼 있는 만렙 명예교수 중의 한 분 정도로나 접하게 됐다.

두 분 다 업적이 워낙 전문적이고 비가시적인 곳에 있는지라 대중적으로 유명하지는 않다. (2011년 10월에 1주일 간격으로 나란히 세상을 떠났음에도 불구하고 스티브 잡스와 데니스 리치의 대외 인지도의 차이를 생각해 볼 것!)
그러나 굳이 따지자면 아무래도 전자보다는 후자가 약간 더 유명하다. 우리나라 인터넷의 아버지라고 최근에 웹툰도 올라왔고 이게 각종 SNS에 퍼날라지면서 반짝 뜨곤 했다. 독자 여러분에게도 일독을 권한다.

(1982년 5월 15일, 구미 전자 기술 연구소와 서울 대학교 사이에 국내 최초 원거리 컴퓨터 네트워크 교신에 성공. 이건 모뎀이냐 랜이냐 뭐냐? 무슨 물리 메커니즘으로? 으음...;;)

저분은 은퇴한 뒤에도 활발히 활동하고 계시고, 게다가 저 웹툰을 보고는 작가에게 고증 오류 피드백까지 친절하게 해 주셨다고 한다. 여담이지만, 저분의 배우자가 여성 운동가인 조한 혜정 교수라니 깜짝 놀랐다.

최근의 강연 내지 인터뷰에서 전 박사는 인터넷은 너무나 대중적으로 퍼진 만큼 앞으로는 좀 더 안전해져야 한다고 거듭 강조한 적이 있다. 안티바이러스 프로그램의 개발자로 유명한 카스퍼스키는 강력한 인터넷 규제와 신원 확인에 찬성하는 의견을 피력하는 사람인데 그것과도 비슷한 맥락인가 싶었다. 초창기에 인터넷의 각종 규격을 설계했던 엔지니어들은 이 비싼 통신 인프라가 어중이떠중이가 다 쓰는 보편적인 물건이 될 거라고는 감히 생각을 못 했었을 것이다. 그러니 보안보다는 성능과 효율을 훨씬 더 중요하게 생각할 수밖에 없었겠지.

난 전산학의 여러 분야 중에서도 네트워크, 보안 쪽은 제일 까막눈 문외한이다 보니..;; 저런 분을 보면 그냥 입 쩍 벌리고 대단하다는 말밖에 안 나온다.

그럼, 다음으로 성 기수 박사 얘기를 좀 하겠다.
이분도 완전 날고 기는 수재였으며 하버드 대학교에서 석· 박사를 3년 만에 뚝딱 마친 것은 오늘날까지도 유학생들 사이에 전설로 회자된다고 그런다. 원래 전공은 기계· 항공 공학 쪽이었으며 전자· 전산이 아니었다. NASA 같은 데에나 들어가서 우주선과 로켓 엔지니어가 됐을 분이 “아무래도 우리나라엔 컴퓨터가 필요하다”는 신념 하에 한국으로 돌아와 KIST 전산실 실장을 맡았다.

전 길남 박사가 라우터 등 인터넷 기술을 자체 개발하여 우리나라를 인터넷 대열에 합류시켰다면, 성 기수 박사는 그보다 옛날에 우리나라의 행정, 은행, 병원, 철도 등 각 분야의 시스템 전산화를 이끌었다. 전산학이라는 학문이 국내 학계에 제대로 정립조차 되기 전인 초창기에 하드웨어와 소프트웨어를 넘나들며 우리나라의 발전에 지대한 업적을 남긴 것이다. 워낙 옛날이기 때문에 구분이 별로 의미가 없었을지도 모르지만, 저분의 세부 관심사는 HW와 SW 중 어디에 가까웠을지가 궁금해진다.

2000년대 초반에 바둑 연구를 끝으로, 그 뒤부터는 저분은 언론에 보도되는 근황은 없이 조용히 노후를 보내고 계신 듯하다.

인터넷 검색을 하면 성 박사의 일대기를 곳곳에서 발견할 수 있다. 그런데 내 시선을 고정시키는 에피소드가 하나 있었다.
지금으로부터 40년도 더 전인 1970년, KIST 전산실에서 그의 주도하에 한글 전자 인쇄 장치를 개발해 냈다고 한다.
유니코드고 트루타입 글꼴이고 뭐고 하나도 없던 까마득한 옛날에 일종의 1세대 비스무리한 한글 기계화를 이룬 거라고 보면 되겠다.
그런데 여기서 벌써 한글 입력 방식에 대한 얘기가 나온다.

이 글을 읽을 때 유의해야 할 점은 다루는 시기가 굉장히 옛날이라는 점이고, 그럼에도 불구하고 논쟁의 대상이 흔히 생각하기 쉬운 기계식 타자기가 아니라 컴퓨터라는 점이다. 물론 시기가 시기이다 보니, 일반인이 간편하게 다룰 수 있는 오늘날의 개인용 소형 컴퓨터 얘기는 전혀 아니다. 저건 애초에 그런 범용(general-purpose) 컴퓨터도 아니다.

저 때보다 약간 전인 1969년 여름에 국가에서는 타자기용으로 네벌식 글자판을 표준으로 지정했다.
난 그 시절엔 두벌식이라는 게 전혀 없었고 그건 나중에 1980년대에 와서야 생긴 줄 알았다. 그런데 그건 아니고 그 이전부터 두벌식과 네벌식이 모두 있었던 듯하다. 사료를 모두 종합해서 고찰해 보면, 1969년에는 “타자기는 네벌식, 전자 기기는 두벌식”으로 표준이 제정됐고 나중에는 네벌식이 공식 폐기뒨 후 “기계식 타자기까지도 받침 글쇠를 넣어서 두벌식”으로 바뀐 것 같다.

또한 같은 두벌식이라 해도 그때의 두벌식은 오늘날의 '바지들고서' KSX5002 26키 배열하고는 차이가 있었을 수도 있으니까. 나의 역사 지식에 오류가 있다면 수정 지적을 환영하는 바이다.

아무튼, 성 기수 박사가 한글 전자 인쇄기를 개발하던 당시에 국가에서는 이미 네벌식과 두벌식을 밀고 있었다. 그리고 성 박사는 자신이 개발하는 기계에 들어가는 한글 입력 소프트웨어를 별다른 고민 없이 두벌식 기반으로 설계했다.
그분도 그렇게 타자기 따로, 컴퓨터 따로 식인 글자판 표준에는 문제가 있다고 판단했다. 그러나 “씁 어쩔 수 없지”였고, 그런 문제의식만으로 끝이었다.

기계식 타자기가 연극과 같다면 컴퓨터는 영화와 같은 매체이다. 기계식 타자기야 메커니즘이 복잡해서 어쩔 수 없지만, 컴퓨터에는 아무 제약이 없으니 글쇠배열은 가능한 한 간단할 수록 좋을 것이다. 자음의 초· 종성 구분은 컴퓨터 소프트웨어가 알아서 판단하게 하는 게 좋을 것이다. 사용자의 입장에서는 자동화가 되어서 좋고, 개발자의 입장에서는 오토마타 이론을 구현하면서 자신의 프로그래밍 실력을 과시할 수도 있어서 좋다..는 게, 컴퓨터쟁이가 한글 입력에 대해서 생각할 수 있는 딱 전형적인 의식 수준 그 이상도 그 이하도 아니지 않았을까?

그 시절, 공 병우 박사는 안 그래도 나라에서 자기의 세벌식 글자판을 외면한 것 때문에 심기가 불편했다. 그랬는데 마침 한글 전자 인쇄기에 네벌식 대신 두벌식 글자판이 들어간다고 하자 책임자인 성 박사를 자기 집에 초대해서 로비(?)까지 시도했다고 한다. 공 박사는 그 시절에 이미 그야말로 억만장자가 된 60대의 안과 의사였고, 성 박사는 30대 중후반으로 공 박사의 아들 연배인 파릇파릇한 공학자였다. 물론 전공은 다를지언정 두 분 다 대한민국 0.1% 이내에 드는 천재들인 건 주지의 사실이다.

공 박사는 고급 외제차를 몰고 성 박사를 데리러 홍릉 KIST를 직접 찾아갔다. 그리고 호화로운 자기 집에서 최고급 요리를 대접하면서 제안을 한 게.. “당신 같은 사람이 세벌식을 지지해 준다면 당신이 필요한 연구비는 내가 얼마든지 대 주겠소.”였다고. 여러분도 잘 아시잖는가. 공 박사는 기계덕후였으며 평생 젊은 프로그래머, 엔지니어들을 굉장히 좋아하셨다.

국가로부터 받는 예산만으로는 당장 연구실의 장비 내지 컴퓨터의 업그레이드조차 빠듯할 지경이었는데.. 그 제안에 성 박사가 귀가 솔깃해질 정도였다고 한다. 이거 뭐 “KIST에 공 병우 박사의 기증으로 슈퍼컴퓨터가 한 대 도입되었다” 같은 역사가 쓰여질 수도 있었다!

허나 설득은 잘 되지 않았던 것 같다. 공 박사의 입장에서 성 박사는 장래는 촉망되지만 한글이나 글자판에 대한 건전한(?) 소신이 없이 그냥 어용학자로 빠질 위험이 있는 인재로 보였을 것이다. 그리고 성 박사의 입장에서 공 박사는 그냥 자기 발명품만 꽉 껴안고 놓을 생각을 안 하는 고집쟁이 타자기 덕후로만 보였을 것이다. 늘어놓는 이야기가 서로 핀트가 안 맞았다.

성 박사는 공 박사로부터 융숭한 대접을 받고 세벌식 한영 타자기를 한 대 선물로까지 받았지만, 세벌식 같은 덴 애착이 별로 안 갔으며 그건 곧 그걸 갖고 싶어하는 다른 후배에게 줘 버렸다고 한다. 그리고 두 '박사'간의 만남은 그걸로 끝이었다. 저 사이트의 글도 “성 기수의 결정은 결과적으로 반공병우파의 손을 들어 준 셈이 되어 버렸다.”라고 씁쓸하게 끝난다.

그래. 하버드에서 3년 만에 박사 학위를 받은 공돌이라고 해도 그 옛날에 타자기와 컴퓨터의 글자판 통일 가능성을 생각할 수는 없었을 것이다. 글자판 일체형 직결식 글꼴이 항공· 기계 분야하고 관계가 있지는 않잖아.

물론 공 박사도 의사 겸 의학자일 뿐, 언어학이나 타이포그래피를 체계적으로 공부해서 그 분야에 학위가 있지는 않은 건 마찬가지다. 그러나 이 분야의 식견에 관한 한은 더 옛날부터 이 극로 선생으로부터 감화를 받아서 한글덕후로 개조가 끝나 있던 공 박사가 더 앞서 있었다. (그러고 보니 이 글에서 덕후 타이틀만 무려 3개가 나왔군.. -_-)

그럼에도 불구하고 저 사이트의 글에서는 꼭 공 박사가 성 박사를 무슨 불의한 일에 접대로 유혹하고 매수라도 하려 한 것처럼 묘사되어 있어서 좀 유감스럽다. 다른 사람들이 보면 오해하겠다.
이거 무슨... “통일교를 공인해 주면 내 사재로 IMF 빚 다 갚아 주겠다”도 아니고.. 뭐냐?

Posted by 사무엘

2014/08/13 08:35 2014/08/13 08:35
, , , , , , , ,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/995

십계명 해설

흐음, 지금까지 내가 블로그에 십계명 자체를 분석한 글을 올린 적이 없었구나.

십계명은 하나님께서 모세에게 주신 법으로, 성경에서 출애굽기 20장에 처음으로 등장하고 나중에 신명기 5장에서 재탕된다.
십계명은 곰곰이 뜯어 보면 굉장히 잘 만든 법 체계이다.
각각의 아이템들이 다 죄라는 vector space에서 서로 일차독립을 이루는 벡터를 구성하고 있다. 쉽게 말해 인간이 지을 수 있는 죄(색깔)를 서로 독립된 분야(R, G, B??)별로 잘 망라했다는 뜻이다.

십계명의 속성을 쪼개 보면 이러하다.

I. 하나님 관련

1. 하나님 외에 다른 신을 섬기지 말라
2. 형상: 하나님을 잘못된 방식으로, 혹은 하나님 아닌 것을 하나님이라고 우기면서 섬기지 말라.
3. 하나님의 이름을 헛되이 일컫지 말라

신앙 정체성을 국가 정체성에다 비유하자면, 2와 1은 각각 내란죄-외환죄 정도에 대응하는 굉장한 중죄이다. 천주교의 십계명은 1과 2를 한데 뭉뚱그려서 '반역죄' 정도로 취급하는 듯한데, 본인의 입장에서는 신념상 이를 인정하지 않는다.
출애굽기에 나오는 금송아지 사건만 해도.. 이스라엘 백성이 대놓고 주 하나님을 버리고 다른 신을 섬기러 떨어져 나간 사건이 아니었다. 단지 금송아지를 하나님이라고 간주하고 얘에게 경배했을 뿐이다.

3은 한국어는 딱히 그리 심한 게 없지만, 심심하면 Oh my God! Goddamn! Jesus! 이런 신성모독적인 감탄사를 남발하는 게 정확하게 해당한다. 성경이 말하는 그 심각하고 끔찍한 문자적인 지옥은 안 믿으면서, What the hell.. 이런 저주를 가벼이 입에 달고 다니는 것도 포함해서 말이다.

II. 약간 특이한 구석이 있는 중간 계명

4. 안식일을 거룩히 지키라: “어떤 나쁜 짓을 하지 말라” 패턴이 아니라, “신이 정해 준 휴일엔 욕심 부리지 말고 조바심 내지 말고 반드시 쉬어라”라는 점에서 독특하다. 지금 쉬느라 생산성이 저하되는 것은 하나님이 유· 무형으로 나중에 다 보상해 주겠다고 약속했으니 이 계명을 지키려면 역시나 믿음이 필요하다. 안식일을 지키는 것도 보통일이 아닌 게, 딱 이 날을 노려서 적의 침략을 받기라도 하면 어떡할 참인가? (당장 우리나라의 6·25 전쟁만 해도 북한군이 일요일에 딱 맞춰 쳐들어왔었다!).

물론 안식일은 유대인의 표적이기 때문에 이 계명은 신약 크리스천에게 문자적으로 적용되지는 않는 유일한 계명이다. 이걸 주일 지키는 것에다 적용하는 건, 마치 열역학 제2법칙을 들이대면서 진화론을 반박하는 것만큼이나 4계명을 굉장히 간접적으로 영적으로 적용한 귀결이다.

5. 부모를 공경하라: 사람 관련이긴 하되, 그냥 일반인 타인이 아니라 자신에게 하나님 같은 역할을 수행하는 특별한 사람에 대한 계명이다. 성경의 하나님은 패륜죄를 굉장히 싫어하신다. (출 21:15,17; 레 20:9; 특히 압권은 신 21:18-21)
안 지켰을 때 채찍만 가혹한 게 아니라, 지켰을 때 이 땅에서 장수할 거라는 당근까지 문맥에서 직접적으로 주어진 유일한 계명임.

III. 사람 관련

6. 살인하지 말라: 물리적인 폭력으로 지을 수 있는 죄 중에서 단연 1위. 하나님의 법은 “ '살인하지 말라'를 어기는 자를 반드시 죽일지니라”이다. 물론 여기서 말하는 살인은 흉계를 품고 남을 고의로 죽이는 것을 말한다. 고의성 없는 과실치사나 정당방위, 전쟁 등은 해당되지 않음.
7. 간음하지 말라: 꼭 물리적인 폭력을 동원하지 않아도 사람 몸에다 쉽게 지을 수 있고 자기 자신의 몸까지 실질적으로 더럽힐 수 있는 심각한 죄이다. 간음은 성경에서 영적인 의미도 매우 크다.

8. 도둑질하지 말라: 남의 것을 속여 빼앗는 모든 행위에 대한 철퇴이다. 이건 “세상에 공짜는 없다”, “일하지 않으면 먹지도 말라”, 황금률 등 인생의 기본 원칙을 위반하는 죄이다.

9. 거짓 증언하지 말라: 거짓말에 대한 철퇴이긴 한데, 일단 이 문맥이 가장 좁은 범위에서 말하는 것은 판결을 굽게 하는 법적 위증을 하지 말라는 얘기이다. 이건 그야말로 입만 뻥긋함으로써 지을 수 있는 죄이다.
10. 탐내지 말라: 이제는 입을 움직일 필요조차 없이 마음과 생각만으로 지을 수 있는 죄가 십계명의 대미를 장식한다. 이것은 인간을 다른 무수히 많은 죄들로 끌어들인 죄이며 스스로 완벽을 자처하던 사도 바울을 떡실신시킨 죄이기도 하다.

십계명은 신약 그리스도인들에게도 매우 유익하며, 제4를 제외하면 문자 그대로 지켜야 할 규범이다.
그러나 크리스천의 행실을 하도 강조하다 보니, 십계명을 평생 지켜야 구원이 유지된다거나 하는 말도 안 되는 율법주의 농간에는 속지 마시길 바란다.

이 자리에서 또 구약 율법과 신약 복음의 조화를 논하기에는 시간과 지면이 매우 부족하니, 결론만 간단히 말하겠다. 구약 성경에 나온 하나님의 법은 “나 이렇게 외형적인 법을 딱 맞춰 지켰어요. 나 잘했죠? 이 정도면 내 힘으로 칭의와 구원이 가능하겠죠?”라고 으스대라고 있는 게 절대로 아니다.
성경은 십계명이, 아니 하나님의 법 전체가 다음과 같은 두 개의 추상적인 계명에 그대로 요약되어 있다고 말한다.

너는 네 마음을 다하고 혼을 다하고 생각을 다하여 [주] 네 하나님을 사랑하라.
너는 네 이웃을 네 자신과 같이 사랑하라. (롬 13:9)

Posted by 사무엘

2014/08/10 08:34 2014/08/10 08:34
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/994

예전에도 몇 차례 얘기했듯이 비주얼 C++은 지금까지 내 인생에서 가장 재미있는 장난감이요, 친구요, 자아실현 매체요, 생계 수단 역할을 톡톡이 해 왔다.

비주얼 C++은 여느 프로그래밍 툴과는 다르게 뭐랄까, standalone, independent이고 자가생성이 가능하다. 쉽게 말해서 비주얼 C++ 자신과 같은 레벨의 컴파일러/런타임/IDE 같은 프로그램을 비주얼 C++로 또 만들 수 있다는 뜻이다. 실제로 마소에서 비주얼 C++은 이전 버전의 비주얼 C++로 만들고 있기도 하고. 이렇듯, 이 툴은 가장 배우기 어렵지만 가장 강력하고 군더더기 없는 프로그램을 만들 수 있다.

2014년 현재, 난 한 컴퓨터에 다음과 같은 세 버전을 깔아 놓는다. 제각기 필요와 쓸모가 있기 때문이다.

1. 2003

  • 2010에서 새로 도입된 Help Viewer가 완전 거지 같아서.. 단순 윈도 API나 MFC 레퍼런스를 조회하는 덴 200x 구버전 document explorer 기반의 msdn이 짱이다. (1) 색인이 처음에 뜨는 데 시간이 너무 오래 걸리는 것, (2) 가끔 목차/색인을 클릭해도 해당 항목 문서가 안 나타나는 것--정확히는 수 초 뒤에 한참 뒤에 뜸.. 이 두 버그 때문에 학을 뗐다. (단, 2012 이후의 Help Viewer 2.0은 불편하던 게 좀 개선된 거 같기도 하고..)
  • 2003은 MFC가 지금처럼 말도 안 되게 bloat되기 전이며, 굉장한 legacy 운영체제에도 돌아가는 바이너리를 만들 수 있는 버전이다. <날개셋> 타자연습을 여전히 10년 전의 구닥다리 컴파일러로 빌드하는 이유가 이것 때문이다.
  • 다만 2003은 IDE가 빌드 내지 리소스 편집 중에 잘 뻗는 편이고(불안정!) Vista 이후 OS에서는 일부 기능이 충돌도 함. 조심해서 써야 한다.

2. 2010

  • 닷넷 이래로 Visual Studio가 기본 제공하던 msi 설치/배포 프로젝트 기능이 2012에서 갑자기 없어져 버린 관계로, 2010을 도저히 제거할 수가 없게 됐다. 대체품이라는 InstallShield 번들 에디션은 어마어마한 덩치와 복잡한 사용법 때문에 곧바로 gg 치고 언인스톨해 버렸다.
  • 또한 <날개셋> 한글 입력기는 빌드와 관련된 특이한 이슈 때문에 2012가 아닌 2010 컴파일러 툴체인을 사용하고 있다.
  • 다만, 2010은 IDE의 비주얼이 역대 VC++ 역사상 제일 구리고 우중충 칙칙하고 안 좋았다. -_-;;

3. 2012

난 201x가 다음과 같은 점에서 마음에 든다. (1) 크게 강화된 인텔리센스 엔진 (2) 람다 같은 C++ 최신 문법 (3) 빌드나 리소스 편집 중에 IDE가 이제 거의 뻗지 않음
2012는 이를 바탕으로 2010보다 훨씬 더 깔끔한 GUI에, 신택스 컬러링도 훨씬 더 강화되어 몹시 마음에 든다. 몇 가지 크리티컬만 없었으면 2012가 2010을 완전히 대체할 수도 있었을 텐데. ㅜ.ㅜ
다만 2012 얘만 꼭 남겨 둘 이유 역시 없기 때문에 이것보다 더 최신 버전이 나오면 그걸로 대체할 수도 있다. 즉, 2012는 2003/2010과는 달리 고정 보존 상태는 아니다.

위와는 달리, 보존 대상에서 제외되고 안 쓰는 버전은 다음과 같다.

1. 6.0

VC6은 그야말로 개발툴계의 IE6이나 마찬가지다. 출시 시기는 다르지만 공교롭게도 버전 번호도 동일하고 말이다. IE가 윈도 비스타의 출시 지연 때문에 6 이후로 5년 가까이 버전업이 없었다면, VC는 닷넷이 첫 개발되느라 4년 가까이 6 이후로 버전업이 없었다. 그 뒤 지나치게 오랫동안 현역을 뛰어 왔다.

웹 개발자들이 제발 IE6 좀 퇴출시키자고 캠페인 하는 것만큼이나 PC 클라이언트 개발자들은 업계에서 VC6 좀 퇴출시키자고 캠페인이라도 해야 할 판이다. 단지, IE는 모든 PC 사용자들이 쓰는 웹브라우저인 반면, VC는 극소수 프로그래머만이 쓰는 개발툴이라는 점이 다르다.

VC6은 이제 해도 해도 너무하다 싶을 정도로 심하게 후지고 낡았다. IDE가 IME-aware하지도 않고, 특히 한글 윈도에서는 기본 글꼴이 윈도 3.1 스타일의 완전 추레한 System으로 나옴! 인텔리센스는 지금에 비하면 완전 안습 크리 수준이고. 최신 C++ 표준이나 멀티코어 같은 건 아웃 오브 안중이다.

VC6이 아니면 도저히 빌드시킬 수 없는 비표준 코드가 이미 수십만 줄 이상 작성되어 버려서 도저히 수습을 못 할 지경이 된, 한 20년 묵은 불가피한 프로젝트가 아니라면 아직까지 VC6을 고집할 이유란 없어야 정상일 것이다. for문 변수 scope 정도는 후대의 컴파일러로도 옵션을 바꿔서 수용시킬 수 있을 텐데.

굳이 장점을 찾자면, VC6은 생성되는 바이너리가 운영체제의 MSVCRT와 MFC42를 직통 지원한다는 점이 매우 유리하다. 그러나 이것도 어차피 64비트는 지원 안 하기 때문에 장점이 반쪽짜리 이하로 의미를 크게 상실한다.

2. 2005

MS 오피스 2003이 아닌 독자 GUI 비주얼을 선택한 첫 버전 되시겠다. (VC 2005가 오피스 2003 같은 시퍼런 비주얼 기반이었다면? 상상만 해도 ㅎㅎ)
난 얘는 일단 sp1과 운영체제 패치를 설치하는 시간이 2005 자체를 설치하는 데 걸리는 시간보다 더 길어서 인상이 매우 안 좋다. 게다가 CRT/MFC DLL 배포 방식도 구리게 바뀌었고. 장점은 어차피 (1) 2003이나(msdn 등) (2) 이후 버전(64비트 지원 등)에 다 포함돼 있기 때문에 굳이 얘가 필요하진 않다. out.

3. 2008

2005보다는 훨씬 더 괜찮은 물건이고 쓸 만하다. 그리고 은은한 연보라색 톤(비스타/7 기준)의 IDE 외형은 역대 버전들 중 가장 깔끔하고 괜찮았다고 생각한다.
200x 중에서는 가장 훌륭했지만, 역시 얘만 보존해야 할 필요는 존재하지 않는다. 플러스 팩의 등장과 함께 MFC가 완전 bloatware로 바뀌어 버렸고, CRT/MFC DLL 배포 방식은 여전히 아쉬운 점이다.

위의 두 카테고리 말고 본인이 special case로 예우하는 골동품 버전이 있는데, 그건 6.0보다도 더 옛날 버전인 4.2이다. mfc42의 원조인 바로 그 버전이다.
본인이 난생 처음으로 구경한 비주얼 C++ 버전이어서 애착이 간다.

Posted by 사무엘

2014/08/07 08:28 2014/08/07 08:28
, , ,
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/993

헷갈리는 개념들 Q&A

어찌 보면 이런 것들을 인제야 깨우친 본인의 무식-_-을 인증하는 아이템들인지도 모르겠는데, 뭐 그냥 재미로 나열해 보았다. 서로 제각기 다른 분야들이다.

1. 스플래시 데미지 + 타격 데미지?

공격이라는 게 존재하는 거의 모든 게임에는.. 그냥 목표물에만 총알의 운동량을 박아 넣는다는 설정인 일반 데미지가 있고, 그에 덧붙여 발사체가 폭발 후 파편을 터뜨려서 주변에 추가적인 데미지까지 입히는 스플래시 데미지가 있다.

난 폭탄을 직통으로 맞은 놈은 데미지가 100, 그리고 폭심지로부터 멀어질수록 데미지는 1/n 내지 1/n^2 등등으로 감소.. 이런 모델만 생각하곤 했다. 스타로 치면 리버나 시즈 탱크, 혹은 핵의 스플래시 데미지 계산 방식처럼 말이다.
그러나 둠 내지 퀘이크 같은 FPS 게임은 로켓 런처의 경우, 로켓을 맞은 것 자체에 대한 타격 데미지를 스플래시 데미지와는 별개로 계산한다. 로켓을 직통으로 맞으면 맞은 데미지 100에다가 파편 스플래시 데미지 100을 추가로 받아서 200을 먹으며, 주변에 있던 놈들은 폭심지로부터의 거리에 따라 100 이하의 데미지를 받는 것이다.

그리고 전통적으로 보스급 대형 몬스터들은 스플래시 데미지를 받지 않아서 로켓 공격을 사실상 절반씩밖에 먹지 않았다. 반대로 플레이어에게도 스플래시 데미지를 받지 않게 하는 파워업 아이템이 꼭 있곤 했다. (퀘이크 3 Arena의 Battle Suit처럼.)

제자리에 가만히 있던 수류탄의 폭발을 직통으로 당한 것이라면 스플래시만 있는 게 맞다. 그러나 로켓 런처의 경우 총알보다는 느리지만 그래도 총알보다 더 크고 무거운 로켓을 맞은 것이니 이놈 자체의 운동량부터 타격 데미지로 치는 것이 가만히 생각해 보니 더 합리적이긴 해 보인다. 지금까지 이런 생각을 안 하고 있었다.

로켓 점프는 스플래시 데미지만으로 점프를 하는 것이다. 게임에서는 구현 가능하지 않지만 로켓을 바닥이 아니라 내 배에다 대고 쐈다면 그건 타격 데미지와 스플래시를 이중으로 받는 것일 테고.

2. 자동차 직진과 후진 평행주차의 차이

평행주차는 주차 중에서도 꽤 어려운 스킬이지만, 정식 주차장이 아닌 길가에다 적당히 차를 세울 때는 반드시 할 줄 알아야 하는 스킬이다.
평행주차는 주차 지점을 지나친 뒤 후진으로 진입했다가 마지막에 핸들을 확 꺾어서 집어넣는 게 정석이다. 그런데 본인은 왜 하필 후진인지를 뭔가 수학적인 증명 수준으로 이해를 잘 못 했다. 후진으로 가능한 것은 전진으로도 똑같이 가능하지 않은가? 평행주차는 왜 전진이 후진보다 어려우며 공간이 더 많이 필요한 걸까?

그래서 머리에다 종이를 펴고 그림을 그려 보고서야 원리를 이해하기 시작했다.
핸들을 완전히 90도로 꺾을 수 있다면 후진 방식은 차 뒷부분부터 주차 지점에 박아 넣은 뒤, 앞부분은 앞바퀴의 회전을 통해 추가 공간 없이도 쏙 집어넣을 수 있다.

그러나 전진 방식은 핸들을 많이 꺾는다고 해서 차를 집어넣는 게 가능치 않으며, 회전 후에 차가 완전히 평행한 방향을 복원할 때까지 추가적인 주행 공간이 필요하다. 구조적으로 더 어려울 수밖에 없게 된다.
또한 발상을 반대로 바꿔서 생각해도 된다. 평행 주차되어 있던 곳에서 차가 “빠져나갈 때는” 전진이 아주 유리한 반면 후진은 완전 어렵다는 걸 알 수 있다.

전진과 후진으로 모두 수월하게 방향을 틀 수 있고 평행 주차가 가능하려면 앞바퀴와 뒷바퀴가 모두 조향 가능해야 한다. 비좁은 실내에서 작업하는 걸 염두에 두고 만들어진 지게차 정도나 이런 조건을 만족한다.

3. 스포츠 사격과 군대 사격

군대 미필자나 여성분들은 잘 모르실 수도 있으니 설명하자면..
군대 사격이 거리가 더 멀고 큰 표적을 쏜다. 스포츠 사격 종목은 수십m대이지 무슨 250m씩이나 되는 거리를 쏘지는 않는다.
스포츠 사격은 가까운 대신 정밀도도 상상을 초월한다. 양궁만 해도 과녁이 얼마나 작은데, 격발이 더 쉬운 총으로는 그야말로 정말 코딱지만 한 표적을 명중시켜야 국제 스포츠로서 밸런스가 유지될 정도다.

그리고 스포츠 사격에서 사용되는 총기는 권총이든 라이플이든 정밀도 향상에 왕창 최적화돼 있다. 반동을 최소화하려고 총이 굉장히 무거우며--군대 돌격소총의 2배 이상--, 방아쇠도 아주 아주 살짝만 건드려 줘도 바로 격발된다. 스포츠용 총이 무슨 행군시의 무게를 고려한다거나 할 필요는 없으니까. 그리고 총의 살상력 내지 대인저지력은 아무래도 군인용 총만치 강하지는 않다.

영점 잡는 건 두 부류의 총으로 각각 어떻게 하는지는 잘 모르겠지만, 여러 정황상 군대에서의 저격수 내지 특등사수가 스포츠 사격 메달리스트하고는 완벽하게 호환되지 않는다고 보는 게 타당하다. 서로 지향하는 바가 다르니까 말이다. 스포츠 사격에 무슨 조준경을 쓰고 탄환 궤도 오차 보정을 해서 수백~1km 밖의 목표물을 맞히는 게 있지는 않다.

4. 스웨덴과 덴마크

북유럽에 서로 가깝다면 가까이 있는 나라이며 3글자짜리 이름에 '덴'자가 있다는 공통점 때문에.. 난 두 나라가 정말 지독하게 헷갈리고 분간하기 어려웠다. 사실, 폴란드와 핀란드의 차이도 지금까지도 잘 모르겠고. -_-

일단 스웨덴은 노르웨이와 접해 있는 큼직한 왕국이며, 스톡홀름 증후군의 본산지이다.
그리고 철덕들에게 친숙한 서울 지하철 5호선의 인버터를 제작한 ABB 사가 스웨덴 국적이기도 하다. (더 정확히는 스웨덴의 Asea와 스위스의 Brown Boveri가 합병하여 ABB라고..)
자동차 제조사 VOLVO가 스웨덴에서 출발한 기업이며, 또한 다이너마이트를 발명한 알프레드 노벨이 스웨덴 출신임.

다음으로 덴마크는 그 밑에 있는 아주 작은 나라이다. 수도는 코펜하겐 되시겠다. 본토는 아주 작지만 그린란드가 덴마크령이다.
덴마크 하면 유명한 사람은 동화 작가인 안데르센이다. 그리고 프로그래밍 언어 분야에서 전세계를 평정한 괴수 컴퓨터 과학자가 두 명이나 미국이 아닌 덴마크 사람인 것은 상당히 의미심장한 일이다.

한 명은 C++ 언어를 고안한 Bjarne Stroustrup (1950~)으로, 더 설명이 필요하지 않을 것이다.
다른 한 명은 Anders Hejlsberg (1960~)로, 왕년에 볼랜드에서 터보 파스칼과 델파이를 개발했다가, 마이크로소프트로 이직한 뒤에는 C# 언어를 설계하고 관리하고 있는 브레인이다.

5. 오르막과 단순 하중의 차이

자전거를 타는데 단순히 뒤에 짐을 많이 싣는 것하고, 짐은 없지만 오르막을 오르는 것 둘 중 “어느 게 더 힘들까? 이걸 정량적으로 수식으로 나타내는 방법은 없을까?”를 생각한 적이 있었다. 자동차로 치면 어느 게 연료가 더 많이 드느냐 하는 것이다.

당장 바퀴와 지면 사이의 마찰계수부터 시작해서 생각해야 할 개념이 많을 것이나, 그래도 중· 고등학교 수준의 고전역학 지식으로도 어느 정도 답이 나올 것이다.
뒤에 백수십 kg 정도 되는 수레를 끌고 가든, 1~2도 정도의 오르막을 오르든 똑같이 힘이 더 많이 필요하고 출발이 더 어려워지는 건 마찬가지이다.
그래도 단순히 하중만 많이 실린 것은 일단 가속을 한 후에는 어느 정도 관성의 덕을 볼 수도 있으며 크게 힘든 게 없다.

그에 반해 오르막은.. 끊임없이 페달을 밟아 줘야 한다. 안 그러면 서 버리는 정도가 아니라 자전거가 뒤로 밀려난다. 단순히 무거운 하중이 걸린 차원이 아니라, 누군가가 약하게나마 뒤쪽으로 페달을 역으로 꾸준히 밟고 있다고 봐야 한다.
그러니 주행하는 거리가 길어질수록 짐보다는 오르막이 확실히 더 큰 장애물이 될 듯하다.

이것과 비슷한 맥락으로, 사진을 찍을 때 대상 물체를 크게 찍기 위해 줌을 당기는 것하고, 그냥 대상에게 가까이 가는 것하고 차이가 무엇인지도 생각한 적이 있었다.
피사체가 단순히 2차원적인 형상일 뿐이라고 생각한다면 둘은 동일하게 피사체를 확대하는 효과를 낸다.
그러나 당연한 말이지만, zoom을 당기는 것은 주변 배경의 원근감을 동일하게 내 주지는 않는다. 그런 차이가 있다. 이것도 오르막과 하중의 차이와 비슷한 맥락인 걸까? ㅎㅎ

6. 럭비와 미식축구의 차이?

스포츠에 완전 문외한이고 관심이 없는 본인으로서는, 둘 다 얼굴에 무슨 펜싱 선수 같은 보호구를 쓰고 손과 발을 모두 동원해서 갈색의 타원형 공을 향해 미친 듯이 쫓아다니는 구기 종목으로밖에 보이지 않는다.
하지만 둘은 규칙이나 체계가 많이 다르다고 한다. 얘는 더 자세한 설명은 패스.. ㅋㅋ

Posted by 사무엘

2014/08/04 08:20 2014/08/04 08:20
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/992

1. 지하철에서 “대형” 화재가 발생했을 때는 차라리 선로로 대피하는 게 낫다

화재 현장에서 목숨을 잃는 사람들은 소사보다는 질식사가 훨씬 더 많다는 게 상식이다.
일반적으로는 깊은 지하가 빛도 안 들어오고 산소도 부족해서 생존에 불리한 게 사실이지만, 지하철은 말 그대로 지하에 뚫린 길이다. 지하가 길이 더 없는 막다른 던전이 아니라는 큰 차이가 있다.

유독가스는 위로 굉장히 빠르게 잘 퍼진다. 대구 지하철 화재 참사 때도, 발상을 전환하여 앗싸리 선로로 대피해서 멀찌기 인접역까지 걸어 간 후 거기서 지상으로 빠져나온 소수의 사람들은 다 별다른 부상 없이 멀쩡히 살아 나왔다.
그 반면, 대부분의 다른 사람들은 당장 지상과 더 가까워 보이는 화재 발생 당역의 출구를 통해 나가려 했으며, 그 결과는 좋지 못했다. 살아서 빠져나가지 못하거나, 생존하더라도 유독가스 흡입으로 인해 몸이 상했다. 후자가 더 안전할 것 같은데 결과는 정반대였던 것이다.

특히나 지하 n층 이하의 매우 깊은 역이라면 정말로 무리해서 지상으로 빠져나갈 생각일랑은 버리고 선로로 대피하는 게 더 훨씬 더 안전할 것이다. 선로가 단선 쌍굴이라면 통행하기가 좀 무섭겠지만, 그래도 지하철에서 그 정도 사고가 났다면 어차피 근처 열차들은 안전 장치 내지 사령부로부터의 지시를 받고 멈추니 열차에 치일 걱정은 안 해도 된다. 단, 요즘은 스크린도어가 역설적으로 이런 선로 탈출에 악재로 작용할 가능성이 있다.

2. 구명조끼는 탈출 후에 부풀려라

육상 교통수단과는 달리 비행기나 배는 사고가 났을 때 사망, 부상뿐만 아니라 실종이 있을 수 있다. 그래서 탑승 전에 신분증으로 탑승객의 신원을 일일이 확인한다.
또한 얘들은 추락이나 침몰로 인해 동체가 수면에 떨어질 수 있다. 안전벨트와 산소 마스크는 비행기에만 있지만, 구명조끼는 두 교통수단이 공통으로 갖추고 있다.

비행기나 배의 위급 상황에서 구명조끼를 잘 착용하는 것까지는 좋으나, 거기에다 공기를 주입해서 부력을 만드는 건 아무리 위급한 상황이라도 해당 동체를 탈출하여 밖에 나온 뒤에 해야 한다.

이미 물에 빠져서 내부에 물이 들어오기 시작한 배나 비행기를 탈출하기 위해서는 일시적으로 잠수를 해야 할 수도 있는데, 너무 일찍 공기를 집어넣으면 이것 때문에 동체에서 탈출도 못 하고 거기서 갇혀 죽을 수도 있기 때문이다.
이것은 1996년의 에티오피아 항공 961편 피랍 사건과 최근의 세월호 침몰 사고에서도 실제로 일어났던 일이다. 선실에서 숨진 채 발견된 사람들이 부풀어 오른 구명조끼를 입고 있던 것은 바르게 행동한 것이 아니었다.

저 비행기 피랍 사건도 마찬가지다. 동반 자살을 유도하던 테러리스트 때문에 비행기는 연료가 고갈되어 추락했다. 기장은 필사적인 노력으로 기체를 바다 위에 최대한 안전하게 착수시켰으며, 적절한 대처를 한 공로를 인정받아 나중에 상까지 받았다고 한다. 그러나 170여 명의 승객과 승무원 중 목숨을 부지한 사람은 50명에 그쳤는데, 사망자들은 구명조끼를 기내에서 미리 부풀리는 바람에 침수되고 있는 동체에 갇혀서 최후를 맞이한 경우가 적지 않았다고 한다.

Posted by 사무엘

2014/07/30 08:34 2014/07/30 08:34
, , ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/990

국어, 언어학 잡설

1. '여' 불규칙

ㄱ부터 ㅎ까지
'가다(go), 나다(bring forth), 사다(buy), 자다(sleep), 차다(kick), 타다(get on), 파다(dig)'
라는 용어들을 생각해 보면, 이들은 과거형은
'갔다, 났다, 샀다, 잤다, 찼다, 탔다, 팠다'
라는 아주 규칙적인 패턴으로 활용된다.

그러나 잘 알다시피 '하다'(do)만은..
'하였다' 아니면 '했다'라고 굉장히 이상하게 활용된다. 중등학교 국어 시간엔 이를 '여' 불규칙이라고 배운다.
그런데 어미 '여'가 쓸데없이 붙는 것도 이상한데, 그게 축약되어서 '했다'가 되는 건 또 뭐냐..? '하다' 말고 그 어떤 용언도 활용 시에 ㅏ와 ㅐ가 그런 식으로 연계하여 변하는 경우는 없다.

'가다'의 경우, 다른 'Xㅏ다' 용언과는 달리, 명령형에서 '가거라'라고 생뚱맞은 '거'가 불규칙으로 첨가되기는 한다. 그러나 이 '거'는 명령형에서만 첨가되지 '해서/하여서, 했다/하였다'의 '여'에 비하면 등장이 훨씬 제한적이다.

'갔다', '팠다'처럼 '핬다'라는 단어는 한국어의 역사상 존재한 적이 없었던 걸까? 원래 있긴 했는데 혹시 전설모음 역행동화가 일어나서 '했다'라고 바뀌기라도 한 건 아닐까? 난 잘 모르겠다.

본인은 '바라다'가 자꾸 '바랬다', '바랬는데', '바램'처럼 활용되는 것도 비슷한 맥락의 현상이 아닌가 하고 거의 10년도 넘게 더 전부터 생각해 왔다. '하다'는 '함'이 '햄'으로 바뀌는 건 아니니 둘이 완전히 같은 양상은 아닌지도 모른다.
그리고 이것도 자음 하나만 다른 '자라다'는 활용 과정에서 '라'가 '래'로 바뀌는 현상이 결코 전혀 없으니 참으로 이상하지 않을 수 없다. '자랐다', '자랐는데', '자람' 등.. =_= 신기하다.

2. 지난 학기에 들은 변형 생성 문법 수업의 편린

(1) 아무래도 교재가 영어 원서이고 영어 통사론을 다루는 비중이 적지 않다 보니.. 선생님이 영어 고어 문법 얘기도 종종 하셨다. 그래서 내 머리엔 KJV 영어가 떠오른 적이 적지 않았다.

옛날에는 be + 동사PP가 수동태뿐만 아니라 마치 지금의 have + 동사PP처럼 완료 시제를 나타내기도 했다고 한다. KJV에 "is come"이 왜 이리도 많이 등장하는지 이제 알 것 같다.

(2) have가 의문문으로 등장할 때 Do you have 대신 곧바로 Have가 나오는 거..
난 개인적으로 have ye any meat? (요 21:5)가 곧장 떠오르던데 오늘날에도 이런 패턴이 영국의 일부 방언으로 남아 있다고 한다.
마치 C언어로 치면, C이긴 한데 오늘날 안 쓰는 오리지널 K&R 스타일 C 같은 느낌이다. #include 과감히 생략하고 main 함수에 int나 return 다 생략하고 바로 printf("hello, world!");를 하는... 좋게 말하면 간결하고 나쁘게 말하면 불친절한 스타일 되겠다.

(3) 문법을 설명하는 데도 문장 구조 binary tree를 그려서 노드를 이리 저리 옮기는 게 많다. 마치 빨강 검정 나무의 동작을 다루는 것 같았다. 물론 둘은 개념과 성격은 서로 완전히 다르지만 말이다.
또한, 전산학 자료구조 시간에는 tree 노드를 표현할 때 sibling, child 등 다 중성 어휘를 쓰지만, 언어학에서는 sister, daughter 같은 여성형 어휘를 쓰더라.

프로그래밍 언어와 자연어를 설명하는 이론을 모두 마스터하고 싶다.

Posted by 사무엘

2014/07/28 08:33 2014/07/28 08:33
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/989

C/C++에서 구조체나 클래스는 통상적으로 global scope에서 선언되거나 기껏해야 다른 클래스 내지 namespace의 내부에서 선언된다. 즉, 어차피 비실행문들만 있는 곳에서 선언되는 편이다.
그러나 실행문으로 이뤄져 있는 함수 안에서 이들을 새로 선언하는 것도 문법적으로 가능하다. 다시 말해, 변수를 선언하는 것뿐만 아니라 그 변수들의 type을 결정하는 구조체나 클래스를 즉석에서 선언해 쓰는 것도 가능하다는 뜻이다.

다른 곳에서 두고두고 재사용하는 구조체가 아니라 함수 한 곳에서 튜플 같은 형태로 잠깐만 사용하고 마는 구조체라면, 이런 식으로 함수 안에서 간단히 선언해서 사용하면 좋다. 하긴, 그러고 보니 struct, class, union, enum뿐만 아니라 typedef도 실행문과 비실행문 문맥에서 모두 사용 가능한 물건이다.

함수 안에서 클래스 같은 걸 따로 선언하는 건 C#에서는 가능하지 않으며 C++만의 전유물인 듯하다.
이렇게 함수에서 선언된 자료형은 유효 범위도 마치 지역변수처럼 그 함수 안으로 완전 local하게 한정된다. 그래서 각종 IDE 같은 데에 명칭이 뜨지도 않는다. 지금부터는 이와 관련해서 좀 더 기괴한 이야기들을 풀어 보겠다.

1. 무명 자료형

C/C++에는 '이름 없는' 구조체/클래스/공용체 따위의 개체가 있을 수 있다. '이름 없는' 함수 그 자체만의 선언은 지원되지 않아서 함수형 프로그래밍 패러다임이 도입된 C++0x 이후에서야 람다와 함께 등장한 반면, 이름 없는 복합 자료형이라는 개념은 있었던 것이다.

class {
public:
    int x,y,z;
} obj;

C#이나 자바 스타일이라면 상상도 할 수 없는 일이겠지만, C/C++은 자료형의 선언과 해당 자료형에 속하는 변수의 선언을 동시에 할 수 있다. class OBJ { ... } a,b,c; 도 OBJ a,b,c;나 심지어 int a,b,c;와 개념적으로 같다.
class, struct, enum, union 등을 선언한 뒤에는 닫는 중괄호 다음에 세미콜론을 반드시 붙여야 하는 이유가 바로 이 때문이다.

그런데 이름 없는 자료형은 자료형의 선언과 함께 변수 선언도 같이 해 주는 게 선택이 아닌 '필수'라는 차이가 있다. 그도 그럴 것이, 얘는 이름이 없는 일회용 자료형인 고로 그 자료형을 선언하는 구문이 끝난 뒤에는 그걸 지칭할 방법이 없기 때문이다. 변수가 단 하나라도 같이 선언돼 있어야 나중에 C++11의 auto 라도 써서 그것과 동일한 자료형의 변수를 추가로 만들 수 있을 것이다.

이런 무명 자료형이라는 개념은 대개 한 자료구조 내부에서 구조체와 공용체를 섞어 가며 쓸 때 유용하지만, 그렇잖아도 일회용 성격이 강한 local 자료형에서도 더욱 의미가 있다. 굳이 이름을 생각할 필요 없이 내가 생각하는 복합 자료형을 간단하게 만들어서 쓰게 해 주기 때문이다.
물론 local뿐만 아니라 global scope에서도 무명 자료형을 얼마든지 선언해서 쓸 수 있다. C/C++의 오묘한 면모 중 하나이다.

2. 함수 안에 함수

C/C++은 복합 자료형은 앞서 살펴보았듯이 무명으로 선언할 수 있고, 그 안에 또 다른 복합 자료형을 nested된 형태로 선언하고 집어넣을 수 있다. 그러나 실행되는 코드의 집합인 함수를 그렇게 일종의 값처럼 자유자재로 다룰 수 있지는 않았다.

함수 자체를 다른 함수에다가 전달하는 것은 그나마 함수 포인터가 있으니 불가능하지는 않지만, 그건 자료형, 함수명 등에 대한 작명이 필요하며 기계 중심적이고 융통성이 부족했다. 또한 함수 안에다가 또 일회용으로 간단히 쓰고 마는 함수를 잠깐 선언하는 것도 가능치 않아서 global/class scope 차원에서의 선언이 필요했다. 남는 건 매크로 함수밖에 없지만 이게 얼마나 구조적으로 허접한 물건인지는 역시 설명이 필요하지 않는 수준이고.

void func()
{
    void simple_func(int x) { }

    simple_func(0);
    simple_func(1);
}

nested function은 C와 파스칼의 큰 차이 중 하나이기도 했다. 파스칼은 지원하지만 C/C++ 계열은 지원하지 않았기 때문이다. 마치 가변 길이 배열만큼이나 언어 차원에서 결코 지원되지 않을 금기 봉인 사항이기라도 한가 궁금하다. 다만, 옛날에 gcc던가 극소수 C 컴파일러에서 확장 옵션을 통해서 nested function을 지원하는 걸 본 것 같다.

물론, 중첩 함수를 써서 할 수 있는 일은 중첩 함수라는 개념이 없이도 완전히 똑같이 할 수 있기 때문에 상호 등가 교환이 가능하다. 마치 클래스에서 public과 private 구분을 해 주든, 아니면 전부 싸잡아 public인 struct로 코드를 작성하든.. 이것은 코드의 유지 관리의 편의성 내지 정보 은닉하고만 관계가 있지 프로그래밍 언어의 구조적인 계산 능력과는 무관한 것하고 같은 맥락이다. 그래서 C/C++은 nested 함수라는 개념을 도입하지 않은 듯하다. 정수 타입에 subrange 같은 개념도 없을 정도이니 뭐~

지금이야 람다 덕분에 함수 안에 함수의 선언이 사실상 가능해졌다. 캡처 같은 새로운 개념도 같이 도입됐다. 하지만 이건 일반적인 함수와 개념적으로 같은 물건은 아니다.
C++에서는 (1) 중첩 namespace 안에 들어있는 함수가 얼추 비슷한 개념일 수 있으며, 이것 말고도 좀 더 직접적으로 함수 안에 함수를 만드는 것이 편법 우회 경로로 가능하다. (2) 바로 함수 안에 클래스를 선언하고 멤버 함수를 정의하는 것이다. 이런 식으로.

int main(int argc, char* argv[])
{
    class A {
    public:
        static void Func() { puts("function inside function"); }
    };
    A::Func();
    return 0;
}

특히 static 함수는 this 포인터를 사용하지도 않으니 진짜로 일반 함수와 다를 바가 없다.
함수 안에다 구조체를 정의하는 것으로도 모자라서 완전한 형태의 클래스를 정의하고 멤버 함수를 정의하는 것까지도 가능하다니 놀랍지 않은지?

단, 이런 지역 클래스에서 멤버 함수를 선언할 때는 논리적으로 당연한 제약이 하나 걸린다. 함수의 몸체는 반드시 그 클래스 안에서 저렇게 정의되어야 한다. 안 그러면 아까 무명 자료형에서 변수 선언을 바로 안 해 줄 때처럼 경고가 뜬다.

비주얼 C++의 경우 일단 C4822 경고만 뜨고 그걸 실제로 호출까지 한 경우 링크 에러가 났지만, 요즘은 그 즉시 C3640 에러도 같이 나오는 듯. 링크 에러가 더 친절하게 컴파일 에러로 바뀌었다.
클래스의 밖인 그 함수 몸체 안에서 또 void A::Func() { } 이런 식으로 함수 몸체를 따로 정의하는 건 문법적으로 허용되지 않기 때문이다.

또한, 이런 이유로 인해, 지역 클래스는 static 멤버 함수는 가질 수 있는 반면 static 멤버 변수(=데이터)는 가질 수 없다.
그건 함수 안의 일반 static 변수와 같은 취급을 받으려나 궁금했는데, 만들어 보니 그건 언어 문법 차원에서 허용되지 않으며 곧바로 컴파일 에러가 난다. static const도 허용되지 않는다.

그러고 보니 이름 없는 클래스도 static 멤버 변수를 사실상 가질 수 없을 듯하다. 사실, 이름 없는 클래스에다가 그런 것까지 바라는 것 자체가 변태 도둑놈 심보이긴 하다. ㅎㅎ
멤버 함수야 몸체를 클래스의 선언부 안에다 강제로 집어넣는 식으로 정의할 수 있지만 static 변수는 결국 클래스 밖에서 따로 정의를 해야 하는데, 클래스 이름이 없으니 정의를 할 수 없어서 링크 에러가 나기 때문이다.
이거 정말 복잡한 문제다. C++이 C#/Java하고는 다른 독특 기괴한 면모가 이런 데서 또 발견된다.

Posted by 사무엘

2014/07/25 08:32 2014/07/25 08:32
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/988

라벨, 에디트, 리스트 박스, 콤보 박스, 일반 버튼, 라디오/체크 박스.
이름만 들어도 친숙한 이 물건들은 응용 프로그램의 대화상자에 들어가는 그야말로 필수 GUI 구성요소들이다.

여기에다 리스트 컨트롤, 트리 컨트롤 같은 더 고급스러운 공용 컨트롤까지 있으니 실무에서는 사실 99%에 가까운 일은 기존 컨트롤만으로 다 해치울 수 있다.
사소하게 마음에 안 들고 동작 방식을 좀 고쳐야 하는 건, (1) 이들이 제공하는 owner-draw 옵션(주로 외형 외주) 내지 일부 메시지에 대한 (2) 윈도우 프로시저의 서브클래싱으로 customize 가능하다.

그러나 아주 가끔은, 기존 컨트롤과는 동작 방식이 완전히 다른 새로운 윈도우를 내가 머리부터 발끝까지 직접 구현하여 대화상자에다 집어넣어야 하는 경우가 있다. 기존 컨트롤을 약간만 고치는 정도로는 성이 안 찬다.

본인이 개발한 <날개셋> 한글 입력기의 GUI를 보면 이런 custom 컨트롤들이 적지 않게 보인다. 당장 비트맵 글꼴을 사용하는 자체 에디트 컨트롤은 편집기의 클라이언트 영역뿐만 아니라 대화상자에서 입력란으로도 쓰인다. 그리고 한글 낱자를 뽑아 오는 독특한 스타일의 콤보 박스라든가 문자표 리스트, 글쇠배열 편집 윈도우도 다 자체 개발한 custom 컨트롤이다.

꼭 그렇게까지 특이한 용도의 윈도우가 아니더라도.. 이걸 생각해 보자.
자체적인 키보드 포커스를 받으며, 화살표 key나 마우스 휠로 2차원적인 스크롤이 가능한 형태로 그림 같은 owner-draw 컨텐츠를 출력하는 컨트롤.
쉽게 말해 MFC로 치면 CScrollView에 해당하는 컨트롤이다. 특이할 것 없는 아주 기본적인 기능임에도 불구하고 기존 컨트롤의 서브클래싱만으로는 구현 가능하지 않다.

키보드 포커스를 받지 않으며 스크롤 같은 것도 없이 고정적인 owner draw 그림만을 화면에 달랑 그리는 거라면 쉽다. 기성 컨트롤인 STATIC 윈도우에다 owner draw 스타일을 줘서 WM_DRAWITEM 메시지를 처리하거나, 아예 서브클래싱을 해서 WM_PAINT 메시지를 통째로 가로채면 된다.

그러나 스스로 키보드와 마우스 입력을 처리하는 윈도우라면 독립된 형태로 자체 구현이 불가피하다. 여러 메시지들에 대한 동작을 인위로 고쳐야 하기 때문이다.
<날개셋> 편집기에서 화면 인쇄를 시켰을 때 화면 인쇄 결과를 출력하는 윈도우가 바로 이런 용도로 만들어진 custom control이다.

custom control을 MFC를 써서 개발한다면 응당 CWnd에서 파생된 새로운 클래스를 떠올리게 될 것이다. 이 C++ 클래스는 자신만의 윈도우 클래스 이름을 갖고 있을 것이고 자신을 운영체제에다 등록하는(RegisterClass 호출) 함수도 static 형태로 갖추고 있어야 할 것이다. (응용 프로그램이 실행 초기에 호출함)
그리고 대화상자 리소스에는 그 클래스 이름을 지정해 놓은 custom 컨트롤을 마음껏 생성해 놓는다.

그런데 대화상자의 컨트롤들은 내가 CWnd::Create를 호출하여 만드는 게 아니라 운영체제의 대화상자 관련 함수들이 CreateWindowEx에다가 윈도우 클래스 이름만 달랑 줘서 만들어진다. 이렇게 C++ 언어 체계의 통제를 받지 않고 밖에서 만들어진 HWND에다가 MFC 기반의 C++ 개체는 어떤 메커니즘을 통해 상호 연결시켜야 할까?

단순히 CWnd::FromHandle 함수 같은 걸로 임시 CWnd만 달랑 생성해서 연결하는 게 아니다. 이 custom 컨트롤은 구현체 클래스가 존재하니, 그냥 CWnd가 아니라 내가 만든 전용 CWnd 파생 클래스가 정확히 연결돼야 한다. 그렇게 해야 응용 프로그램 해당 윈도우끼리는 type-safe하지 않고 불편한 메시지를 쓸 필요 없이 C++ 멤버 함수/변수에 직통으로 가능해지니 좋다.

연결하는 방법은 크게 두 가지가 있다. 먼저, C++ 클래스의 생명 주기를 윈도우 자체의 생명 주기와 일치시키는 것이다. 만드는 윈도우 클래스에다가 윈도우 프로시저를 아래와 같이.. MFC의 AfxWndProc와 거의 똑같은 형태로 작성해 준다.

LRESULT CALLBACK CHeapCtrl::_MyWndProc(HWND hWnd, UINT msg, WPARAM w, LPARAM l)
{
    CWnd *pWnd = CWnd::FromHandlePermanent(hWnd);
    if (pWnd==NULL) { pWnd=new CHeapCtrl; pWnd->Attach(hWnd); }
    return AfxCallWndProc(pWnd, hWnd, msg, w, l);
}

이 개체는 언제나 new 연산자를 통해 heap에만 생성된다. 그러므로 PostNcDestroy 함수를 다음과 같이 구현하여 윈도우와 함께 C++ 개체도 같이 소멸되게 해 줘야 한다.

void CHeapCtrl::PostNcDestroy()
{
    delete this;
}

또한 대화상자 내부에서는 CHeapCtrl을 언제나 포인터를 통해 접근해야 한다.

CHeapCtrl *p = DYNAMIC_DOWNCAST(CHeapCtrl, GetDlgItem(IDC_MYCONTROL));

둘째 방법은.. 대화상자이니까 가능한 더 간단한 방법이다. 대화상자 클래스에다가 해당 컨트롤 클래스의 개체를 선언한다. 윈도우 클래스를 등록할 때 WNDCLASS 구조체에다가 윈도우 프로시저는 그냥 쿨하게 DefWindowProc이라고 주면 된다.

CStackCtrl m_wndCustomCtrl;

그리고 윈도우와 C++ 개체를 그냥 이렇게 컨트롤 변수로 연결해 버린다.

void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_MYCONTROL, m_wndCustomCtrl);
}

이 경우, CStackCtrl은 스택, 아니 최소한 대화상자 클래스와 동일한 메모리에 생성된다. 그래서 개체를 포인터를 거치지 않고 더 간편하게 접근할 수 있을 뿐만 아니라, 대화상자 같은 윈도우 개체가 사라진 뒤에도 C++ 객체가 갖고 있던 내부 정보에 접근을 할 수 있다. PostNcDestroy 처리가 필요하지 않음은 두 말할 나위도 없고. 여러 모로 더 속 편하다.

윈도우 클래스상으로 이 윈도우는 프로시저가 아무 특수한 일도 하지 않는 DefWindowProc로 지정되어 있지만, DDX_Control 함수는 윈도우 프로시저를 서브클래싱하고 저 윈도우의 핸들을 우리가 준 CStackCtrl에다가 연결해 준다. 그래서 각종 메시지가 발생했을 때 CStackCtrl의 메시지 맵에 등록된 핸들러 함수가 호출되는 것이다.

윈도우 클래스와 MFC 클래스를 연결한 건 시작일 뿐이고 본격적인 코딩은 지금부터이다. 그야말로 산 넘어 산이다.
WM_PAINT와 필요하다면 WM_SIZE를 처리해야 할 것이고, 키보드 포커스를 받는 물건으로 계획을 했으니 WM_GETDLGCODE를 잡아서 스크롤을 위해 최소한 DLGC_WANTARROWS 정도는 되돌려야 할 것이다. 다른 단축키 같은 걸 추가로 인식하려면 DLGC_WANTCHARS도 필요할 테고.

스크롤이 되는 윈도우라면 요즘은 마우스 휠 인식은 필수다. WM_MOUSEWHEEL을 처리해야 한다. SystemParametersInfo(SPI_GETWHEELSCROLLLINES, ...) 을 호출하여 마우스 휠의 움직임 단위를 감지하여 동작할 필요가 있다. 특히 n줄이냐, 아예 페이지 단위냐(WHEEL_PAGESCROLL)를 잘 판단해야 한다.

만드는 컨트롤에 확대/축소 배율이 존재한다면 Ctrl+휠로 배율 조절을 시키는 게 요즘 트렌드다.
또한, 전통적인 세로 스크롤용 마우스 휠뿐만이 아니라 가로 마우스 휠 WM_MOUSEHWHEEL (wheel 앞에 H 추가)이라는 게 있다는 것도 알아 두면 좋다. 마우스 현물보다는 손가락 제스처를 이용한 스크롤 기능이 있는 노트북 터치패드로 생성되는 듯하다.

어디 그 뿐이랴? 표준 인터페이스에는 아예 마우스 휠을 눌러서 구동하는 '자동 스크롤' 모드도 있다. WM_MBUTTONDOWN(마우스 가운데 버튼) 되시겠다. 이건 아까와는 반대로 마우스 실물이 아닌 노트북 터치패드로는 구경하기 힘든 모드이다.

.마우스로 화면을 끌어서 스크롤이 되게 하려면 WM_LBUTTONDOWN, WM_MOUSEMOVE 같은 메시지들을 처리하면 될 것이고.
아, 이런 것보다 더 중요하면서도 스크롤 윈도우에서 상당히 번거로운 작업이 하나 있는데 그건 바로 WM_HSCROLL 및 WM_VSCROLL 메시지이다. 우리의 편견과는 달리,처음에 SetScrollInfo 함수 하나로 전체 스크롤 크기와 영역만 지정해 준다고 해서 그 다음부터 모든 스크롤 처리가 자동으로 되는 게 아니기 때문이다.

스크롤 메시지는 사용자가 스크롤 바의 화살표(한 칸씩)를 눌렀을 때, 스크롤 바를 드래그하고 있을 때, 스크롤 바 옆을 눌렀을 때(한 페이지 씩) 등등의 상황별로 서로 다른 정보가 담긴 채로 전달된다. 그리고 이때 실제로 화면을 얼마만치 스크롤시키고 어떤 처리를 할지는 전적으로 해당 응용 프로그램에 달려 있다. 운영체제가 자동으로 해 주는 일은 없다. 이걸 처리하지 않으면 사용자가 스크롤 바를 눌러도 다른 반응이 발생하지 않는다.

바로 이런 특성 때문에 사용자가 스크롤 바를 끌고 있는 동안 화면이 바로 갱신될지, 혹은 곧장은 아니고 스크롤 바의 드래그가 끝난 뒤에야 화면을 갱신할지 같은 것도 응용 프로그램마다 달리 동작할 수 있다. 물론 반응성이 좋은 프로그램이라면 어지간하면 즉각 화면이 갱신되는 게 좋겠지만 말이다.

그리고 요즘은 화면 캡처 유틸리티들이 스크롤 캡처를 지원하는데, 이 역시 생각보다 꼼수를 써서 구현돼 있다. 화면에다 별도의 표식을 그려 넣은 뒤, 캡처 대상 윈도우에다 스크롤 메시지를 보내고 그 표시가 얼마나 이동했는지를 수동으로 점검한다. 위와 같은 높은 자유도로 인해, 저렇게 하지 않으면 그 스크롤 분량을 정량적으로 알아낼 수 없기 때문이다. (스크롤 바가 이동한 양과 그에 따라 지금 화면이 실제로 이동한 픽셀수 사이의 인과관계)

화면이 스크롤되면 ScrollWindowEx 함수를 호출해서 이미 그려진 화면은 운영체제가 제공하는 스크롤 기능으로 넘기고 새로 칠해져야 하는 최소한의 부분만 새로 칠하는 '평범한 프로그램'이라면.. 저 꼼수가 통한다.
그러나 스크롤 될 때마다 화면을 몽땅 지우고 새로 그리는 프로그램이라면, 저 표식도 지워지기 때문에 스크롤 캡처를 할 수 없게 된다.

이상이다. 윈도우의 스크롤 기능까지 얘기하다 보니 말이 또 길어졌다. 여기에도 뭔가 정량적인 동작 패턴이 분명 있는 듯한데, 그것만 추려내기는 쉽지 않아 보인다.
공통된 기능을 운영체제가 API 함수로든, 공용 컨트롤 윈도우로든 뭘로든 좀 제공을 하지 않는다면 역시나 프로그래머들이 비슷한 기능을 여전히 자체적으로 중복 구현할 수밖에 없을 것이다.

Posted by 사무엘

2014/07/22 08:36 2014/07/22 08:36
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/987

내가 컴퓨터 프로그래밍을 시작하기 전에, 심지어 철도를 빨기 전에.. 정말 까마득한 먼 옛날엔
자동차를 머리부터 발끝까지 얼마나 심취해서 진심으로 쪽쪽 빨고 지냈는지...;;

1991년, 지금으로부터 거의 23년 전에 혼자 다른 책을 베끼고 온갖 사견을 덧붙여서 만들었던 자동차 화보-_-;;가 고향집에서 뒤늦게 발견되었다. 나의 초딩 3학년 시절의 작품이다.
물론 사진 찍는 건 어머니께서 도와 주셨다. 디카가 없던 시절이니 당연히 필카로 찍고 현상해서 찾아 와서 붙였다.

사용자 삽입 이미지사용자 삽입 이미지

어린 눈에는 자동차별로 타코미터의 존재 여부, 파워윈도우의 존재 여부, 그리고 뒷좌석 중앙에 팔걸이의 존재 여부가 특별하게 다가왔던가 보다.

사용자 삽입 이미지사용자 삽입 이미지

르망, 각그랜저, 그리고 콩코드, 로얄 시리즈 등.. 정말 추억의 올드카들이다. 지금은 저 차 번호들은 존재할 가능성이 0에 한없이 수렴하므로 번호판을 굳이 가리지는 않았다.

사용자 삽입 이미지사용자 삽입 이미지
그 당시 우리집 자가용이었던 엑셀의 카탈로그 내지 취급 설명서를 베껴서 그린 거지 싶다. ㅎㅎ

사용자 삽입 이미지사용자 삽입 이미지
그 당시 액정 디지털 계기판, 그리고 헤드라이트에까지 와이퍼가 달려 있던 임페리얼을 무척 신기하게 여기고 인상깊게 관찰했었다.

사용자 삽입 이미지사용자 삽입 이미지
대략 이런 내용.
걍 이 취미를 그대로 유지해서 현대 자동차에라도 입사했으면 돈은 더 많이 벌었겠다는 생각이 폭풍처럼 든다. ㅠ.ㅠ

Posted by 사무엘

2014/07/19 08:22 2014/07/19 08:22
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/986

« Previous : 1 : ... 140 : 141 : 142 : 143 : 144 : 145 : 146 : 147 : 148 : ... 230 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2026/08   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

Site Stats

Total hits:
4000805
Today:
981
Yesterday:
6203