Slide 1

Slide 1 text

이흥섭 2018년 8월 고랭코리아 밋업 재제작기

Slide 2

Slide 2 text

이흥섭 2018년 8월 고랭코리아 밋업 재제작기 안녕하세요.

Slide 3

Slide 3 text

이흥섭 2018년 8월 고랭코리아 밋업 재제작기 2018년 8월 고랭코리아 밋업에서 〈한글라이즈 재제작기〉를 발표하는

Slide 4

Slide 4 text

이흥섭 sublee 이흥섭이라고 합니다. 반갑습니다.

Slide 5

Slide 5 text

•야생의 땅: 듀랑고 •카트라이더 코인러시 •카트라이더 대시 넥슨 왓 스튜디오 서버아키텍트 저는 넥슨 왓 스튜디오에서 서버아키텍트를 맡고 있고

Slide 6

Slide 6 text

•야생의 땅: 듀랑고 •카트라이더 코인러시 •카트라이더 대시 넥슨 왓 스튜디오 서버아키텍트 얼마 전 〈야생의 땅: 듀랑고〉를 출시했습니다.

Slide 7

Slide 7 text

•what-studio/profiling •sublee/trueskill •what-studio/tossi •hangulize/hangulize 오픈소스 2744 385 110 53 개수는 2018년 9월 6일 기준

Slide 8

Slide 8 text

•what-studio/profiling •sublee/trueskill •what-studio/tossi •hangulize/hangulize 오픈소스 2744 385 110 53 개수는 2018년 9월 6일 기준 한편으론 틈틈이 오픈소스 활동도 하고 있어요.

Slide 9

Slide 9 text

•what-studio/profiling •sublee/trueskill •what-studio/tossi •hangulize/hangulize 오픈소스 2744 385 110 53 개수는 2018년 9월 6일 기준 제가 주축이 된 오픈소스 프로젝트 중에 별이 많은 것만 한 번 추려봤는데

Slide 10

Slide 10 text

•what-studio/profiling •sublee/trueskill •what-studio/tossi •hangulize/hangulize 오픈소스 2744 385 110 53 개수는 2018년 9월 6일 기준 이 중에선 가장 별이 적은 〈한글라이즈〉가 오늘 발표의 주제입니다.

Slide 11

Slide 11 text

Go 코딩 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루

Slide 12

Slide 12 text

Go 코딩 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루 우리가 새로운 언어를 습득해 나갈 때 아마 이런 과정을 거치게 될 것 같은데

Slide 13

Slide 13 text

Go 코딩 협업 장난감 옹알이 실무 리뷰 구루 고랭코리아 진지한 장난감 Go 언어의 경우 고랭코리아 여러분은 대부분 이쯤에 계실 것 같습니다.

Slide 14

Slide 14 text

Go 코딩 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루 저 반면 저는 여기 쯤에 있어요.

Slide 15

Slide 15 text

Go 코딩 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루 저 Go 코딩은 매일 하고 있지만 아직 본격적으로 실무에 써보진 못 했습니다.

Slide 16

Slide 16 text

Go 코딩 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루 저 한글라이즈도 제 본업과는 전혀 무관하게

Slide 17

Slide 17 text

지난 3개월 일과 후 취미코딩 지난 3개월동안 매진했던 일과 후 취미코딩이었어요.

Slide 18

Slide 18 text

지난 3개월 일과 후 취미코딩 그러다보니 아마 이 발표에서 제가 여러분에게

Slide 19

Slide 19 text

지난 3개월 일과 후 취미코딩 Go에 대한 새로운 지식을 전해 드리진 못 할 것 같은데

Slide 20

Slide 20 text

지난 3개월 일과 후 취미코딩 그래도 취미로 익히면서 재밌었던 점을 소개해보려고 합니다.

Slide 21

Slide 21 text

지난 3개월 일과 후 취미코딩 학예회 보듯이 재밌게 봐주시면 감사하겠습니다.

Slide 22

Slide 22 text

1. 한글라이즈 2. Go 3. 이룬 것 차례

Slide 23

Slide 23 text

1. 한글라이즈 2. Go 3. 이룬 것 차례 우선 오늘 발표의 내용은 이렇습니다.

Slide 24

Slide 24 text

1. 한글라이즈 2. Go 3. 이룬 것 차례 제가 만들고 있는 한글라이즈에 대해 소개하고

Slide 25

Slide 25 text

1. 한글라이즈 2. Go 3. 이룬 것 차례 한글라이즈를 Go로 만들면서 느낀 흥미로웠던 점에 대해서 말씀드릴게요.

Slide 26

Slide 26 text

1. 한글라이즈 2. Go 3. 이룬 것 차례 그리고 발표 제목에 "재제작기"라고 적었듯이

Slide 27

Slide 27 text

1. 한글라이즈 2. Go 3. 이룬 것 차례 8년 전에 파이썬으로 만들었던 한글라이즈를 이번에 Go로 다시 구현한 것이거든요.

Slide 28

Slide 28 text

1. 한글라이즈 2. Go 3. 이룬 것 차례 예전과 비교해서 어떤 성과를 이뤘는지 보여드리겠습니다.

Slide 29

Slide 29 text

1. 한글라이즈 그럼 지금부터 한글라이즈가 무엇이고 이 프로젝트가 어떻게 시작됐는지

Slide 30

Slide 30 text

1. 한글라이즈 그리고 어떤 원리로 돌아가는지 소개해드릴게요.

Slide 31

Slide 31 text

외국어 단어를 한글로 옮겨 적는 도구 한글라이즈

Slide 32

Slide 32 text

외국어 단어를 한글로 옮겨 적는 도구 한글라이즈 한글라이즈는 외국어 단어를 한글로 옮겨 적어주는 도구예요.

Slide 33

Slide 33 text

말소리를 음성 문자로 옮겨 적음.다음사전 의미를 옮기는 번역(translation)과는 달라요. 전사(transcription) 좀 더 정확히는 "전사"라고 부르는데

Slide 34

Slide 34 text

말소리를 음성 문자로 옮겨 적음.다음사전 의미를 옮기는 번역(translation)과는 달라요. 전사(transcription) 다음사전에서 찾아보면 말소리를 음성 문자로 옮겨 적는 걸 뜻한다고 합니다.

Slide 35

Slide 35 text

말소리를 음성 문자로 옮겨 적음.다음사전 의미를 옮기는 번역(translation)과는 달라요. 전사(transcription) 한글라이즈의 역할은 외국어 단어의 의미를 해석해서

Slide 36

Slide 36 text

말소리를 음성 문자로 옮겨 적음.다음사전 의미를 옮기는 번역(translation)과는 달라요. 전사(transcription) 우리말로 번역하는 게 아니라 발음만 한글로 표기하는 것이죠.

Slide 37

Slide 37 text

Go▶ 고(전사) ▶ 가(번역) 영어 단어 "Go"를 예로 들면

Slide 38

Slide 38 text

Go▶ 고(전사) ▶ 가(번역) 발음 그대로 "고"로 옮기는 건 전사고

Slide 39

Slide 39 text

Go▶ 고(전사) ▶ 가(번역) 의미를 살려 우리말 "가"로 옮기는 건 번역입니다.

Slide 40

Slide 40 text

PlayOverwatch Lúcio ▶ 루시우 花村 ▶ 하나무라 인명 지명 Overwatch Wiki

Slide 41

Slide 41 text

PlayOverwatch Lúcio ▶ 루시우 花村 ▶ 하나무라 인명 지명 Overwatch Wiki 전사는 인명이나 지명같은 고유명사나 외래어를 우리말로 옮길 때 필요합니다.

Slide 42

Slide 42 text

PlayOverwatch Lúcio ▶ 루시우 花村 ▶ 하나무라 인명 지명 Overwatch Wiki 지명인 "하나무라"를 굳이 "꽃 마을"이라고 뜻을 번역해서 옮기지는 않겠죠.

Slide 43

Slide 43 text

국립국어원이 정한 외래어 네이밍 컨벤션 외래어 표기법 이렇게 외래어를 한글로 전사할 때 우리는

Slide 44

Slide 44 text

국립국어원이 정한 외래어 네이밍 컨벤션 외래어 표기법 귀에 들리는 대로 주먹구구식으로 옮기는 대신

Slide 45

Slide 45 text

국립국어원이 정한 외래어 네이밍 컨벤션 외래어 표기법 국립국어원에서 정한 "외래어 표기법"을 따라야 합니다.

Slide 46

Slide 46 text

국립국어원이 정한 외래어 네이밍 컨벤션 외래어 표기법 코딩할 때 따르는 네이밍 컨벤션과 비슷하다고 보면 될 것 같아요.

Slide 47

Slide 47 text

국립국어원이 정한 외래어 네이밍 컨벤션 외래어 표기법 모두가 외래어 표기법을 잘 따르는 건 아니지만

Slide 48

Slide 48 text

국립국어원이 정한 외래어 네이밍 컨벤션 외래어 표기법 그래도 이게 있는 덕분에 외래어의 한글표기가 일관성을 어느정도 지켜갈 수 있는 거죠.

Slide 49

Slide 49 text

Cappuccino이탈리아어 ▶ 몇 가지 예시를 들어볼게요.

Slide 50

Slide 50 text

Cappuccino이탈리아어 ▶ 익숙한 이탈리아어 단어인 "Cappuccino"입니다.

Slide 51

Slide 51 text

Cappuccino이탈리아어 ▶ 캡푸씨노…? 어쩌면 "캡푸씨노"라고 옮겨도 말이 될 것 같은데

Slide 52

Slide 52 text

Cappuccino이탈리아어 ▶ 카푸치노 우린 외래어 표기법에 따라서 이 단어를 "카푸치노"라고 옮깁니다.

Slide 53

Slide 53 text

Cappuccino이탈리아어 ▶ 카푸치노 "티라미수", "누텔라", "브로콜리"같이 이탈리아어에서 온 외래어는

Slide 54

Slide 54 text

Cappuccino이탈리아어 ▶ 카푸치노 대체로 외래어 표기법을 잘 따르는 것 같습니다.

Slide 55

Slide 55 text

宮本茂일본어 ▶ 이번엔 일본어입니다. 일본 사람 이름이에요.

Slide 56

Slide 56 text

宮本茂일본어 ▶ 궁본무…? 아마 한자를 잘 안다면 우리말 한자음을 따서 "궁본무"라고 옮길 수도 있을 것 같아요.

Slide 57

Slide 57 text

宮本茂일본어 ▶ 미야모토 시게루 이 이름을 표기법대로 옮기면 "미야모토 시게루"가 되는데

Slide 58

Slide 58 text

宮本茂일본어 ▶ 미야모토 시게루 우리말 한자음이 아닌 일본어 한자음을 따른 겁니다.

Slide 59

Slide 59 text

宮本茂일본어 ▶ 미야모토 시게루 〈슈퍼마리오〉를 만든 분으로 게임 업계에서 전설적인 분의 이름이죠.

Slide 60

Slide 60 text

Χίος그리스어 ▶ 이건 그리스에 있는 한 섬의 이름이에요. "Xioc"처럼 생기긴 했는데

Slide 61

Slide 61 text

Χίος그리스어 ▶ 히오스 "히오스"라고 옮깁니다.

Slide 62

Slide 62 text

ピカチュウ일본어 ▶ 피카츄 때론 표기법대로 쓰는 게 불편할 수도 있어요. 일본어 이름인 "피카츄"의 경우

Slide 63

Slide 63 text

ピカチュウ일본어 ▶ 피카추 외래어 표기법에 따르면 "츄"가 아닌 "추"로 표기해야 합니다.

Slide 64

Slide 64 text

• ピカチュウ ▶ 피카츄 •靑島 ▶ 칭따오 • Chevrolet ▶ 쉐보레 어디까지나 권고사항 피카추 칭다오 셰브럴레이 하지만 외래어 표기법은 어디까지나 권고사항일 뿐이라서

Slide 65

Slide 65 text

• ピカチュウ ▶ 피카츄 •靑島 ▶ 칭따오 • Chevrolet ▶ 쉐보레 어디까지나 권고사항 피카추 칭다오 셰브럴레이 이미 다른 표기가 널리 퍼져 있는 브랜드라면 국립국어원에서도 그쪽의 손을 들어주고 있습니다.

Slide 66

Slide 66 text

제1항 외래어는 국어의 현용 24 자모만으로 적는다. 제2항 외래어의 1 음운은 원칙적으로 1 기호로 적는다. 제3항 받침에는 ㄱ, ㄴ, ㄹ, ㅁ, ㅂ, ㅅ, ㅇ만을 쓴다. 제4항 파열음 표기에는 된소리를 쓰지 않는 것을 원칙으로 한다. 제5항 이미 굳어진 외래어는 관용을 존중하되, 그 범위와 용례는 따로 정한다. 외래어 표기법 자음 반모음 모음 국제 음성 기호 한글 국제 음성 기호 한글 국제 음성 기호 한글 모음 앞 자음 앞 또는 어 말 p ㅍ ㅂ, 프 j 이 i 이 b ㅂ 브 ɥ 위 y 위 t ㅌ ㅅ, 트 w 오, 우 e 에 d ㄷ 드 φ 외 k ㅋ ㄱ, 크 ɛ 에 g ㄱ 그 ɛ̃ 앵 f ㅍ 프 œ 외 v ㅂ 브 œ̃ 욍 θ ㅅ 스 æ 애 ð ㄷ 드 a 아 s ㅅ 스 ɑ 아

Slide 67

Slide 67 text

제1항 외래어는 국어의 현용 24 자모만으로 적는다. 제2항 외래어의 1 음운은 원칙적으로 1 기호로 적는다. 제3항 받침에는 ㄱ, ㄴ, ㄹ, ㅁ, ㅂ, ㅅ, ㅇ만을 쓴다. 제4항 파열음 표기에는 된소리를 쓰지 않는 것을 원칙으로 한다. 제5항 이미 굳어진 외래어는 관용을 존중하되, 그 범위와 용례는 따로 정한다. 외래어 표기법 자음 반모음 모음 국제 음성 기호 한글 국제 음성 기호 한글 국제 음성 기호 한글 모음 앞 자음 앞 또는 어 말 p ㅍ ㅂ, 프 j 이 i 이 b ㅂ 브 ɥ 위 y 위 t ㅌ ㅅ, 트 w 오, 우 e 에 d ㄷ 드 φ 외 k ㅋ ㄱ, 크 ɛ 에 g ㄱ 그 ɛ̃ 앵 f ㅍ 프 œ 외 v ㅂ 브 œ̃ 욍 θ ㅅ 스 æ 애 ð ㄷ 드 a 아 s ㅅ 스 ɑ 아 외래어 표기법은 이런 규칙집으로 이뤄져 있습니다.

Slide 68

Slide 68 text

제1항 외래어는 국어의 현용 24 자모만으로 적는다. 제2항 외래어의 1 음운은 원칙적으로 1 기호로 적는다. 제3항 받침에는 ㄱ, ㄴ, ㄹ, ㅁ, ㅂ, ㅅ, ㅇ만을 쓴다. 제4항 파열음 표기에는 된소리를 쓰지 않는 것을 원칙으로 한다. 제5항 이미 굳어진 외래어는 관용을 존중하되, 그 범위와 용례는 따로 정한다. 외래어 표기법 자음 반모음 모음 국제 음성 기호 한글 국제 음성 기호 한글 국제 음성 기호 한글 모음 앞 자음 앞 또는 어 말 p ㅍ ㅂ, 프 j 이 i 이 b ㅂ 브 ɥ 위 y 위 t ㅌ ㅅ, 트 w 오, 우 e 에 d ㄷ 드 φ 외 k ㅋ ㄱ, 크 ɛ 에 g ㄱ 그 ɛ̃ 앵 f ㅍ 프 œ 외 v ㅂ 브 œ̃ 욍 θ ㅅ 스 æ 애 ð ㄷ 드 a 아 s ㅅ 스 ɑ 아 국립국어원 홈페이지에서 누구나 자유롭게 볼 수 있죠.

Slide 69

Slide 69 text

제1항 외래어는 국어의 현용 24 자모만으로 적는다. 제2항 외래어의 1 음운은 원칙적으로 1 기호로 적는다. 제3항 받침에는 ㄱ, ㄴ, ㄹ, ㅁ, ㅂ, ㅅ, ㅇ만을 쓴다. 제4항 파열음 표기에는 된소리를 쓰지 않는 것을 원칙으로 한다. 제5항 이미 굳어진 외래어는 관용을 존중하되, 그 범위와 용례는 따로 정한다. 외래어 표기법 자음 반모음 모음 국제 음성 기호 한글 국제 음성 기호 한글 국제 음성 기호 한글 모음 앞 자음 앞 또는 어 말 p ㅍ ㅂ, 프 j 이 i 이 b ㅂ 브 ɥ 위 y 위 t ㅌ ㅅ, 트 w 오, 우 e 에 d ㄷ 드 φ 외 k ㅋ ㄱ, 크 ɛ 에 g ㄱ 그 ɛ̃ 앵 f ㅍ 프 œ 외 v ㅂ 브 œ̃ 욍 θ ㅅ 스 æ 애 ð ㄷ 드 a 아 s ㅅ 스 ɑ 아 하지만 워낙 복잡해서 아무리 잘 따르려 노력해도 틀리는 경우가 많습니다.

Slide 70

Slide 70 text

•정기적으로 각 외래어의 한글 표기 결정 • 언론에 보도되는 이름 중심 정부·언론 외래어 심의 공동위원회 그래서 바른 말 쓰기를 특히 중요하게 여기는 정부와 언론 쪽에선

Slide 71

Slide 71 text

•정기적으로 각 외래어의 한글 표기 결정 • 언론에 보도되는 이름 중심 정부·언론 외래어 심의 공동위원회 외래어 표기법이 잘 지켜지고 있는지 평가하고

Slide 72

Slide 72 text

•정기적으로 각 외래어의 한글 표기 결정 • 언론에 보도되는 이름 중심 정부·언론 외래어 심의 공동위원회 정기적으로 공식 외래어 표기를 발표하는 위원회를 두고 있어요.

Slide 73

Slide 73 text

•정기적으로 각 외래어의 한글 표기 결정 • 언론에 보도되는 이름 중심 정부·언론 외래어 심의 공동위원회 "정부·언론 외래어 심의 공동위원회"라는 곳인데 코드리뷰어 집단이라고 생각하면 될 것 같습니다.

Slide 74

Slide 74 text

제92차 정부·언론외래어심의공동위원회 심의 결정안 (인명 52건, 일반용어 1건-재심의 2건) • 아베라, 암살라 Amsale Aberra 1954(?1953)~ 에티오피아 여성 기업가·디자이너. 암살라(Amsale) 그룹 대표 겸 디자 인 총책임자. 유행을 좇지 않으면서 세련된 클래식 모던을 강조하는 디자인으로 유명함. • 아벨란제, 주앙 João Havelange 1916~ 국제축구연맹(FIFA) 회장(1974~1998). 브라질 인. • 그루벨, 루스 Ruth M. Grubel 1950~ 미국 교육가·선교사. 일본 간사이(關西)학원 원장(2007. 4.~ ).

Slide 75

Slide 75 text

제92차 정부·언론외래어심의공동위원회 심의 결정안 (인명 52건, 일반용어 1건-재심의 2건) • 아베라, 암살라 Amsale Aberra 1954(?1953)~ 에티오피아 여성 기업가·디자이너. 암살라(Amsale) 그룹 대표 겸 디자 인 총책임자. 유행을 좇지 않으면서 세련된 클래식 모던을 강조하는 디자인으로 유명함. • 아벨란제, 주앙 João Havelange 1916~ 국제축구연맹(FIFA) 회장(1974~1998). 브라질 인. • 그루벨, 루스 Ruth M. Grubel 1950~ 미국 교육가·선교사. 일본 간사이(關西)학원 원장(2007. 4.~ ). 이건 외래어 심의위가 발표한 표기 심의 결정안 중 하나인데

Slide 76

Slide 76 text

제92차 정부·언론외래어심의공동위원회 심의 결정안 (인명 52건, 일반용어 1건-재심의 2건) • 아베라, 암살라 Amsale Aberra 1954(?1953)~ 에티오피아 여성 기업가·디자이너. 암살라(Amsale) 그룹 대표 겸 디자 인 총책임자. 유행을 좇지 않으면서 세련된 클래식 모던을 강조하는 디자인으로 유명함. • 아벨란제, 주앙 João Havelange 1916~ 국제축구연맹(FIFA) 회장(1974~1998). 브라질 인. • 그루벨, 루스 Ruth M. Grubel 1950~ 미국 교육가·선교사. 일본 간사이(關西)학원 원장(2007. 4.~ ). 아버라, 암살러 그루블 심의위에서도 드물게 틀리는 경우가 있습니다.

Slide 77

Slide 77 text

제92차 정부·언론외래어심의공동위원회 심의 결정안 (인명 52건, 일반용어 1건-재심의 2건) • 아베라, 암살라 Amsale Aberra 1954(?1953)~ 에티오피아 여성 기업가·디자이너. 암살라(Amsale) 그룹 대표 겸 디자 인 총책임자. 유행을 좇지 않으면서 세련된 클래식 모던을 강조하는 디자인으로 유명함. • 아벨란제, 주앙 João Havelange 1916~ 국제축구연맹(FIFA) 회장(1974~1998). 브라질 인. • 그루벨, 루스 Ruth M. Grubel 1950~ 미국 교육가·선교사. 일본 간사이(關西)학원 원장(2007. 4.~ ). 아버라, 암살러 그루블 원 단어의 발음을 잘못 유추하는 바람에 표기를 잘못 정하는 경우가 종종 있다고 해요.

Slide 78

Slide 78 text

•세계의 말과 글 •끝소리 박종성 @iceager

Slide 79

Slide 79 text

•세계의 말과 글 •끝소리 박종성 @iceager 한편 예전부터 외래어 표기법에 큰 관심을 보인 분이 있는데

Slide 80

Slide 80 text

•세계의 말과 글 •끝소리 박종성 @iceager 바로 박종성 님입니다.

Slide 81

Slide 81 text

•세계의 말과 글 •끝소리 박종성 @iceager 종성 님은 "세계의 말과 글"이라는 블로그와 "끝소리"라는 페이스북 페이지에서

Slide 82

Slide 82 text

•세계의 말과 글 •끝소리 박종성 @iceager 외래어 표기법이나 여러가지 언어에 대한 글을 연재하고 계세요.

Slide 83

Slide 83 text

•세계의 말과 글 •끝소리 박종성 @iceager 연재하는 글이 굉장히 깊고 재밌으니

Slide 84

Slide 84 text

•세계의 말과 글 •끝소리 박종성 @iceager 혹시 이 발표가 흥미롭다면 한 번 들어가 보길 추천해드립니다.

Slide 85

Slide 85 text

•세계의 말과 글 •끝소리 외래어 심의 위원 박종성 @iceager 종성 님은 작년부터는 글 연재 이외에

Slide 86

Slide 86 text

•세계의 말과 글 •끝소리 외래어 심의 위원 박종성 @iceager 외래어 심의위 위원으로도 활동하고 계십니다.

Slide 87

Slide 87 text

정기적으로 회의를 열어 용례를 정하는 것으 로는 한계가 있다. 외래어 표기 심의 방식이 자동화되어 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다. http://iceager.egloos.com/2610028

Slide 88

Slide 88 text

정기적으로 회의를 열어 용례를 정하는 것으 로는 한계가 있다. 외래어 표기 심의 방식이 자동화되어 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다. http://iceager.egloos.com/2610028 8년 전, 종성 님은 블로그에 이런 글을 쓰셨어요.

Slide 89

Slide 89 text

정기적으로 회의를 열어 용례를 정하는 것으 로는 한계가 있다. 외래어 표기 심의 방식이 자동화되어 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다. http://iceager.egloos.com/2610028 정기적으로 회의를 열어 용례를 정하는 것으로는 한계가 있다.

Slide 90

Slide 90 text

정기적으로 회의를 열어 용례를 정하는 것으 로는 한계가 있다. 외래어 표기 심의 방식이 자동화되어 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다. http://iceager.egloos.com/2610028 외래어 표기 심의 방식이 자동화되어

Slide 91

Slide 91 text

정기적으로 회의를 열어 용례를 정하는 것으 로는 한계가 있다. 외래어 표기 심의 방식이 자동화되어 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다. http://iceager.egloos.com/2610028 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다.

Slide 92

Slide 92 text

강범모, 《언어: 풀어 쓴 언어학 개론》(2005) 잠깐 샛길로 빠지면, 제가 대학교 다닐 때 제일 좋아했던 강의는 〈언어학 개론〉이었거든요.

Slide 93

Slide 93 text

강범모, 《언어: 풀어 쓴 언어학 개론》(2005) 언어학은 사람이 구사하는 언어를 연구하는 과학분야인데

Slide 94

Slide 94 text

강범모, 《언어: 풀어 쓴 언어학 개론》(2005) 학생 절반이 수능시험의 언어영역 생각하고 들어왔다가

Slide 95

Slide 95 text

강범모, 《언어: 풀어 쓴 언어학 개론》(2005) 첫 강의만 듣고 대거 취소했던 강의이긴 하지만 저에겐 인생 강의였습니다.

Slide 96

Slide 96 text

강범모, 《언어: 풀어 쓴 언어학 개론》(2005) 언어학을 전공한 건 아니더라도 늘 덕심을 갖고 있었죠.

Slide 97

Slide 97 text

정기적으로 회의를 열어 용례를 정하는 것으 로는 한계가 있다. 외래어 표기 심의 방식이 자동화되어 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다. http://iceager.egloos.com/2610028 그런 전 종성 님의 이 글을 보고 깊은 감명을 받았어요.

Slide 98

Slide 98 text

정기적으로 회의를 열어 용례를 정하는 것으 로는 한계가 있다. 외래어 표기 심의 방식이 자동화되어 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다. http://iceager.egloos.com/2610028 외래어 표기법이 자동화되면 당장 저에게도 도움될 것 같았고

Slide 99

Slide 99 text

정기적으로 회의를 열어 용례를 정하는 것으 로는 한계가 있다. 외래어 표기 심의 방식이 자동화되어 한글로 표기하고 싶은 외국어를 입력하자마자 한글 표기가 나와야 한다. http://iceager.egloos.com/2610028 그걸 만드는 과정도 굉장히 재밌어 보였죠.

Slide 100

Slide 100 text

그래서 덥석 물었습니다.

Slide 101

Slide 101 text

아쉽게도 비공개 덧글이고 암호도 잊어서 뭐라고 썼었는진 모르겠지만

Slide 102

Slide 102 text

그렇게 종성 님과 둘이서 외래어 표기법을 자동화하기 시작했어요.

Slide 103

Slide 103 text

파이썬

Slide 104

Slide 104 text

파이썬 당시엔 한창 파이썬을 익히는 중이어서 파이썬으로 개발했고

Slide 105

Slide 105 text

>>> from hangulize import * >>> hangulize(u'Cappuccino', 'ita') u'카푸치노' 옛 한글라이즈 이런 식으로 파이썬 환경에서 쓸 수 있는 "hangulize" 라이브러리를 만들었습니다.

Slide 106

Slide 106 text

>>> from hangulize import * >>> hangulize(u'Cappuccino', 'ita') u'카푸치노' 옛 한글라이즈 이 파이썬 구현을 "옛 한글라이즈"라고 부를게요.

Slide 107

Slide 107 text

https://hangulize.org/ 꼭 프로그래머가 아니더라도 누구나 쉽게 쓸 수 있도록

Slide 108

Slide 108 text

https://hangulize.org/ "hangulize.org" 웹 서비스도 운영해왔는데

Slide 109

Slide 109 text

주로 번역가가 사용 이지민, 《그래도 번역가로 살겠다면》(2017) 이 웹 서비스가 번역가 분들에겐 소소한 도움을 주고 있는 것 같더라고요.

Slide 110

Slide 110 text

•주먹구구식 구현 •고치기 어려운 버그 •전사 규칙이 파이썬 코드 옛 한글라이즈 불만 하지만 제가 어렸을 때 만든 것이다 보니

Slide 111

Slide 111 text

•주먹구구식 구현 •고치기 어려운 버그 •전사 규칙이 파이썬 코드 옛 한글라이즈 불만 지금 보면 맘에 들지 않는 부분도 몇 가지 있는데

Slide 112

Slide 112 text

•주먹구구식 구현 •고치기 어려운 버그 •전사 규칙이 파이썬 코드 옛 한글라이즈 불만 주먹구구식 구현으로 고치기 어려운 버그를 만든 것도 문제지만

Slide 113

Slide 113 text

•주먹구구식 구현 •고치기 어려운 버그 •전사 규칙이 파이썬 코드 옛 한글라이즈 불만 특히 외래어 표기법 전사 규칙을 파이썬 코드로 쓰게 했던 점이 가장 후회됩니다.

Slide 114

Slide 114 text

•주먹구구식 구현 •고치기 어려운 버그 •전사 규칙이 파이썬 코드 옛 한글라이즈 불만 프로그래머가 아니면 진입장벽도 높고 버그를 야기할 여지도 많아서

Slide 115

Slide 115 text

•주먹구구식 구현 •고치기 어려운 버그 •전사 규칙이 파이썬 코드 옛 한글라이즈 불만 새 표기법을 구현할 때 생산성이 그리 좋지 않았던 것 같아요.

Slide 116

Slide 116 text

옛 한글라이즈 2010-2018 이런 후회를 뒤로 하고 옛 한글라이즈는 얼마 전에 공식적으로 폐쇄했습니다.

Slide 117

Slide 117 text

Go Go로 완전히 새로 구현했죠.

Slide 118

Slide 118 text

gore> :import "github.com/hangulize/hangulize" gore> hangulize.Hangulize("rus", "Владивосто́ к") "블라디보스토크" 새 한글라이즈 2018년 5월-

Slide 119

Slide 119 text

gore> :import "github.com/hangulize/hangulize" gore> hangulize.Hangulize("rus", "Владивосто́ к") "블라디보스토크" 새 한글라이즈 2018년 5월- "새 한글라이즈"는 8년 만인 지난 5월부터 만들었어요.

Slide 120

Slide 120 text

gore> :import "github.com/hangulize/hangulize" gore> hangulize.Hangulize("rus", "Владивосто́ к") "블라디보스토크" 새 한글라이즈 2018년 5월- 옛 한글라이즈처럼 Go 환경에서 쓸 수 있는 간단한 라이브러리죠.

Slide 121

Slide 121 text

lang: id = "rus" codes = "ru", "rus" english = "Russian" korean = "러시아어" script = "cyrillic" macros: "@" = "" vars: "cs" = "б", "в", "г" 전사 규칙 .hgl 파일 rewrite: "град" -> "град-" "^ль" -> "л-ь" "ый" -> "ы" transcribe: "б" -> "ㅂ" "л," -> "-ㄹ" test: "Ольга" -> "올가" "Пётр" -> "표트르" 새로 구현하면서는 전사 규칙도 코드 대신 이런 텍스트파일로 정의할 수 있게 설계했는데

Slide 122

Slide 122 text

lang: id = "rus" codes = "ru", "rus" english = "Russian" korean = "러시아어" script = "cyrillic" macros: "@" = "" vars: "cs" = "б", "в", "г" 전사 규칙 .hgl 파일 rewrite: "град" -> "град-" "^ль" -> "л-ь" "ый" -> "ы" transcribe: "б" -> "ㅂ" "л," -> "-ㄹ" test: "Ольга" -> "올가" "Пётр" -> "표트르" 정해진 틀 안에서 쓰다 보니 버그가 발생할 여지도 적고

Slide 123

Slide 123 text

lang: id = "rus" codes = "ru", "rus" english = "Russian" korean = "러시아어" script = "cyrillic" macros: "@" = "" vars: "cs" = "б", "в", "г" 전사 규칙 .hgl 파일 rewrite: "град" -> "град-" "^ль" -> "л-ь" "ый" -> "ы" transcribe: "б" -> "ㅂ" "л," -> "-ㄹ" test: "Ольга" -> "올가" "Пётр" -> "표트르" 맞춤형 문법이라서 읽기도 훨씬 편해졌습니다.

Slide 124

Slide 124 text

H 형상, 로마자 i, 화살표, 한글ㅣ 옛 로고 새 로고 그리고 8년 만에 새 로고도 디자인했죠.

Slide 125

Slide 125 text

四川 쓰촨

Slide 126

Slide 126 text

四川 쓰촨 이번엔 한글라이즈의 원리를 살펴보기 위해 중국 지명인 "쓰촨"을 예로 들어보겠습니다.

Slide 127

Slide 127 text

Rewrite Transcribe Phonemize 四川 쓰촨 한글라이즈 파이프라인 한글라이즈에 한자 "四川"이 입력되면

Slide 128

Slide 128 text

Rewrite Transcribe Phonemize 四川 쓰촨 한글라이즈 파이프라인 일련의 파이프라인을 통과해 최종적으로 "쓰촨"이 되죠.

Slide 129

Slide 129 text

•뜻글자를 소리글자로 •사전 •형태소 분석 1단계: Phonemize Rewrite Transcribe Phonemize 四川 si chuan 파이프라인의 첫 단계는 Phonemize 단계인데

Slide 130

Slide 130 text

•뜻글자를 소리글자로 •사전 •형태소 분석 1단계: Phonemize Rewrite Transcribe Phonemize 四川 si chuan 여기선 뜻글자를 소리글자로 바꾸는 작업을 합니다.

Slide 131

Slide 131 text

•뜻글자를 소리글자로 •사전 •형태소 분석 1단계: Phonemize Rewrite Transcribe Phonemize 四川 si chuan 한자 "四川"의 경우 중국어 병음 "si chuan"으로 바뀌죠.

Slide 132

Slide 132 text

•뜻글자를 소리글자로 •사전 •형태소 분석 1단계: Phonemize Rewrite Transcribe Phonemize 四川 si chuan Phonemize 단계가 모든 언어에서 필요한 건 아니지만

Slide 133

Slide 133 text

•뜻글자를 소리글자로 •사전 •형태소 분석 1단계: Phonemize Rewrite Transcribe Phonemize 四川 si chuan 중국어나 일본어처럼 뜻글자를 쓰는 경우엔 이 단계를 거쳐야만 한글로 옮길 수 있습니다.

Slide 134

Slide 134 text

•뜻글자를 소리글자로 •사전 •형태소 분석 1단계: Phonemize Rewrite Transcribe Phonemize 四川 si chuan 이때 방대한 발음 사전이나 형태소 분석 같은 기능이 필요한데

Slide 135

Slide 135 text

•뜻글자를 소리글자로 •사전 •형태소 분석 1단계: Phonemize Rewrite Transcribe Phonemize 四川 si chuan 여기에 어떤 라이브러리를 썼는지는 뒤에서 다시 소개하겠습니다.

Slide 136

Slide 136 text

•패턴 찾아 바꾸기 •표음성 강화 2단계: Rewrite Rewrite Transcribe Phonemize si chuan "{s}i" -> "i," si, chuan "{h}uan" -> "wan" si, chwan "n$" -> "n," si, chwan,

Slide 137

Slide 137 text

•패턴 찾아 바꾸기 •표음성 강화 2단계: Rewrite Rewrite Transcribe Phonemize si chuan "{s}i" -> "i," si, chuan "{h}uan" -> "wan" si, chwan "n$" -> "n," si, chwan, 두 번째 Rewrite 단계에선 일련의 패턴 찾아 바꾸기로

Slide 138

Slide 138 text

•패턴 찾아 바꾸기 •표음성 강화 2단계: Rewrite Rewrite Transcribe Phonemize si chuan "{s}i" -> "i," si, chuan "{h}uan" -> "wan" si, chwan "n$" -> "n," si, chwan, 앞에서 넘어온 "si chuan"을 "si, chwan,"로 바꿔줍니다.

Slide 139

Slide 139 text

•패턴 찾아 바꾸기 •표음성 강화 2단계: Rewrite Rewrite Transcribe Phonemize si chuan "{s}i" -> "i," si, chuan "{h}uan" -> "wan" si, chwan "n$" -> "n," si, chwan, 이 단계의 용도는 소리글자의 표음성을 강화하는 것인데

Slide 140

Slide 140 text

표음성 신도림행 열차 지옥행 급행열차 표음성 극대화 형태학적 표기 신도리맹 녈차 지오캥 그팽녈차 여기서 "표음성"이란

Slide 141

Slide 141 text

표음성 신도림행 열차 지옥행 급행열차 표음성 극대화 형태학적 표기 신도리맹 녈차 지오캥 그팽녈차 소리글자가 실제 소리에 대응되는 정도를 뜻합니다.

Slide 142

Slide 142 text

표음성 신도림행 열차 지옥행 급행열차 표음성 극대화 형태학적 표기 신도리맹 녈차 지오캥 그팽녈차 한글도 왼쪽처럼 소리나는 대로만 적으면 표음성은 극대화되지만

Slide 143

Slide 143 text

표음성 신도림행 열차 지옥행 급행열차 표음성 극대화 형태학적 표기 신도리맹 녈차 지오캥 그팽녈차 한 눈에 의미를 파악하긴 더 어렵죠.

Slide 144

Slide 144 text

표음성 신도림행 열차 지옥행 급행열차 표음성 극대화 형태학적 표기 신도리맹 녈차 지오캥 그팽녈차 그래서 철자법에선 오른쪽처럼 표음성을 희생하고

Slide 145

Slide 145 text

표음성 신도림행 열차 지옥행 급행열차 표음성 극대화 형태학적 표기 신도리맹 녈차 지오캥 그팽녈차 대신 단어의 형태와 어원을 살리는 경우가 많습니다.

Slide 146

Slide 146 text

•패턴 찾아 바꾸기 •표음성 강화 2단계: Rewrite Rewrite Transcribe Phonemize si chuan "{s}i" -> "i," si, chuan "{h}uan" -> "wan" si, chwan "n$" -> "n," si, chwan, 따라서 소리글자라고 해도 실제 소리에 1:1 대응되는 경우는 별로 없는데

Slide 147

Slide 147 text

•패턴 찾아 바꾸기 •표음성 강화 2단계: Rewrite Rewrite Transcribe Phonemize si chuan "{s}i" -> "i," si, chuan "{h}uan" -> "wan" si, chwan "n$" -> "n," si, chwan, 한글로 옮기려면 의미가 아닌 발음이 필요하니까

Slide 148

Slide 148 text

•패턴 찾아 바꾸기 •표음성 강화 2단계: Rewrite Rewrite Transcribe Phonemize si chuan "{s}i" -> "i," si, chuan "{h}uan" -> "wan" si, chwan "n$" -> "n," si, chwan, 이 단계에서 철자로부터 발음을 최대한 유추합니다.

Slide 149

Slide 149 text

•한글 자모로 변환 •패턴 찾아 바꾸기 •외래어 표기법 구현 3단계: Transcribe Rewrite Transcribe Phonemize si, chwan, "wan,?" -> "ㅘ-ㄴ" si, chㅘ-ㄴ "i," -> "ㅡ" sㅡ chㅘ-ㄴ "ch" -> "ㅊ" sㅡ ㅊㅘ-ㄴ "s" -> "ㅆ" ㅆㅡ ㅊㅘ-ㄴ

Slide 150

Slide 150 text

•한글 자모로 변환 •패턴 찾아 바꾸기 •외래어 표기법 구현 3단계: Transcribe Rewrite Transcribe Phonemize si, chwan, "wan,?" -> "ㅘ-ㄴ" si, chㅘ-ㄴ "i," -> "ㅡ" sㅡ chㅘ-ㄴ "ch" -> "ㅊ" sㅡ ㅊㅘ-ㄴ "s" -> "ㅆ" ㅆㅡ ㅊㅘ-ㄴ 그렇게 구한 발음을 세 번째 Transcribe 단계에선

Slide 151

Slide 151 text

•한글 자모로 변환 •패턴 찾아 바꾸기 •외래어 표기법 구현 3단계: Transcribe Rewrite Transcribe Phonemize si, chwan, "wan,?" -> "ㅘ-ㄴ" si, chㅘ-ㄴ "i," -> "ㅡ" sㅡ chㅘ-ㄴ "ch" -> "ㅊ" sㅡ ㅊㅘ-ㄴ "s" -> "ㅆ" ㅆㅡ ㅊㅘ-ㄴ 대응되는 한글 자모로 바꿔줍니다.

Slide 152

Slide 152 text

•한글 자모로 변환 •패턴 찾아 바꾸기 •외래어 표기법 구현 3단계: Transcribe Rewrite Transcribe Phonemize si, chwan, "wan,?" -> "ㅘ-ㄴ" si, chㅘ-ㄴ "i," -> "ㅡ" sㅡ chㅘ-ㄴ "ch" -> "ㅊ" sㅡ ㅊㅘ-ㄴ "s" -> "ㅆ" ㅆㅡ ㅊㅘ-ㄴ 여기가 외래어 표기법이 실제로 구현되는 단계죠.

Slide 153

Slide 153 text

•한글 자모로 변환 •패턴 찾아 바꾸기 •외래어 표기법 구현 3단계: Transcribe Rewrite Transcribe Phonemize si, chwan, "wan,?" -> "ㅘ-ㄴ" si, chㅘ-ㄴ "i," -> "ㅡ" sㅡ chㅘ-ㄴ "ch" -> "ㅊ" sㅡ ㅊㅘ-ㄴ "s" -> "ㅆ" ㅆㅡ ㅊㅘ-ㄴ Transcribe 단계도 Rewrite 단계와 마찬가지로 일련의 패턴 찾아 바꾸기로 이뤄져 있습니다.

Slide 154

Slide 154 text

Rewrite Transcribe Phonemize 四川 쓰촨 한글라이즈 파이프라인 si chuan si, chwan, ㅆㅡㅊㅘ-ㄴ 마지막으로 나열된 자모들을 한글 글자로 모아쓰기하면 전사가 완료돼요.

Slide 155

Slide 155 text

아제르바이잔어 벨라루스어 불가리아어 카탈로니아어 체코어 중국어 웨일스어 독일어 그리스어 에스페란토어 에스토니아어 핀란드어 고대 그리스어 세르보크로아트어 헝가리어 아이슬란드어 이탈리아어 일본어 일본어최영애-김용옥 조지아어제1안 조지아어제2안 라틴어 라트비아어 리투아니아어 마케도니아어 네덜란드어 폴란드어 포르투갈어 브라질 포르투갈어 루마니아어 러시아어 슬로바키아어 슬로베니아어 스페인어 알바니아어 스웨덴어 터키어 우크라이나어 베트남어 웨일스어중세

Slide 156

Slide 156 text

아제르바이잔어 벨라루스어 불가리아어 카탈로니아어 체코어 중국어 웨일스어 독일어 그리스어 에스페란토어 에스토니아어 핀란드어 고대 그리스어 세르보크로아트어 헝가리어 아이슬란드어 이탈리아어 일본어 일본어최영애-김용옥 조지아어제1안 조지아어제2안 라틴어 라트비아어 리투아니아어 마케도니아어 네덜란드어 폴란드어 포르투갈어 브라질 포르투갈어 루마니아어 러시아어 슬로바키아어 슬로베니아어 스페인어 알바니아어 스웨덴어 터키어 우크라이나어 베트남어 웨일스어중세 한글라이즈엔 현재 일본어, 헝가리어 등 총 40개의 전사 규칙이 들어있어요.

Slide 157

Slide 157 text

영어 하지만 아쉽게도 가장 수요가 많은 영어는 아직 지원하지 못 하고 있습니다.

Slide 158

Slide 158 text

영어 영어는 특히나 표음성이 낮은 언어라서 그런데

Slide 159

Slide 159 text

• though ▶ • through ▶ • rough ▶ • cough ▶ • thought ▶ • bough ▶ 영어의 낮은 표음성 예를 들어 "ough"는 이렇게나 다양한 발음을 갖고 있지만

Slide 160

Slide 160 text

• though ▶ • through ▶ • rough ▶ • cough ▶ • thought ▶ • bough ▶ 영어의 낮은 표음성 철자 규칙만으로 발음을 정확하게 유추하는 건 불가능하다고 합니다.

Slide 161

Slide 161 text

Ghoti ▶ 영어의 낮은 표음성을 비꼬는 유명한 농담으로 이런 것도 있습니다.

Slide 162

Slide 162 text

Ghoti ▶ "고티"라고 읽을 것 같은 단어인데

Slide 163

Slide 163 text

Ghoti ▶ enough women nation "gh"는 "enough"에서, "o"는 "women"에서, "ti"는 "nation"에서 따와서

Slide 164

Slide 164 text

Ghoti ▶ 피시 enough women nation "피시"라고 읽어야 한다고 합니다.

Slide 165

Slide 165 text

2. Go

Slide 166

Slide 166 text

2. Go 이번엔 한글라이즈를 Go로 다시 만들면서 저에게 흥미로웠던 점들을 소개해 드릴게요.

Slide 167

Slide 167 text

초보 주의 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루 저 고랭코리아 우선 들어가기 전에 앞에서 말씀드렸듯이 전 Go를 취미로만 써봤거든요.

Slide 168

Slide 168 text

초보 주의 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루 저 고랭코리아 큰 코드베이스에서 남들과 협업해보거나 실무에서 제대로 써본 적이 아직 없습니다.

Slide 169

Slide 169 text

초보 주의 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루 저 고랭코리아 그래서 너무 당연한 얘기를 하거나 틀린 얘기를 할 수도 있는데

Slide 170

Slide 170 text

초보 주의 진지한 장난감 협업 장난감 옹알이 실무 리뷰 구루 저 고랭코리아 그럴 경우 부담 없이 [email protected]로 제보해주시면 감사하겠습니다.

Slide 171

Slide 171 text

고루틴 끝내준다! Go 첫인상

Slide 172

Slide 172 text

고루틴 끝내준다! Go 첫인상 몇 년 전에 Go 튜토리얼 책을 처음 보면서 들었던 첫인상은 이랬습니다.

Slide 173

Slide 173 text

고루틴 끝내준다! Go 첫인상 고루틴 끝내준다!

Slide 174

Slide 174 text

고루틴 끝내준다! Go 첫인상 이렇게 병렬 프로그래밍을 쉽게 할 수 있는 환경은 처음 봤었거든요.

Slide 175

Slide 175 text

고루틴 끝내준다! Go 첫인상 쓸 때마다 늘 피곤했던 병렬처리 단위, 채널, 큐 등을

Slide 176

Slide 176 text

고루틴 끝내준다! Go 첫인상 언어의 기본 기능으로 제공한다는 데에 깜짝 놀랐죠.

Slide 177

Slide 177 text

•고루틴은 끝내주는데 •그런데 너무 기능이 적다. Go 첫인상 그런데 그 밖엔 취향에 맞지 않는 점이 많았어요.

Slide 178

Slide 178 text

•고루틴은 끝내주는데 •그런데 너무 기능이 적다. Go 첫인상 그 흔한 반복자나 재정의, 예외도 없고 특히 제네릭이 없어서

Slide 179

Slide 179 text

•고루틴은 끝내주는데 •그런데 너무 기능이 적다. Go 첫인상 범용적인 정적 자료구조를 만들 수 없다는 점도 의아하게 느껴졌습니다.

Slide 180

Slide 180 text

•고루틴은 끝내주는데 •그런데 너무 기능이 적다. •고퍼도 귀엽지 않고 Go 첫인상 그리고 무엇보다도 고퍼가 영 귀엽지 않았죠.

Slide 181

Slide 181 text

이걸로 정말 제품이 만들어질까? Go 첫인상 이렇게 단순한 언어로 정말 강력한 제품을 만들 수 있을까 의문이 들었습니다.

Slide 182

Slide 182 text

Docker etcd Terraform K8s 하지만 점점 더 많은 유명 프로젝트가 Go로 만들어지고 있는 모습을 보면서

Slide 183

Slide 183 text

된다. 아주 잘 된다는 걸 깨닫게 됐죠.

Slide 184

Slide 184 text

협업 장난감 옹알이 실무 리뷰 구루 진지한 장난감 저도 한 번 Go를 제대로 익혀보고 싶어서 간단한 취미코딩에 써보기 시작했어요.

Slide 185

Slide 185 text

https://subl.ee/runker/ 예를 들면 이런 겁니다.

Slide 186

Slide 186 text

https://subl.ee/runker/ 〈섭리랑카〉라는 간단한 〈똥피하기〉 패러디 게임인데

Slide 187

Slide 187 text

https://subl.ee/runker/ 랭킹서버가 Go 여기서 랭킹서버가 Go와 구글 앱 엔진으로 돼있습니다.

Slide 188

Slide 188 text

sublee/subpptx 지금 이 발표자료에 자막 붙이는 데 쓰고 있는 "subpptx"도 Go로 만들었어요.

Slide 189

Slide 189 text

sublee/subpptx 이 프로젝트에선 고루틴 덕분에 손쉽게 페이지 단위로 병렬처리할 수 있었죠.

Slide 190

Slide 190 text

쓸 만 하다. 더 잘 하고 싶다. 이런저런 간단한 장난감을 만들면서 Go를 써보니 꽤 쓸 만 하고 재미있다는 인상을 받았습니다.

Slide 191

Slide 191 text

쓸 만 하다. 더 잘 하고 싶다. Go 특유의 간결함이 이제 명료함으로 느껴지더라고요.

Slide 192

Slide 192 text

쓸 만 하다. 더 잘 하고 싶다. 몇 십 줄 짜리 간단한 장난감에서 벗어나 좀 더 진지한 걸 만들어보면서

Slide 193

Slide 193 text

쓸 만 하다. 더 잘 하고 싶다. Go를 더 잘 다루고 싶다고 생각하게 됐습니다.

Slide 194

Slide 194 text

한글라이즈 다시 만들면 왠지 더 잘 만들 것 같다.

Slide 195

Slide 195 text

한글라이즈 다시 만들면 왠지 더 잘 만들 것 같다. 석 달 전 마침

Slide 196

Slide 196 text

한글라이즈 다시 만들면 왠지 더 잘 만들 것 같다. 한글라이즈를 다시 만들면 왠지 더 잘 만들 것 같다는 생각이 떠올랐어요.

Slide 197

Slide 197 text

•주먹구구식 구현 •고치기 어려운 버그 •전사 규칙이 파이썬 코드 옛 한글라이즈 불만 앞에서 말씀드렸듯이 기존 한글라이즈에서 맘에 들지 않는 구석도 많았고

Slide 198

Slide 198 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 또 한글라이즈가 저에겐 새로운 언어를 익힐 때 연습과제로 삼기 꽤 좋은 프로젝트거든요.

Slide 199

Slide 199 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 이미 한 번 만들어봐서 불확실성은 별로 없는데

Slide 200

Slide 200 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 적당히 복잡하면서 상당히 계산 중심적이다 보니

Slide 201

Slide 201 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 구조나 알고리즘에 대한 고민도 다시 한 번 해보게 되고

Slide 202

Slide 202 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 그 언어가 유니코드와 정규표현식을 어떻게 다루는지 깊게 겪어볼 수도 있고

Slide 203

Slide 203 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 또 이미 만들어둔 테스트케이스가 많아서 제대로 짰는지 검증할 재료도 충분하죠.

Slide 204

Slide 204 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 마지막으로 제가 덕질할 수 있는 주제여서

Slide 205

Slide 205 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 몇 달 정도는 지긋이 해볼 수 있는 과제이기도 합니다.

Slide 206

Slide 206 text

• 이미 한 번 만들어 봄 • 적당한 복잡성 • 계산 중심적 •유니코드/정규표현식 •풍부한 테스트케이스 •언어학 덕질 연습과제: 한글라이즈 그렇게 파이썬으로 만들었던 한글라이즈를 Go로 다시 만들게 됐습니다.

Slide 207

Slide 207 text

a. 정규표현식 b. 말과 글 c. 테스트와 문서화

Slide 208

Slide 208 text

a. 정규표현식 b. 말과 글 c. 테스트와 문서화 그럼 Go에서 흥미로웠던 세 가지 주제로 넘어가 보겠습니다.

Slide 209

Slide 209 text

a. 정규표현식 b. 말과 글 c. 테스트와 문서화 좀 두서 없을 수도 있는데 정규표현식, 말과 글, 테스트와 문서화에 대해 다룰 거예요.

Slide 210

Slide 210 text

a. 정규표현식

Slide 211

Slide 211 text

a. 정규표현식 첫 번째는 정규표현식입니다. 줄여서 "정규식"이라고도 부르는데

Slide 212

Slide 212 text

/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~- ]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d- \x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9- ]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0- 5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0- 9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e- \x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/ 이메일 정규표현식 http://emailregex.com/ 텍스트 매칭하는 데에 다들 한 번 쯤은 써보셨을 것 같아요.

Slide 213

Slide 213 text

/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~- ]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d- \x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9- ]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0- 5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0- 9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e- \x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/ 이메일 정규표현식 http://emailregex.com/ 정규식 엔진엔 몇 가지 알고리즘이 있지만

Slide 214

Slide 214 text

import "regexp" Go 표준 정규식 라이브러리는

Slide 215

Slide 215 text

•안전한 정규표현식 구현 •문자열 길이에 대해 선형 시간 •고의적으로 일부 기능 미지원 RE2 by Google 구글에서 만든 정규식 엔진인 RE2를 기반으로 하고 있습니다.

Slide 216

Slide 216 text

•안전한 정규표현식 구현 •문자열 길이에 대해 선형 시간 •고의적으로 일부 기능 미지원 RE2 by Google RE2는 평균적으로 가장 빠른 정규식 엔진은 아니더라도

Slide 217

Slide 217 text

•안전한 정규표현식 구현 •문자열 길이에 대해 선형 시간 •고의적으로 일부 기능 미지원 RE2 by Google 대상 문자열 길이에 정비례하는 선형 시간을 보장하는 걸 목표로 삼는다고 합니다.

Slide 218

Slide 218 text

•안전한 정규표현식 구현 •문자열 길이에 대해 선형 시간 •고의적으로 일부 기능 미지원 RE2 by Google 그래서 선형 시간에 구현할 수 없는 정규식의 일부 고급 기능은 고의적으로 지원하지 않죠.

Slide 219

Slide 219 text

O(mn) RE2 성능 보장 RE2의 시간복잡도는 평균, 최악 모두 O(mn)입니다.

Slide 220

Slide 220 text

O(mn) RE2 성능 보장 정규표현식 길이 대상 문자열 길이 여기서 m은 정규식 패턴의 길이고 n은 대상 문자열의 길이예요.

Slide 221

Slide 221 text

O(mn) RE2 성능 보장 정규표현식 길이 대상 문자열 길이 grep 같이 정규식을 사용자입력으로 받는 프로그램이 아닌 이상

Slide 222

Slide 222 text

O( n) RE2 성능 보장 대상 문자열 길이 보통 상수항 정규식 패턴은 코드에 미리 적어 두는 경우가 대부분이다 보니

Slide 223

Slide 223 text

O( n) RE2 성능 보장 대상 문자열 길이 보통 상수항 사실상 m을 상수항으로 취급해도 좋습니다. 상당히 훌륭하죠.

Slide 224

Slide 224 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007)

Slide 225

Slide 225 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) RE2를 만든 Russ Cox의 홈페이지에 가보면

Slide 226

Slide 226 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 두 종류의 정규식 엔진을 비교하는 재미있는 벤치마크가 있습니다.

Slide 227

Slide 227 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) Russ Cox는 Go 개발진으로도 유명한 분이죠?

Slide 228

Slide 228 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 우선 이 예시를 보시죠.

Slide 229

Slide 229 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 패턴엔 /a?/와 리터럴 /a/가 각각 3개씩 있고

Slide 230

Slide 230 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 대상 문자열은 "a" 3개로 이뤄져 있습니다.

Slide 231

Slide 231 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 패턴에서 /a?/는 전부 건너뛰고 리터럴 /a/ 3개만 매치시켜야

Slide 232

Slide 232 text

/a?a?a?aaa/를 "aaa"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 매치에 성공할 수 있는 패턴이에요.

Slide 233

Slide 233 text

f(1) = /a?a/를 "a"에 매치 f(3) = /a?a?a?aaa/를 "aaa"에 매치 f(5) = /a?a?a?a?a?aaaaa/를 "aaaaa"에 매치 f(x) = /a?ˣaˣ/를 "aˣ"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 벤치마크는 패턴과 문자열의 길이를 바꿔가며 진행할 텐데

Slide 234

Slide 234 text

f(1) = /a?a/를 "a"에 매치 f(3) = /a?a?a?aaa/를 "aaa"에 매치 f(5) = /a?a?a?a?a?aaaaa/를 "aaaaa"에 매치 f(x) = /a?ˣaˣ/를 "aˣ"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 이런 식으로 /a?/와 /a/를 x개만큼 반복하는 패턴과

Slide 235

Slide 235 text

f(1) = /a?a/를 "a"에 매치 f(3) = /a?a?a?aaa/를 "aaa"에 매치 f(5) = /a?a?a?a?a?aaaaa/를 "aaaaa"에 매치 f(x) = /a?ˣaˣ/를 "aˣ"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) x개의 "a"로 이뤄진 대상 문자열을 가지고

Slide 236

Slide 236 text

f(1) = /a?a/를 "a"에 매치 f(3) = /a?a?a?aaa/를 "aaa"에 매치 f(5) = /a?a?a?a?a?aaaaa/를 "aaaaa"에 매치 f(x) = /a?ˣaˣ/를 "aˣ"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) x를 늘려가면서 속도를 비교해볼 겁니다.

Slide 237

Slide 237 text

f(1) = /a?a/를 "a"에 매치 f(3) = /a?a?a?aaa/를 "aaa"에 매치 f(5) = /a?a?a?a?a?aaaaa/를 "aaaaa"에 매치 f(x) = /a?ˣaˣ/를 "aˣ"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) 저는 파이썬의 정규식 표준 라이브러리 "re"와

Slide 238

Slide 238 text

f(1) = /a?a/를 "a"에 매치 f(3) = /a?a?a?aaa/를 "aaa"에 매치 f(5) = /a?a?a?a?a?aaaaa/를 "aaaaa"에 매치 f(x) = /a?ˣaˣ/를 "aˣ"에 매치 벤치마크 Russ Cox, 〈Regular Expression Matching Can Be Simple And Fast〉(2007) Go의 정규식 표준 라이브러리 "regexp" 두 가지로 직접 돌려봤어요.

Slide 239

Slide 239 text

/a?ˣaˣ/를 "aˣ"에 매치 시간 파이썬의 re Go의 regexp f(x) 결과는 이랬습니다.

Slide 240

Slide 240 text

/a?ˣaˣ/를 "aˣ"에 매치 시간 파이썬의 re Go의 regexp f(x) 파이썬 쪽 곡선이 압도적으로 가파르게 올라갔죠.

Slide 241

Slide 241 text

/a?ˣaˣ/를 "aˣ"에 매치 시간 파이썬의 re Go의 regexp f(x) Russ Cox의 설명에 의하면

Slide 242

Slide 242 text

/a?ˣaˣ/를 "aˣ"에 매치 시간 f(x) O(x²) O(2ˣ) 시간복잡도가 Go 쪽은 O(x²)이고 파이썬 쪽은 O(2ˣ)이라고 합니다.

Slide 243

Slide 243 text

/a?ˣaˣ/를 "aˣ"에 매치 시간 f(x) O(x²) O(2ˣ) 언뜻 보면 제곱 시간도 나쁜 성능처럼 보이지만

Slide 244

Slide 244 text

/a?ˣaˣ/를 "aˣ"에 매치 시간 f(x) O(x²) O(2ˣ) 이 벤치마크 함수는 x가 커질 수록 패턴 길이 m과 문자열 길이 n을 같이 키우니까

Slide 245

Slide 245 text

/a?ˣaˣ/를 "aˣ"에 매치 시간 f(x) O(x²) O(2ˣ) 제곱 시간이면 사실은 이상적인 성능이라고 볼 수 있습니다.

Slide 246

Slide 246 text

/a?ˣaˣ/를 "aˣ"에 매치 파이썬 re Go regexp f(10) 39.7㎲ 1.8㎲ f(15) 1.3㎳ 3.8㎲ f(20) 47.2㎳ 6.6㎲ f(25) 1.7초 9.7㎲ f(30) 61.8초 13.9㎲ f(50) 676일(예상) 38.5㎲ 제가 돌려본 벤치마크 환경에선 x가 50일 때 Go 쪽은 38.5㎲면 끝나지만

Slide 247

Slide 247 text

/a?ˣaˣ/를 "aˣ"에 매치 파이썬 re Go regexp f(10) 39.7㎲ 1.8㎲ f(15) 1.3㎳ 3.8㎲ f(20) 47.2㎳ 6.6㎲ f(25) 1.7초 9.7㎲ f(30) 61.8초 13.9㎲ f(50) 676일(예상) 38.5㎲ 파이썬 쪽은 1년 9개월이나 걸릴 것으로 예상되더라고요.

Slide 248

Slide 248 text

Spencer 류 펄, PCRE, 파이썬, 루비, 자바 Thompson 류 awk, sed, grep, RE2, Go, 러스트

Slide 249

Slide 249 text

Spencer 류 펄, PCRE, 파이썬, 루비, 자바 Thompson 류 awk, sed, grep, RE2, Go, 러스트 앞서 정규식 엔진엔 몇 가지 알고리즘이 있다고 말씀드렸는데

Slide 250

Slide 250 text

Spencer 류 펄, PCRE, 파이썬, 루비, 자바 Thompson 류 awk, sed, grep, RE2, Go, 러스트 크게 Spencer 류와 Thompson 류로 나눌 수 있을 것 같습니다.

Slide 251

Slide 251 text

Spencer 류 펄, PCRE, 파이썬, 루비, 자바 Thompson 류 awk, sed, grep, RE2, Go, 러스트 파이썬 re는 Spencer 류에 속하고 RE2와 Go regexp는 Thompson 류에 속하죠.

Slide 252

Slide 252 text

Spencer 류 펄, PCRE, 파이썬, 루비, 자바 Thompson 류 awk, sed, grep, RE2, Go, 러스트 앞에서 돌렸던 벤치마크의 경우 Spencer 류 엔진에선 지수 시간이 걸리지만

Slide 253

Slide 253 text

Spencer 류 펄, PCRE, 파이썬, 루비, 자바 Thompson 류 awk, sed, grep, RE2, Go, 러스트 Thompson 류 엔진에선 제곱 시간밖에 걸리지 않습니다.

Slide 254

Slide 254 text

Spencer 류 펄, PCRE, 파이썬, 루비, 자바 Thompson 류 awk, sed, grep, RE2, Go, 러스트 왜 이런 차이가 생기는지 x=3일 때를 예로 들어서 살펴볼게요.

Slide 255

Slide 255 text

Spencer 류 "aaa" a? a? a? aaa a?가 있다고 가정 a?가 없다고 가정

Slide 256

Slide 256 text

Spencer 류 "aaa" a? a? a? aaa a?가 있다고 가정 a?가 없다고 가정 Spencer 류 엔진은 /a?/라는 분기를 만나면

Slide 257

Slide 257 text

Spencer 류 "aaa" a? a? a? aaa a?가 있다고 가정 a?가 없다고 가정 우선 /a?/가 존재한다고 가정하고 다음으로 넘어갑니다.

Slide 258

Slide 258 text

Spencer 류 "aaa" a? a? a? aaa a?가 있다고 가정 a?가 없다고 가정 /a?a?a?/가 전부 있다고 가정하고 끝까지 가보면

Slide 259

Slide 259 text

Spencer 류 "aaa" a? a? a? aaa a?가 있다고 가정 a?가 없다고 가정 대상 문자열의 끝에 도달해서 리터럴 /a/를 매치시킬 곳이 없단 걸 깨닫죠.

Slide 260

Slide 260 text

Spencer 류 "aaa" a? a? a? aaa aaa a?가 있다고 가정 a?가 없다고 가정 그럼 마지막 분기로 되돌아가서 그 /a?/가 없다고 가정합니다.

Slide 261

Slide 261 text

Spencer 류 "aaa" a? a? a? aaa aaa a?가 있다고 가정 a?가 없다고 가정 하지만 이 길 역시 틀린 길이죠.

Slide 262

Slide 262 text

Spencer 류 "aaa" a? a? a? aaa a? aaa aaa aaa a?가 있다고 가정 a?가 없다고 가정 한 단계 더 물러나서 이번엔 두 번째 /a?/가 없다고 가정해요.

Slide 263

Slide 263 text

Spencer 류 "aaa" a? a? a? aaa a? aaa aaa aaa a?가 있다고 가정 a?가 없다고 가정 그 상태에서 앞에서와 같이 세 번째 분기도 다시 탐색합니다.

Slide 264

Slide 264 text

Spencer 류 "aaa" a? a? a? aaa a? aaa aaa aaa a?가 있다고 가정 a?가 없다고 가정 새로운 두 가지 길이 있지만 이번에도 모두 틀린 길이죠.

Slide 265

Slide 265 text

Spencer 류 "aaa" a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa a?가 있다고 가정 a?가 없다고 가정 aaa 이젠 첫 번째 /a?/도 없다고 가정하고 그동안 탐색했던 길만큼 다시 탐색합니다.

Slide 266

Slide 266 text

Spencer 류 "aaa" a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa a?가 있다고 가정 a?가 없다고 가정 aaa 매치! 마지막 길까지 살펴보면 마침내 패턴이 매치된단 걸 알 수 있습니다.

Slide 267

Slide 267 text

a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 퇴각검색 (backtracking) 이런 식으로 일단 길 하나를 쭉 파보고 틀렸으면 퇴각한 다음

Slide 268

Slide 268 text

a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 퇴각검색 (backtracking) 다른 길로 다시 파보는 방식을 "퇴각검색"이라고 하는데

Slide 269

Slide 269 text

a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 퇴각검색 (backtracking) Spencer 류 정규식 엔진은 분기를 퇴각검색으로 구현합니다.

Slide 270

Slide 270 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 반면 Thompson 류 정규식 엔진은 대상 문자열의 각 글자에 대해서

Slide 271

Slide 271 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 가능한 선택지를 모두 평가하면서 전진해요.

Slide 272

Slide 272 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 대상 문자열의 첫 번째 "a"의 경우 패턴의 세 /a?/ 중 어디에도 매치될 수 있고

Slide 273

Slide 273 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 첫 번째 리터럴 /a/에도 매치될 수 있어서 총 4가지 가능성을 가집니다.

Slide 274

Slide 274 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 그 다음 앞쪽 가능성이 참일 경우에 뒤따르게 될 다음 가능성을 두 번째 "a"에 매치해보고

Slide 275

Slide 275 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a 세 번째 "a"에서도 같은 일을 반복합니다.

Slide 276

Slide 276 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a 매치! 그러면 패턴 끝까지 도달한 가능성이 하나 나타나는데

Slide 277

Slide 277 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a 매치! 바로 매치를 찾은 것이죠.

Slide 278

Slide 278 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a 매치! 퇴각검색 방식을 쓰는 Spencer 류에서와 달리

Slide 279

Slide 279 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a 매치! Thompson 류에서 대상 문자열의 각 글자는 단 한 번씩만 읽히는데

Slide 280

Slide 280 text

Thompson 류 "aaa" a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a 매치! 즉, 되돌아가는 일 없이 전진만 하는 것입니다.

Slide 281

Slide 281 text

Spencer 류 Thompson 류 "aaa" "aaa" a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 2ˣ a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a x+1

Slide 282

Slide 282 text

Spencer 류 Thompson 류 "aaa" "aaa" a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 2ˣ a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a x+1 이 벤치마크에서 Spencer 류가 탐색하는 가능성은 2ˣ개인데 반해

Slide 283

Slide 283 text

Spencer 류 Thompson 류 "aaa" "aaa" a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 2ˣ a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a x+1 Thompson 류는 x+1개만 탐색합니다.

Slide 284

Slide 284 text

Spencer 류 Thompson 류 "aaa" "aaa" a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 2ˣ a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a x+1 그래서 Spencer 류의 탐색 횟수는 지수적으로 증가하고

Slide 285

Slide 285 text

Spencer 류 Thompson 류 "aaa" "aaa" a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 2ˣ a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a x+1 Thompson 류의 탐색 횟수는 선형적으로 증가하죠.

Slide 286

Slide 286 text

Spencer 류 Thompson 류 "aaa" "aaa" a? a? a? aaa a? a? aaa a? aaa a? aaa aaa aaa aaa aaa 2ˣ a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa a?a?a?aaa 첫 번째 a 두 번째 a 세 번째 a x+1 이 때문에 특정한 경우에 둘 사이에서 극단적인 성능차이를 볼 수 있습니다.

Slide 287

Slide 287 text

•평균적으론 충분히 빠르고 •표현력이 더 좋아요. •펄, PCRE, 파이썬, 루비, 자바 Spencer 류

Slide 288

Slide 288 text

•평균적으론 충분히 빠르고 •표현력이 더 좋아요. •펄, PCRE, 파이썬, 루비, 자바 Spencer 류 하지만 일반적인 경우 Spencer 류 정규식 엔진도 충분히 빠르게 동작해요.

Slide 289

Slide 289 text

•평균적으론 충분히 빠르고 •표현력이 더 좋아요. •펄, PCRE, 파이썬, 루비, 자바 Spencer 류 패턴만 안전하게 짜면 Thompson 류만큼 안정적으로 쓸 수 있죠.

Slide 290

Slide 290 text

•평균적으론 충분히 빠르고 •표현력이 더 좋아요. •펄, PCRE, 파이썬, 루비, 자바 Spencer 류 그리고 정규식 기능 중엔 퇴각검색으로만 구현할 수 있는 것도 있어서

Slide 291

Slide 291 text

•평균적으론 충분히 빠르고 •표현력이 더 좋아요. •펄, PCRE, 파이썬, 루비, 자바 Spencer 류 이쪽의 정규식 표현력이 훨씬 좋습니다.

Slide 292

Slide 292 text

•평균적으론 충분히 빠르고 •표현력이 더 좋아요. •펄, PCRE, 파이썬, 루비, 자바 Spencer 류 그래서인지 펄과 PCRE, 파이썬을 비롯해

Slide 293

Slide 293 text

•평균적으론 충분히 빠르고 •표현력이 더 좋아요. •펄, PCRE, 파이썬, 루비, 자바 Spencer 류 오늘날 수많은 정규식 엔진이 이 방식을 쓴다고 해요.

Slide 294

Slide 294 text

/(a+)+/ /([a-zA-Z]+)*/ /(a|aa)+/ /(a|a?)+/ ReDoS 공격 하지만 Spencer 류 정규식 엔진을 쓰는 서버가

Slide 295

Slide 295 text

/(a+)+/ /([a-zA-Z]+)*/ /(a|aa)+/ /(a|a?)+/ ReDoS 공격 만약 사용자 입력으로 정규식 패턴을 받는다면 얘기가 달라집니다.

Slide 296

Slide 296 text

/(a+)+/ /([a-zA-Z]+)*/ /(a|aa)+/ /(a|a?)+/ ReDoS 공격 공격자가 정규식 엔진에서 최악의 경우를 이끌어내는

Slide 297

Slide 297 text

/(a+)+/ /([a-zA-Z]+)*/ /(a|aa)+/ /(a|a?)+/ ReDoS 공격 악의적인 정규식 패턴으로 ReDoS 공격을 가할 수 있거든요.

Slide 298

Slide 298 text

/(a+)+/ /([a-zA-Z]+)*/ /(a|aa)+/ /(a|a?)+/ ReDoS 공격 구글에서도 ReDoS 공격에 대한 우려가 있어서

Slide 299

Slide 299 text

/(a+)+/ /([a-zA-Z]+)*/ /(a|aa)+/ /(a|a?)+/ ReDoS 공격 Thompson의 정규식 알고리즘을 기반으로 RE2를 만들게 됐다고 합니다.

Slide 300

Slide 300 text

"^gli{@}" "^^(a|e|i|o|u)" "{~@}sub" HRE 한글라이즈 정규표현식 방언

Slide 301

Slide 301 text

"^gli{@}" "^^(a|e|i|o|u)" "{~@}sub" HRE 한글라이즈 정규표현식 방언 한편 한글라이즈에선 패턴 찾아 바꾸기 할 때

Slide 302

Slide 302 text

"^gli{@}" "^^(a|e|i|o|u)" "{~@}sub" HRE 한글라이즈 정규표현식 방언 "HRE"로 명명한 한글라이즈 전용 정규표현식 방언을 쓰고 있어요.

Slide 303

Slide 303 text

"^gli{@}" "^^(a|e|i|o|u)" "{~@}sub" HRE 한글라이즈 정규표현식 방언 파란색으로 강조한 부분은 RE2 정규식엔 없는 문법인데

Slide 304

Slide 304 text

HRE를 RE2로 "^gli{@}"HRE /((?:^|\\s+|{}))()gli(a|e|i|o|u)()/RE2 RE2가 이해할 수 있는 문법으로 번역해서 사용하고 있죠.

Slide 305

Slide 305 text

HRE 룩어라운드 "foo{bar}" "foo{~bar}" 그 중 구현하기 골치 아팠던 룩어라운드에 대해 얘기해 드리겠습니다.

Slide 306

Slide 306 text

/^foo/ foo인데 맨 앞 /foo$/ foo인데 맨 뒤 정규식에서 /^/과 /$/가 무엇을 뜻하는진 다들 잘 아시죠?

Slide 307

Slide 307 text

/^foo/ foo인데 맨 앞 /foo$/ foo인데 맨 뒤 /^foo/는 "foo"인데 문자열 맨 앞에 있는 경우에 매치되고

Slide 308

Slide 308 text

/^foo/ foo인데 맨 앞 /foo$/ foo인데 맨 뒤 /foo$/는 "foo"인데 문자열 맨 뒤에 있는 경우에 매치됩니다.

Slide 309

Slide 309 text

"foo{bar}" foo인데 bar 바로 전 "foo{~bar}" foo인데 bar가 아닌 것 바로 전 "{bar}foo" foo인데 bar 바로 뒤 "{~bar}foo" foo인데 bar가 아닌 것 바로 뒤 룩어라운드도 비슷해요.

Slide 310

Slide 310 text

"foo{bar}" foo인데 bar 바로 전 "foo{~bar}" foo인데 bar가 아닌 것 바로 전 "{bar}foo" foo인데 bar 바로 뒤 "{~bar}foo" foo인데 bar가 아닌 것 바로 뒤 "foo{bar}"라고 쓰면 "bar" 바로 앞에 있는 "foo"에만 매치되고

Slide 311

Slide 311 text

"foo{bar}" foo인데 bar 바로 전 "foo{~bar}" foo인데 bar가 아닌 것 바로 전 "{bar}foo" foo인데 bar 바로 뒤 "{~bar}foo" foo인데 bar가 아닌 것 바로 뒤 "foo{~bar}"라고 쓰면 "bar"가 아닌 것 바로 앞에 있는 "foo"에만 매치되죠.

Slide 312

Slide 312 text

"foo{bar}" foo인데 bar 바로 전 "foo{~bar}" foo인데 bar가 아닌 것 바로 전 "{bar}foo" foo인데 bar 바로 뒤 "{~bar}foo" foo인데 bar가 아닌 것 바로 뒤 "{bar}foo", "{~bar}foo" 처럼 "{}"가 앞에 올 수도 있습니다.

Slide 313

Slide 313 text

"foo{bar}" 포지티브 룩어헤드 "foo{~bar}" 네거티브 룩어헤드 "{bar}foo" 포지티브 룩비하인드 "{~bar}foo" 네거티브 룩비하인드 각각의 문법을 "포지티브 룩어헤드", "네거티브 룩어헤드",

Slide 314

Slide 314 text

"foo{bar}" 포지티브 룩어헤드 "foo{~bar}" 네거티브 룩어헤드 "{bar}foo" 포지티브 룩비하인드 "{~bar}foo" 네거티브 룩비하인드 "포지티브 룩비하인드", "네거티브 룩비하인드"라고 부릅니다.

Slide 315

Slide 315 text

".^" foo foobar foobaz foobarr foofoobar

Slide 316

Slide 316 text

".^" foo foobar foobaz foobarr foofoobar 룩어라운드가 실제로 매치되는 모습을 한 번 보겠습니다.

Slide 317

Slide 317 text

".^" foo foobar foobaz foobarr foofoobar 위쪽은 패턴이고 아래쪽은 대상 문자열이에요.

Slide 318

Slide 318 text

".^" foo foobar foobaz foobarr foofoobar ".^"은 아무 데도 매치되지 않는 모순 패턴이죠.

Slide 319

Slide 319 text

"foo" foo foobar foobaz foobarr foofoobar 패턴 "foo"를 찾으면 모든 "foo"에 불이 들어옵니다.

Slide 320

Slide 320 text

"foo(bar)" foo foobar foobaz foobarr foofoobar "foo" 뒤에 "(bar)"를 붙이면 "foobar"에 불이 들어오고

Slide 321

Slide 321 text

"foo{bar}" foo foobar foobaz foobarr foofoobar "(bar)" 대신 "{bar}"를 써서 포지티브 룩어헤드로 만들면

Slide 322

Slide 322 text

"foo{bar}" foo foobar foobaz foobarr foofoobar "foobar" 중 "foo"에만 불이 들어옵니다.

Slide 323

Slide 323 text

"foo{bar}" foo foobar foobaz foobarr foofoobar 이런 식으로 "{}" 속 단어는 매치에 참고는 되지만 실제 결과에 포함되진 않아요.

Slide 324

Slide 324 text

"foo{~bar}" foo foobar foobaz foobarr foofoobar "{bar}"에 물결을 붙여 "{~bar}"로 바꿔서 네거티브 룩어헤드로 만들면

Slide 325

Slide 325 text

"foo{~bar}" foo foobar foobaz foobarr foofoobar "foobar"가 아닌 곳의 "foo"에만 불이 들어옵니다.

Slide 326

Slide 326 text

•어두의 n은 초성 ㄴ으로 치환 •모음 뒤 n은 종성 ㅇ으로 치환 •m 뒤 n은 묵음이니 삭제 룩어라운드 쓰임새 한글라이즈에선 이런 룩어라운드가 꽤 자주 쓰이는데

Slide 327

Slide 327 text

•어두의 n은 초성 ㄴ으로 치환 •모음 뒤 n은 종성 ㅇ으로 치환 •m 뒤 n은 묵음이니 삭제 룩어라운드 쓰임새 특히 같은 글자라고 해도 앞뒤 글자에 따라 다르게 바꿔야 하는 경우에 주로 쓰고 있습니다.

Slide 328

Slide 328 text

/foo(?=bar)/ 포지티브 룩어헤드 /foo(?!bar)/ 네거티브 룩어헤드 /(?<=bar)foo/ 포지티브 룩비하인드 /(?

Slide 329

Slide 329 text

/foo(?=bar)/ 포지티브 룩어헤드 /foo(?!bar)/ 네거티브 룩어헤드 /(?<=bar)foo/ 포지티브 룩비하인드 /(?

Slide 330

Slide 330 text

/foo(?=bar)/ 포지티브 룩어헤드 /foo(?!bar)/ 네거티브 룩어헤드 /(?<=bar)foo/ 포지티브 룩비하인드 /(?

Slide 331

Slide 331 text

/foo(?=bar)/ 포지티브 룩어헤드 /foo(?!bar)/ 네거티브 룩어헤드 /(?<=bar)foo/ 포지티브 룩비하인드 /(?

Slide 332

Slide 332 text

/foo(?=bar)/ 포지티브 룩어헤드 /foo(?!bar)/ 네거티브 룩어헤드 /(?<=bar)foo/ 포지티브 룩비하인드 /(?

Slide 333

Slide 333 text

•안전한 정규표현식 구현 •문자열 길이에 대해 선형 시간 •고의적으로 일부 기능 미지원 RE2 by Google 그런데 아까 RE2가 고의적으로 일부 기능을 지원하지 않는다고 말씀 드렸잖아요?

Slide 334

Slide 334 text

룩어라운드 사용 불가 (?=bar) 룩어라운드도 그 중 하나였습니다.

Slide 335

Slide 335 text

룩어라운드 사용 불가 (?=bar) 옛 한글라이즈에서처럼 단순한 번역으로는 구현할 수 없었죠.

Slide 336

Slide 336 text

import "github.com/glenn-brown/.../pcre" import "github.com/dlclark/regexp2" 찾아보니 서드파티 라이브러리 중에

Slide 337

Slide 337 text

import "github.com/glenn-brown/.../pcre" import "github.com/dlclark/regexp2" PCRE나 .NET을 기반으로 한 정규식 엔진도 발견할 수 있었는데

Slide 338

Slide 338 text

import "github.com/glenn-brown/.../pcre" import "github.com/dlclark/regexp2" 이런 라이브러리를 쓰면 정규식의 모든 기능을 쓸 수 있기야 하지만

Slide 339

Slide 339 text

이왕이면 표준 이왕이면 표준 정규식 라이브러리를 쓰고 싶어서

Slide 340

Slide 340 text

이왕이면 표준 RE2만으로 룩어라운드를 구현할 대안을 고민해보게 됐습니다.

Slide 341

Slide 341 text

"foo{bar}" "{bar}foo" 포지티브 룩어라운드 대안 /()(foo)(bar)/ /(bar)(foo)()/

Slide 342

Slide 342 text

"foo{bar}" "{bar}foo" 포지티브 룩어라운드 대안 /()(foo)(bar)/ /(bar)(foo)()/ 포지티프 룩어라운드의 대안 구현은 간단했어요.

Slide 343

Slide 343 text

"foo{bar}" "{bar}foo" 포지티브 룩어라운드 대안 /()(foo)(bar)/ /(bar)(foo)()/ 그냥 룩어라운드 부분까지 포함시켜서 매치하고

Slide 344

Slide 344 text

$2만 취하기 "foo{bar}" "{bar}foo" 포지티브 룩어라운드 대안 /()(foo)(bar)/ /(bar)(foo)()/ $2 그룹만 취해서 앞뒤를 잘라내는 것으로 충분했습니다.

Slide 345

Slide 345 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 반면 네거티브 룩어라운드는 살짝 복잡했어요.

Slide 346

Slide 346 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 일단 RE2 용으로 번역한 정규식에는 "{~}" 부분을 아예 넣지 않았습니다.

Slide 347

Slide 347 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 이 경우 모든 "foo"에 대해서 매치되겠죠.

Slide 348

Slide 348 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 뒤쪽이 /^bar/이면 건너뛰기 앞쪽이 /bar$/이면 건너뛰기 배제 패턴 그러고 나서 "{~}" 속에 있는 배제 패턴을 매치됐던 곳 앞뒤에 한 번 더 매치시켜 봅니다.

Slide 349

Slide 349 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 뒤쪽이 /^bar/이면 건너뛰기 앞쪽이 /bar$/이면 건너뛰기 배제 패턴 만약 앞뒤가 이 패턴에 매치되면 최종 결과에선 빠지는 거죠.

Slide 350

Slide 350 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 뒤 3글자가 /^bar/이면 건너뛰기 앞 3글자가 /bar$/이면 건너뛰기 bar에 맞춰서 길이 제한 이때 살펴보는 앞뒤의 길이를

Slide 351

Slide 351 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 뒤 3글자가 /^bar/이면 건너뛰기 앞 3글자가 /bar$/이면 건너뛰기 bar에 맞춰서 길이 제한 배제 패턴이 매치될 수 있을 만한 최대 길이로 제한하고 있어요.

Slide 352

Slide 352 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 뒤 3글자가 /^bar/이면 건너뛰기 앞 3글자가 /bar$/이면 건너뛰기 bar에 맞춰서 길이 제한 예시로 든 배제 패턴은 /^bar/, /bar$/인데 앞뒤가 "bar"인지 아닌지는

Slide 353

Slide 353 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 뒤 3글자가 /^bar/이면 건너뛰기 앞 3글자가 /bar$/이면 건너뛰기 bar에 맞춰서 길이 제한 3글자만 보면 되니까 딱 그만큼만 보는 거죠.

Slide 354

Slide 354 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 뒤 3글자가 /^bar/이면 건너뛰기 앞 3글자가 /bar$/이면 건너뛰기 bar에 맞춰서 길이 제한 이 길이 제한이 있어야만 대상 문자열이 아무리 길어져도

Slide 355

Slide 355 text

"foo{~bar}" "{~bar}foo" 네거티브 룩어라운드 대안 /()(foo)()/ /()(foo)()/ 뒤 3글자가 /^bar/이면 건너뛰기 앞 3글자가 /bar$/이면 건너뛰기 bar에 맞춰서 길이 제한 네거티브 룩어라운드를 빠르게 끝낼 수 있습니다.

Slide 356

Slide 356 text

syntax.Parse("a?|b", syntax.Perl) import "regexp/syntax" Alternate '|' Literal 'b' Quest '?' Literal 'a' 패턴이 매치될 수 있는 문자열의 최대 길이를 구하는 건 간단했습니다.

Slide 357

Slide 357 text

syntax.Parse("a?|b", syntax.Perl) import "regexp/syntax" Alternate '|' Literal 'b' Quest '?' Literal 'a' regexp/syntax 표준 라이브러를 쓰면 정규식을 해석한 추상구문트리를 얻을 수 있는데

Slide 358

Slide 358 text

Alternate '|' Literal 'b' Quest '?' Literal 'a' 트리 살펴보면 최대 길이 계산 가능 트리 노드를 적당히 살펴보는 것만으로 최대 길이를 쉽게 계산할 수 있었죠.

Slide 359

Slide 359 text

"{~a}foo" O(n) "{~a+}foo" O(n²) 네거티브 룩어라운드 성능 물론 배제 패턴의 매치 최대 길이가 무한대인 경우엔

Slide 360

Slide 360 text

"{~a}foo" O(n) "{~a+}foo" O(n²) 네거티브 룩어라운드 성능 앞뒤를 딱 필요한 만큼 자를 수 없어서 최악의 경우 제곱 시간이 걸릴 수도 있어요.

Slide 361

Slide 361 text

"{~a+}foo" O(n²) 이런 패턴은 금지 하지만 다행히 이런 패턴은 그동안 한 번도 쓰였던 적이 없었고

Slide 362

Slide 362 text

"{~a+}foo" O(n²) 이런 패턴은 금지 간단히 금지하기로 결정할 수 있었습니다.

Slide 363

Slide 363 text

/()(foo)()/ foo foobar foobaz foobarr foofoobar 뒤 3글자가 /^bar/이면 건너뛰기

Slide 364

Slide 364 text

/()(foo)()/ foo foobar foobaz foobarr foofoobar 뒤 3글자가 /^bar/이면 건너뛰기 이렇게 만들어진 한글라이즈의 네거티브 룩어라운드가

Slide 365

Slide 365 text

/()(foo)()/ foo foobar foobaz foobarr foofoobar 뒤 3글자가 /^bar/이면 건너뛰기 실제로 어떻게 돌아가는지 한 번 살펴보겠습니다.

Slide 366

Slide 366 text

/()(foo)()/ foo foobar foobaz foobarr foofoobar 뒤 3글자가 /^bar/이면 건너뛰기 우선 번역한 정규식으로 매치를 돌려봅니다. 모든 "foo"가 매치되겠죠.

Slide 367

Slide 367 text

/()(foo)()/ foo foobar foobaz foobarr foofoobar 뒤 3글자가 /^bar/이면 건너뛰기 그 다음엔 매치된 "foo" 뒤 3글자씩을 살펴봅니다.

Slide 368

Slide 368 text

/()(foo)()/ foo foobar foobaz foobarr foofoobar 뒤 3글자가 /^bar/이면 건너뛰기 그 중에 /^bar/에 매치되는 게 있으면

Slide 369

Slide 369 text

/()(foo)()/ foo foobar foobaz foobarr foofoobar 뒤 3글자가 /^bar/이면 건너뛰기 결과에서 지워요.

Slide 370

Slide 370 text

/()(foo)()/ foo foobar foobaz foobarr foofoobar 뒤 3글자가 /^bar/이면 건너뛰기 이런 과정을 통하면 최종적으로 "bar"가 아닌 것 앞에 있는 "foo"만 남게 됩니다.

Slide 371

Slide 371 text

b. 말과 글

Slide 372

Slide 372 text

b. 말과 글 이번엔 한글라이즈에서 말과 글을 다루는 데 도움됐던

Slide 373

Slide 373 text

b. 말과 글 세 가지 Go 라이브러리를 소개해 드리겠습니다.

Slide 374

Slide 374 text

•한글 모아쓰기 •중국어 병음 사전 •일본어 형태소 분석 필요한 기능 필요한 기능은 한글 모아쓰기, 중국어 병음 사전, 일본어 형태소 분석이었습니다.

Slide 375

Slide 375 text

한글 모아쓰기 ㅐㅍ-ㄹ 받침 표시 한글 모아쓰기는 이런 걸 얘기해요.

Slide 376

Slide 376 text

한글 모아쓰기 ㅐㅍ-ㄹ 받침 표시 "ㅐㅍ-ㄹ"과 같이 자모를 나열했을 때

Slide 377

Slide 377 text

한글 모아쓰기 애 ㅐㅍ-ㄹ 받침 표시 불완전한 모음인 "ㅐ" 앞엔 "ㅇ"을 채워주고

Slide 378

Slide 378 text

한글 모아쓰기 애플 ㅐㅍ-ㄹ 받침 표시 불완전한 자음인 "ㅍ" 뒤엔 "ㅡ"를 채워서

Slide 379

Slide 379 text

한글 모아쓰기 애플 ㅐㅍ-ㄹ 받침 표시 온전한 한글 글자로 합쳐주는 기능입니다.

Slide 380

Slide 380 text

Διόνυσος 디오니소스 διονισοσ Transcribe ㄷㅣㅗㄴㅣㅅㅗㅅ Rewrite P 한글라이즈 파이프라인의 Transcribe 단계에서 나온 자모의 나열을 최종결과로 만드는 데 쓰이죠.

Slide 381

Slide 381 text

suapapa/go_hangul 여기엔 이호민 님이 만드신 "go_hangul"을 사용했습니다.

Slide 382

Slide 382 text

• 한글 판별 •자모 분리 및 조립 • 한글 획 세기 import "github.com/suapapa/go_hangul" hangul.Join('ㅎ', 'ㅏ', 'ㄴ') == '한' hangul.Split('한') == 'ㅎ', 'ㅏ', 'ㄴ' hangul.IsJaeum('ㅋ') == true hangul.IsMoeum('ㅋ') == false 호민 님 감사합니다. 이 라이브러리엔 한글을 다루기 위한 유용한 기능이 많이 있어요.

Slide 383

Slide 383 text

• 한글 판별 •자모 분리 및 조립 • 한글 획 세기 import "github.com/suapapa/go_hangul" hangul.Join('ㅎ', 'ㅏ', 'ㄴ') == '한' hangul.Split('한') == 'ㅎ', 'ㅏ', 'ㄴ' hangul.IsJaeum('ㅋ') == true hangul.IsMoeum('ㅋ') == false 호민 님 감사합니다. 주어진 문자가 한글인지, 자음인지, 모음인지 판별해주는 함수와

Slide 384

Slide 384 text

• 한글 판별 •자모 분리 및 조립 • 한글 획 세기 import "github.com/suapapa/go_hangul" hangul.Join('ㅎ', 'ㅏ', 'ㄴ') == '한' hangul.Split('한') == 'ㅎ', 'ㅏ', 'ㄴ' hangul.IsJaeum('ㅋ') == true hangul.IsMoeum('ㅋ') == false 호민 님 감사합니다. 한글을 자모 단위로 쪼개거나 합치는 기능을 포함해 여러가지를 제공합니다.

Slide 385

Slide 385 text

• 한글 판별 •자모 분리 및 조립 • 한글 획 세기 import "github.com/suapapa/go_hangul" hangul.Join('ㅎ', 'ㅏ', 'ㄴ') == '한' hangul.Split('한') == 'ㅎ', 'ㅏ', 'ㄴ' hangul.IsJaeum('ㅋ') == true hangul.IsMoeum('ㅋ') == false 호민 님 감사합니다. 특이하게 한글의 획을 세는 기능까지도 있더라고요.

Slide 386

Slide 386 text

Rewrite Transcribe Phonemize 四川 쓰촨 si chuan si, chwan, ㅆㅡㅊㅘ-ㄴ

Slide 387

Slide 387 text

Rewrite Transcribe Phonemize 四川 쓰촨 si chuan si, chwan, ㅆㅡㅊㅘ-ㄴ 나머지 두 라이브러리는 Phonemize 단계에서 소리글자를 만드는 데에 쓰고 있습니다.

Slide 388

Slide 388 text

중국어 병음 Qīng dǎo 青岛 칭 다오 그 중 첫 번째는 중국어 병음입니다.

Slide 389

Slide 389 text

중국어 병음 Qīng dǎo 青岛 칭 다오 중국어 한자엔 대응되는 로마자 표기가 있는데 이를 "병음"이라고 불러요.

Slide 390

Slide 390 text

중국어 병음 Qīng dǎo 青岛 칭 다오 예를 들어 "青岛"의 병음은 "Qīng dǎo"로 표현되죠.

Slide 391

Slide 391 text

•중국 한자를 병음으로 변환 •단순 사전이라 빠르다. •의외로 용량도 안 크다. (800KB) import "github.com/mozillazg/go-pinyin" args := pinyin.NewArgs() pinyin.SinglePinyin('青', args) == "Qīng" "go-pinyin"이라는 라이브러리를 쓰면 손쉽게 병음을 구할 수 있습니다.

Slide 392

Slide 392 text

•중국 한자를 병음으로 변환 •단순 사전이라 빠르다. •의외로 용량도 안 크다. (800KB) import "github.com/mozillazg/go-pinyin" args := pinyin.NewArgs() pinyin.SinglePinyin('青', args) == "Qīng" 이 라이브러리는 단순한 사전이어서 속도도 빠르고

Slide 393

Slide 393 text

•중국 한자를 병음으로 변환 •단순 사전이라 빠르다. •의외로 용량도 안 크다. (800KB) import "github.com/mozillazg/go-pinyin" args := pinyin.NewArgs() pinyin.SinglePinyin('青', args) == "Qīng" 의외로 데이터도 별로 크지 않아서 800KB 밖에 되지 않습니다.

Slide 394

Slide 394 text

Hangulize("chi", "北京") Hangulize("chi", "章子怡") == "베이징" == "장쯔이" 이 라이브러리 덕분에 한글라이즈에 중국어를 새로 추가할 수 있게 됐어요.

Slide 395

Slide 395 text

Hangulize("chi", "李興燮") == "리싱셰" 이 흥 섭 중국어가 되니까 자기 한자 이름 넣어보는 재미도 나름 쏠쏠하더라고요.

Slide 396

Slide 396 text

陸カ審月名検ナレチカ可栄1経断ヒヲカツ宅意へざン丁可ホ 載省末応をじいく行昧7年てぼかせ答予シ告断ハヌカサ武元 争ちぞけみ。26丈なづ広靱増理ソヒタセ士定ワオトヘ整判 べっ集遺ワサヤイ聞出じどれな勝際ずンれ線芸せ年今ロエヒ 常政よのトッ上日やみぎね告創ゅど。作ケヨワ逮氏ッじルへ 地能どぜ祉83派あ織口ケ更探づを車下べひく毎旅まひづゅ意 幕づ務鋼けぶ要情ハリス択著乞伍トごへれ。 일본어 형태소 분석 일본어 로렘 입숨

Slide 397

Slide 397 text

陸カ審月名検ナレチカ可栄1経断ヒヲカツ宅意へざン丁可ホ 載省末応をじいく行昧7年てぼかせ答予シ告断ハヌカサ武元 争ちぞけみ。26丈なづ広靱増理ソヒタセ士定ワオトヘ整判 べっ集遺ワサヤイ聞出じどれな勝際ずンれ線芸せ年今ロエヒ 常政よのトッ上日やみぎね告創ゅど。作ケヨワ逮氏ッじルへ 地能どぜ祉83派あ織口ケ更探づを車下べひく毎旅まひづゅ意 幕づ務鋼けぶ要情ハリス択著乞伍トごへれ。 일본어 형태소 분석 일본어 로렘 입숨 다음은 일본어인데

Slide 398

Slide 398 text

陸カ審月名検ナレチカ可栄1経断ヒヲカツ宅意へざン丁可ホ 載省末応をじいく行昧7年てぼかせ答予シ告断ハヌカサ武元 争ちぞけみ。26丈なづ広靱増理ソヒタセ士定ワオトヘ整判 べっ集遺ワサヤイ聞出じどれな勝際ずンれ線芸せ年今ロエヒ 常政よのトッ上日やみぎね告創ゅど。作ケヨワ逮氏ッじルへ 地能どぜ祉83派あ織口ケ更探づを車下べひく毎旅まひづゅ意 幕づ務鋼けぶ要情ハリス択著乞伍トごへれ。 일본어 형태소 분석 일본어 로렘 입숨 일본어는 특히 처리하기 까다로웠던 것 같아요.

Slide 399

Slide 399 text

陸カ審月名検ナレチカ可栄1経断ヒヲカツ宅意へざン丁可ホ 載省末応をじいく行昧7年てぼかせ答予シ告断ハヌカサ武元 争ちぞけみ。26丈なづ広靱増理ソヒタセ士定ワオトヘ整判 べっ集遺ワサヤイ聞出じどれな勝際ずンれ線芸せ年今ロエヒ 常政よのトッ上日やみぎね告創ゅど。作ケヨワ逮氏ッじルへ 地能どぜ祉83派あ織口ケ更探づを車下べひく毎旅まひづゅ意 幕づ務鋼けぶ要情ハリス択著乞伍トごへれ。 일본어 형태소 분석 일본어 로렘 입숨 일본어에선 뜻글자인 한자와 소리글자인 가나를 섞어 씁니다.

Slide 400

Slide 400 text

陸カ審月名検ナレチカ可栄1経断ヒヲカツ宅意へざン丁可ホ 載省末応をじいく行昧7年てぼかせ答予シ告断ハヌカサ武元 争ちぞけみ。26丈なづ広靱増理ソヒタセ士定ワオトヘ整判 べっ集遺ワサヤイ聞出じどれな勝際ずンれ線芸せ年今ロエヒ 常政よのトッ上日やみぎね告創ゅど。作ケヨワ逮氏ッじルへ 地能どぜ祉83派あ織口ケ更探づを車下べひく毎旅まひづゅ意 幕づ務鋼けぶ要情ハリス択著乞伍トごへれ。 일본어 형태소 분석 일본어 로렘 입숨 그리고 띄어쓰기를 사용하지 않아요.

Slide 401

Slide 401 text

陸カ審月名検ナレチカ可栄1経断ヒヲカツ宅意へざン丁可ホ 載省末応をじいく行昧7年てぼかせ答予シ告断ハヌカサ武元 争ちぞけみ。26丈なづ広靱増理ソヒタセ士定ワオトヘ整判 べっ集遺ワサヤイ聞出じどれな勝際ずンれ線芸せ年今ロエヒ 常政よのトッ上日やみぎね告創ゅど。作ケヨワ逮氏ッじルへ 地能どぜ祉83派あ織口ケ更探づを車下べひく毎旅まひづゅ意 幕づ務鋼けぶ要情ハリス択著乞伍トごへれ。 일본어 형태소 분석 일본어 로렘 입숨 여기 붙여 둔 문단은 일본어 로렘 입숨인데 보시다시피 띄어쓰기가 없습니다.

Slide 402

Slide 402 text

陸カ審月名検ナレチカ可栄1経断ヒヲカツ宅意へざン丁可ホ 載省末応をじいく行昧7年てぼかせ答予シ告断ハヌカサ武元 争ちぞけみ。26丈なづ広靱増理ソヒタセ士定ワオトヘ整判 べっ集遺ワサヤイ聞出じどれな勝際ずンれ線芸せ年今ロエヒ 常政よのトッ上日やみぎね告創ゅど。作ケヨワ逮氏ッじルへ 地能どぜ祉83派あ織口ケ更探づを車下べひく毎旅まひづゅ意 幕づ務鋼けぶ要情ハリス択著乞伍トごへれ。 일본어 형태소 분석 일본어 로렘 입숨 전각문자 마침표와 띄어쓰기처럼 보이는 이것도 사실은 전각문자 1개죠.

Slide 403

Slide 403 text

일본어 형태소 분석: 띄어쓰기 宮本茂일본어 ▶ 미야모토 시게루 일본인 이름은 이렇게 한자 서너자로 이뤄진 경우가 많은데

Slide 404

Slide 404 text

일본어 형태소 분석: 띄어쓰기 宮本茂일본어 ▶ 미야모토 시게루 어디까지가 성이고 어디까지가 이름인지 구별해서

Slide 405

Slide 405 text

일본어 형태소 분석: 띄어쓰기 宮本茂일본어 ▶ 미야모토 시게루 전사 결과엔 띄어쓰기를 넣어줘야 합니다.

Slide 406

Slide 406 text

일본어 형태소 분석: 띄어쓰기 宮本茂일본어 ▶ 미야모토 시게루 형태소를 분석해보면 이름 경계를 알 수 있는데

Slide 407

Slide 407 text

일본어 형태소 분석: 띄어쓰기 宮本茂일본어 ▶ 미야모토 시게루 이게 일본어에 형태소 분석이 필요했던 첫 번째 이유죠.

Slide 408

Slide 408 text

일본어 형태소 분석: 후리가나 ニッポンダ ニホンゴ 日本だ 日本語 니 고 혼 닛 폰 다 또 다른 이유는 후리가나입니다.

Slide 409

Slide 409 text

일본어 형태소 분석: 후리가나 ニッポンダ ニホンゴ 日本だ 日本語 니 고 혼 닛 폰 다 일본어에서 한자의 읽는 법을 소리글자로 쓰는 걸 "후리가나"라고 하는데

Slide 410

Slide 410 text

일본어 형태소 분석: 후리가나 ニッポンダ ニホンゴ 日本だ 日本語 니 고 혼 닛 폰 다 같은 한자라도 문맥에 따라서 후리가나가 달라질 수 있습니다.

Slide 411

Slide 411 text

일본어 형태소 분석: 후리가나 ニッポンダ ニホンゴ 日本だ 日本語 니 고 혼 닛 폰 다 한자어인 "日本"의 경우 독립적으로 쓰일 땐 "닛폰"으로 읽히지만

Slide 412

Slide 412 text

일본어 형태소 분석: 후리가나 ニッポンダ ニホンゴ 日本だ 日本語 니 고 혼 닛 폰 다 다른 한자어의 일부로 쓰일 땐 "니혼"으로 읽히더라고요.

Slide 413

Slide 413 text

일본어 형태소 분석: 후리가나 ニッポンダ ニホンゴ 日本だ 日本語 니 고 혼 닛 폰 다 이런 걸 판단해서 한자로부터 후리가나를 추출해줄 도구가 필요했죠.

Slide 414

Slide 414 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 마지막으로 장모음 문제도 있었습니다.

Slide 415

Slide 415 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 우리말에선 사라진 장모음/단모음 구별이 일본어엔 있는데

Slide 416

Slide 416 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 외래어 표기법에선 장모음을 단모음처럼 취급하거든요.

Slide 417

Slide 417 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 그래서 첫 번째 예시인 "いいえ"(iie)의 경우 "いい"(ii)가 장음이라서

Slide 418

Slide 418 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 "이이에"가 아닌 "이에"로 옮깁니다.

Slide 419

Slide 419 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 하지만 똑같이 "いい"(ii)라고 써있더라도 장모음이 아니라

Slide 420

Slide 420 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 형태소의 경계로 나뉘어 있는 경우도 있어요.

Slide 421

Slide 421 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 두 번째 예시인 "かわいい"(kawaii)가 그런 경우인데

Slide 422

Slide 422 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 여기의 "いい"(ii)는 장모음이 아니고 각각 다른 형태소에 속한 두 개의 "い"(i)죠.

Slide 423

Slide 423 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 이때는 단모음처럼 합치면 안 되고 "이이"라고 구별해서 적어줘야 됩니다.

Slide 424

Slide 424 text

일본어 형태소 분석: 장모음 イーエ カワイ·イ いいえ かわいい 가 이 i i e i i wa ka 에 와 이 이 이처럼 일본어는 제대로 한글로 옮기려면 꽤 정밀한 형태소 분석을 필요로 하는데

Slide 425

Slide 425 text

•순수 Go •일본어 형태소 분석기 import "github.com/ikawaha/kagome.ipadic" 다행히 "kagome"라는 적합한 라이브러리가 있었습니다.

Slide 426

Slide 426 text

•순수 Go •일본어 형태소 분석기 import "github.com/ikawaha/kagome.ipadic" kagome는 Go만으로 구현된 일본어 형태소 분석기인데

Slide 427

Slide 427 text

•순수 Go •일본어 형태소 분석기 import "github.com/ikawaha/kagome.ipadic" 여기에 일본어 문장을 입력하면

Slide 428

Slide 428 text

•순수 Go •일본어 형태소 분석기 import "github.com/ikawaha/kagome.ipadic" 형태소의 품사, 원형, 읽는 법까지 꽤 자세한 정보를 구할 수 있어요.

Slide 429

Slide 429 text

•순수 Go •일본어 형태소 분석기 •무거워요 import "github.com/ikawaha/kagome.ipadic" 단, 다소 무거운 편입니다.

Slide 430

Slide 430 text

•순수 Go •일본어 형태소 분석기 •무거워요 import "github.com/ikawaha/kagome.ipadic" 초기화 속도도 느리고 분석 속도도 그리 빠르진 않더라고요.

Slide 431

Slide 431 text

Hangulize("jpn", "任天堂") Hangulize("jpn", "新海誠") Hangulize("jpn", "天空の城ラピュタ") == "닌텐도" == "신카이 마코토" == "덴쿠노시로라퓨타" 어쨌든 옛 한글라이즈의 일본어 규칙에선

Slide 432

Slide 432 text

Hangulize("jpn", "任天堂") Hangulize("jpn", "新海誠") Hangulize("jpn", "天空の城ラピュタ") == "닌텐도" == "신카이 마코토" == "덴쿠노시로라퓨타" 소리글자인 가나만 지원했고 장모음 구별도 못 했는데

Slide 433

Slide 433 text

Hangulize("jpn", "任天堂") Hangulize("jpn", "新海誠") Hangulize("jpn", "天空の城ラピュタ") == "닌텐도" == "신카이 마코토" == "덴쿠노시로라퓨타" kagome 덕분에 새 한글라이즈는 웬만한 일본어 문장까지도 지원할 수 있게 됐습니다.

Slide 434

Slide 434 text

•hangulize 8.1MB •go-pinyin 3.3MB •kagome.ipadic 13MB •합치면 20MB 빌드 용량

Slide 435

Slide 435 text

•hangulize 8.1MB •go-pinyin 3.3MB •kagome.ipadic 13MB •합치면 20MB 빌드 용량 그런데 go-pinyin이랑 kagome까지 한글라이즈 패키지에 포함하려고 보니

Slide 436

Slide 436 text

•hangulize 8.1MB •go-pinyin 3.3MB •kagome.ipadic 13MB •합치면 20MB 빌드 용량 빌드 용량이 너무 커지더라고요.

Slide 437

Slide 437 text

•hangulize 8.1MB •go-pinyin 3.3MB •kagome.ipadic 13MB •합치면 20MB 빌드 용량 특히 JavaScript 빌드도 같이 뽑고 있었는데 20MB면 JS 파일 하나치곤 너무 커서

Slide 438

Slide 438 text

import "github.com/hangulize/hangulize" import "github.com/hangulize/hangulize/phonemize/furigana" func main() { hangulize.UsePhonemizer(&furigana.P) fmt.Println(hangulize.Hangulize("jpn", "秋葉原")) // Output: 아키하바라 } 플러그인 이렇게 플러그인처럼 쓸 수 있도록 분리했어요.

Slide 439

Slide 439 text

import "github.com/hangulize/hangulize" import "github.com/hangulize/hangulize/phonemize/furigana" func main() { hangulize.UsePhonemizer(&furigana.P) fmt.Println(hangulize.Hangulize("jpn", "秋葉原")) // Output: 아키하바라 } 플러그인 여러분이 Go 코드에서 한글라이즈 라이브러리를 쓰실 경우엔

Slide 440

Slide 440 text

import "github.com/hangulize/hangulize" import "github.com/hangulize/hangulize/phonemize/furigana" func main() { hangulize.UsePhonemizer(&furigana.P) fmt.Println(hangulize.Hangulize("jpn", "秋葉原")) // Output: 아키하바라 } 플러그인 직접 UsePhonemizer를 호출해야만 중국어와 일본어도 제대로 다룰 수 있습니다.

Slide 441

Slide 441 text

c. 테스트와 문서화

Slide 442

Slide 442 text

c. 테스트와 문서화 다음으로 Go의 테스트 및 문서화 도구에서 인상적이었던 부분을 말씀드릴게요.

Slide 443

Slide 443 text

assert Portuguese({ 'bossa nova': '보사 노바', 'moor': '모르', 'maracas': '마라카스', }) 용례집 유닛테스트 국립국어원 사이트에선 이렇게 외래어 표기법 용례집을 구할 수 있는데

Slide 444

Slide 444 text

assert Portuguese({ 'bossa nova': '보사 노바', 'moor': '모르', 'maracas': '마라카스', }) 용례집 유닛테스트 옛 한글라이즈 때부터 이 용례집을 유닛테스트로 만들어 써왔어요.

Slide 445

Slide 445 text

assert Portuguese({ 'bossa nova': '보사 노바', 'moor': '모르', 'maracas': '마라카스', }) 용례집 유닛테스트 이것으로 전사 규칙을 제대로 만들었는지 쉽게 검증할 수 있었죠.

Slide 446

Slide 446 text

기존 용례집 테스트 승계 5. 20. 재제작 시작 5. 27. 첫 릴리즈 5. 28. 기존 언어 모두 지원 8. 27. 발표 새 한글라이즈를 만들면서도 기존 용례집 테스트는 그대로 승계했습니다.

Slide 447

Slide 447 text

기존 용례집 테스트 승계 5. 20. 재제작 시작 5. 27. 첫 릴리즈 5. 28. 기존 언어 모두 지원 8. 27. 발표 처음부터 테스트가 충분했던 덕분에

Slide 448

Slide 448 text

기존 용례집 테스트 승계 5. 20. 재제작 시작 5. 27. 첫 릴리즈 5. 28. 기존 언어 모두 지원 8. 27. 발표 8일 첫 8일만에 기존 38가지 언어를 모두 지원하는 것도 가능했죠.

Slide 449

Slide 449 text

기존 용례집 테스트 승계 5. 20. 재제작 시작 5. 27. 첫 릴리즈 5. 28. 기존 언어 모두 지원 8. 27. 발표 8일 그만큼 한글라이즈에서 테스트는 굉장히 중요한 축을 맡고 있습니다.

Slide 450

Slide 450 text

import "testing"

Slide 451

Slide 451 text

import "testing" "testing"은 Go의 표준 테스트 도구인데 기본 도구임에도 불구하고

Slide 452

Slide 452 text

import "testing" 상당히 강력한 테스트 프레임워크를 쓰는 기분이었습니다.

Slide 453

Slide 453 text

// $ go test -run TestLang/ita func TestLang(t *testing.T) { t.Run("jpn", testJpn) t.Run("chi", testChi) t.Run("ita", testIta) } 서브테스트 testing에서 인상적인 점 중 하나는 바로 서브테스트 기능이었어요.

Slide 454

Slide 454 text

// $ go test -run TestLang/ita func TestLang(t *testing.T) { t.Run("jpn", testJpn) t.Run("chi", testChi) t.Run("ita", testIta) } 서브테스트 서브테스트는 한 테스트케이스에서 여러 테스트케이스를 파생시키는 기능인데

Slide 455

Slide 455 text

// $ go test -run TestLang/ita func TestLang(t *testing.T) { t.Run("jpn", testJpn) t.Run("chi", testChi) t.Run("ita", testIta) } 서브테스트 본격적인 서드파티 테스트 프레임워크에서나 지원할 법한 걸

Slide 456

Slide 456 text

// $ go test -run TestLang/ita func TestLang(t *testing.T) { t.Run("jpn", testJpn) t.Run("chi", testChi) t.Run("ita", testIta) } 서브테스트 기본 도구가 지원한다는 점이 놀라웠죠.

Slide 457

Slide 457 text

// $ go test -run TestLang/ita func TestLang(t *testing.T) { t.Run("jpn", testJpn) t.Run("chi", testChi) t.Run("ita", testIta) } 서브테스트 한글라이즈에선 각 언어 별 용례집을 검증하는 테스트를

Slide 458

Slide 458 text

// $ go test -run TestLang/ita func TestLang(t *testing.T) { t.Run("jpn", testJpn) t.Run("chi", testChi) t.Run("ita", testIta) } 서브테스트 이런 식으로 서브테스트를 이용해 만들었습니다.

Slide 459

Slide 459 text

// $ go test -bench . // BenchmarkF 100 1078834 ns/op func BenchmarkF(b *testing.B) { for i := 0; i < b.N; i++ { f() } } 벤치마크

Slide 460

Slide 460 text

// $ go test -bench . // BenchmarkF 100 1078834 ns/op func BenchmarkF(b *testing.B) { for i := 0; i < b.N; i++ { f() } } 벤치마크 또 벤치마크 기능까지 제공하는 점도 신선했는데

Slide 461

Slide 461 text

// $ go test -bench . // BenchmarkF 100 1078834 ns/op func BenchmarkF(b *testing.B) { for i := 0; i < b.N; i++ { f() } } 벤치마크 "Benchmark"로 시작하는 함수에서 testing.B를 인자로 받아

Slide 462

Slide 462 text

// $ go test -bench . // BenchmarkF 100 1078834 ns/op func BenchmarkF(b *testing.B) { for i := 0; i < b.N; i++ { f() } } 벤치마크 b.N바퀴 도는 반복문 코드를 작성하는 식으로 만들더라고요.

Slide 463

Slide 463 text

// $ go test -bench . // BenchmarkF 100 1078834 ns/op func BenchmarkF(b *testing.B) { for i := 0; i < b.N; i++ { f() } } 벤치마크 테스트 실행할 때 "-bench" 옵션을 지정하면

Slide 464

Slide 464 text

// $ go test -bench . // BenchmarkF 100 1078834 ns/op func BenchmarkF(b *testing.B) { for i := 0; i < b.N; i++ { f() } } 벤치마크 벤치마크를 돌려본 후 루프 한 바퀴에 얼마나 걸렸는지 알려줍니다.

Slide 465

Slide 465 text

benchmark( setup='prepare()', run='do_it()', ) 흔히 보던 벤치마크 제가 흔히 보던 벤치마크 도구에선 보통

Slide 466

Slide 466 text

benchmark( setup='prepare()', run='do_it()', ) 흔히 보던 벤치마크 벤치마크를 준비하는 코드 "setup"과 벤치마크할 코드 "run"을

Slide 467

Slide 467 text

benchmark( setup='prepare()', run='do_it()', ) 흔히 보던 벤치마크 따로 입력하는 인터페이스가 있었는데

Slide 468

Slide 468 text

func BenchmarkDoIt(b *testing.B) { Prepare() b.ResetTimer() for i := 0; i < b.N; i++ { DoIt() } } Go 벤치마크 복잡한 추상화 없이 testing.B 인자만으로

Slide 469

Slide 469 text

func BenchmarkDoIt(b *testing.B) { Prepare() b.ResetTimer() for i := 0; i < b.N; i++ { DoIt() } } Go 벤치마크 훨씬 간결하게 같은 기능을 구현한다는 점에서 상당히 감탄했습니다.

Slide 470

Slide 470 text

func BenchmarkF(b *testing.B) { b.Run("1", genBenchmarkF(1)) b.Run("10", genBenchmarkF(10)) b.Run("100", genBenchmarkF(100)) b.Run("1000", genBenchmarkF(1000)) } 서브벤치마크 BenchmarkF/1 BenchmarkF/1000 시간

Slide 471

Slide 471 text

func BenchmarkF(b *testing.B) { b.Run("1", genBenchmarkF(1)) b.Run("10", genBenchmarkF(10)) b.Run("100", genBenchmarkF(100)) b.Run("1000", genBenchmarkF(1000)) } 서브벤치마크 BenchmarkF/1 BenchmarkF/1000 시간 벤치마크에서도 서브테스트와 같은 방식으로 서브벤치마크를 만들 수 있는데

Slide 472

Slide 472 text

func BenchmarkF(b *testing.B) { b.Run("1", genBenchmarkF(1)) b.Run("10", genBenchmarkF(10)) b.Run("100", genBenchmarkF(100)) b.Run("1000", genBenchmarkF(1000)) } 서브벤치마크 BenchmarkF/1 BenchmarkF/1000 시간 덕분에 알고리즘의 시간복잡도에 더 집중할 수 있었고

Slide 473

Slide 473 text

func BenchmarkF(b *testing.B) { b.Run("1", genBenchmarkF(1)) b.Run("10", genBenchmarkF(10)) b.Run("100", genBenchmarkF(100)) b.Run("1000", genBenchmarkF(1000)) } 서브벤치마크 BenchmarkF/1 BenchmarkF/1000 시간 개선하는 과정이 눈에 바로바로 들어와서 성취감도 높았습니다.

Slide 474

Slide 474 text

func TestF(t *testing.T) { if f() != 42 { t.Fail("f() does not return 42") } }

Slide 475

Slide 475 text

func TestF(t *testing.T) { if f() != 42 { t.Fail("f() does not return 42") } } 한 가지 아쉬웠던 건 Go에 assert 문법이 없어서

Slide 476

Slide 476 text

func TestF(t *testing.T) { if f() != 42 { t.Fail("f() does not return 42") } } 테스트케이스를 두꺼운 if문 덩어리로 만들어야 한다는 점이었는데

Slide 477

Slide 477 text

import "github.com/stretchr/testify/assert" func TestF(t *testing.T) { assert.Equal(t, 42, f()) assert.NotEqual(t, 21, f()) } 전 테스트케이스를 좀 더 편하게 쓰기 위해 서드파티 라이브러리인 "testify"를 쓰고 있습니다.

Slide 478

Slide 478 text

import "github.com/stretchr/testify/assert" func TestF(t *testing.T) { assert.Equal(t, 42, f()) assert.NotEqual(t, 21, f()) } testify의 "assert" 패키지가 제공하는 "Equal", "NotEqual" 같은 메소드를 이용하면

Slide 479

Slide 479 text

import "github.com/stretchr/testify/assert" func TestF(t *testing.T) { assert.Equal(t, 42, f()) assert.NotEqual(t, 21, f()) } 테스트 코드 작성도 훨씬 간편하고 테스트 실패 보고서도 읽기 더 좋더라고요.

Slide 480

Slide 480 text

import "github.com/stretchr/testify/assert" func TestF(t *testing.T) { assert.Equal(t, 42, f()) assert.NotEqual(t, 21, f()) } 워낙 유용하고 유명해서 아마 여러분 대부분도 이미 쓰고 계실 것 같습니다.

Slide 481

Slide 481 text

https://godoc.org/github.com/hangulize/hangulize

Slide 482

Slide 482 text

https://godoc.org/github.com/hangulize/hangulize 한편 패키지를 문서화하면서는 GoDoc의 초간단 문법이 인상적이었어요.

Slide 483

Slide 483 text

• **이런거**, _이런거_, `이런거` 없음 • 불릿 목록도 없음 • 그림도 없음 초라한 문법 그동안 마크다운에 익숙해져 있었고 마크다운도 충분히 간단하다고 생각했는데

Slide 484

Slide 484 text

• **이런거**, _이런거_, `이런거` 없음 • 불릿 목록도 없음 • 그림도 없음 초라한 문법 GoDoc의 문법은 훨씬 단순하더라고요.

Slide 485

Slide 485 text

• **이런거**, _이런거_, `이런거` 없음 • 불릿 목록도 없음 • 그림도 없음 초라한 문법 **볼드**, _이탤릭_, `코드`도 없고 불릿 목록도 없고 그림도 없었습니다.

Slide 486

Slide 486 text

• URL엔 하이퍼링크 • 들여쓰면 코드블록 • 대문자로 시작하고 마침표가 없는 줄은 제목 초간단 문법 그렇다고 문서화하는 데에 부족한 건 아니었어요.

Slide 487

Slide 487 text

• URL엔 하이퍼링크 • 들여쓰면 코드블록 • 대문자로 시작하고 마침표가 없는 줄은 제목 초간단 문법 URL엔 자동으로 하이퍼링크가 붙고 한 칸이라도 들여쓰기하면 코드블록으로 인식됩니다.

Slide 488

Slide 488 text

• URL엔 하이퍼링크 • 들여쓰면 코드블록 • 대문자로 시작하고 마침표가 없는 줄은 제목 초간단 문법 마크다운처럼 "#" 같은 걸 붙이지 않고도

Slide 489

Slide 489 text

• URL엔 하이퍼링크 • 들여쓰면 코드블록 • 대문자로 시작하고 마침표가 없는 줄은 제목 초간단 문법 대문자로 시작하고 마침표가 없는 줄은 제목으로 취급되죠.

Slide 490

Slide 490 text

$ go doc github.com/hangulize/hangulize PACKAGE DOCUMENTATION package hangulize import "github.com/hangulize/hangulize" Package hangulize transcribes non-Korean words into Hangul. "Hello!" -> "헬로!" Hangulize was inspired by Brian Jongseong Park (http://iceager.egloos.com/2610028). Based on this idea, the original 커맨드라인 문법이 이렇게 단순한 건 GoDoc이 웹 사이트 뿐만 아니라

Slide 491

Slide 491 text

$ go doc github.com/hangulize/hangulize PACKAGE DOCUMENTATION package hangulize import "github.com/hangulize/hangulize" Package hangulize transcribes non-Korean words into Hangul. "Hello!" -> "헬로!" Hangulize was inspired by Brian Jongseong Park (http://iceager.egloos.com/2610028). Based on this idea, the original 커맨드라인 커맨드라인 출력도 중요하게 다루기 때문이라고 합니다.

Slide 492

Slide 492 text

•.md, .rst에 비해 초라하지만 •외울 게 적어서 •서식을 헷갈리지 않아요. 쉬운 문법 아무튼 마크다운이나 reStructuredText에 비하면 상당히 초라한 문법이지만

Slide 493

Slide 493 text

•.md, .rst에 비해 초라하지만 •외울 게 적어서 •서식을 헷갈리지 않아요. 쉬운 문법 그만큼 외울 게 적어서 금방 익숙해질 수 있었고

Slide 494

Slide 494 text

•.md, .rst에 비해 초라하지만 •외울 게 적어서 •서식을 헷갈리지 않아요. 쉬운 문법 작성하면서 서식을 헷갈리는 일이 거의 없었던 것 같습니다.

Slide 495

Slide 495 text

$ godoc \ -http=:8080 \ -goroot="$GOPATH" 로컬 godoc localhost:8080/pkg/github.com/hangulize/hangulize 처음 쓸 때 조금 헷갈리더라도 로컬 GoDoc 서버를 이용해

Slide 496

Slide 496 text

$ godoc \ -http=:8080 \ -goroot="$GOPATH" 로컬 godoc localhost:8080/pkg/github.com/hangulize/hangulize 실시간으로 바로바로 확인하면서 쓰다 보니 금새 익힐 수 있었습니다.

Slide 497

Slide 497 text

func ExampleComposeHangul_perfect() 예제 코드 대상 이름 소제목 예제 코드로 인식되게 함

Slide 498

Slide 498 text

func ExampleComposeHangul_perfect() 예제 코드 대상 이름 소제목 예제 코드로 인식되게 함 또한 문서에 포함되는 예제 코드를 테스트 코드의 일종으로 다루는 것도 인상적이었는데

Slide 499

Slide 499 text

func ExampleComposeHangul_perfect() 예제 코드 대상 이름 소제목 예제 코드로 인식되게 함 정해진 형식에 맞춰 테스트 함수의 이름을 지정하면

Slide 500

Slide 500 text

문서 상에 딱 그 대상 밑에

Slide 501

Slide 501 text

함수 내용이 예제 코드로써 배치되는 방식이었어요.

Slide 502

Slide 502 text

$ go test --- FAIL: ExampleComposeHangul_perfect (0.00s) got: 하느글라이스 want: 한글라이즈 FAIL exit status 1 FAIL github.com/hangulize/hangulize 1.949s 예제 코드 방부처리 예제 코드가 테스트 코드의 일종이다 보니 혹시 나중에 그 내용이 틀리게 되더라도

Slide 503

Slide 503 text

$ go test --- FAIL: ExampleComposeHangul_perfect (0.00s) got: 하느글라이스 want: 한글라이즈 FAIL exit status 1 FAIL github.com/hangulize/hangulize 1.949s 예제 코드 방부처리 테스트가 바로 실패해서 언제나 올바른 상태를 유지할 수 있도록 도와주더라고요.

Slide 504

Slide 504 text

3. 이룬 것

Slide 505

Slide 505 text

3. 이룬 것 지금까지 한글라이즈를 Go로 다시 만들면서 인상적이었던 부분을 소개해드렸는데

Slide 506

Slide 506 text

3. 이룬 것 마지막으로 이번 재제작 과정을 통해서 이룬 점들을 살펴보고 이 발표를 마치겠습니다.

Slide 507

Slide 507 text

1. 성능 개선 이룬 것 첫 번째는 성능 개선이에요.

Slide 508

Slide 508 text

1. 성능 개선 이룬 것 Go가 파이썬보다 훨씬 빠르기는 하지만 이번엔 알고리즘에도 꽤 신경쓰면서 작업했거든요.

Slide 509

Slide 509 text

Cappuccino이탈리아어 ▶ 카푸치노 •옛 한글라이즈 398㎲ •새 한글라이즈 85㎲ "카푸치노"같이 짧은 단어로 비교해보면 옛 한글라이즈에선 398㎲가 걸렸지만

Slide 510

Slide 510 text

Cappuccino이탈리아어 ▶ 카푸치노 •옛 한글라이즈 398㎲ •새 한글라이즈 85㎲ 새 한글라이즈에선 85㎲밖에 걸리지 않았습니다.

Slide 511

Slide 511 text

Cappuccino이탈리아어 ▶ 카푸치노 •옛 한글라이즈 398㎲ •새 한글라이즈 85㎲ 네다섯 배는 빨라진 거죠.

Slide 512

Slide 512 text

단어 길이 옛 한글라이즈 새 한글라이즈 8만 자 630㎳ 465㎳ 80만 자 10초 5초 800만 자 14분 50초 시간 옛 한글라이즈 새 한글라이즈 단어 길이 단어가 길면 길 수록 새 한글라이즈가 옛 한글라이즈보다 더욱 빠른데

Slide 513

Slide 513 text

단어 길이 옛 한글라이즈 새 한글라이즈 8만 자 630㎳ 465㎳ 80만 자 10초 5초 800만 자 14분 50초 시간 옛 한글라이즈 새 한글라이즈 단어 길이 800만 자짜리 단어에서 새 한글라이즈에선 50초 정도밖에 걸리지 않았지만

Slide 514

Slide 514 text

단어 길이 옛 한글라이즈 새 한글라이즈 8만 자 630㎳ 465㎳ 80만 자 10초 5초 800만 자 14분 50초 시간 옛 한글라이즈 새 한글라이즈 단어 길이 옛 한글라이즈에선 14분이나 걸리더라고요.

Slide 515

Slide 515 text

O(n²) O(n) 옛 한글라이즈 새 한글라이즈 옛 한글라이즈엔 일부 비효율적인 코드가 있어서 시간복잡도가 제곱 시간이었는데

Slide 516

Slide 516 text

O(n²) O(n) 옛 한글라이즈 새 한글라이즈 그에 반해 새 한글라이즈는 선형시간을 보장하기 때문입니다.

Slide 517

Slide 517 text

2. Phonemize 도입 이룬 것

Slide 518

Slide 518 text

2. Phonemize 도입 이룬 것 두 번째는 이번에 새로 추가한 Phonemize 단계예요.

Slide 519

Slide 519 text

Rewrite Transcribe Phonemize 재제작 과정에서 새로 도입 四川 쓰촨 si chuan si, chwan, ㅆㅡㅊㅘ-ㄴ Phonemize 단계가 옛 한글라이즈엔 없었거든요.

Slide 520

Slide 520 text

Rewrite Transcribe Phonemize 재제작 과정에서 새로 도입 四川 쓰촨 si chuan si, chwan, ㅆㅡㅊㅘ-ㄴ 앞에서 살펴봤듯이 이 단계가 추가된 덕분에

Slide 521

Slide 521 text

Rewrite Transcribe Phonemize 재제작 과정에서 새로 도입 四川 쓰촨 si chuan si, chwan, ㅆㅡㅊㅘ-ㄴ 중국어도 새로 지원할 수 있었고 일본어도 더 제대로 지원할 수 있게 됐죠.

Slide 522

Slide 522 text

Ghoti fish Phonemize 어쩌면 영어도? 어쩌면 Phonemize 단계를 이용해서 언젠간 영어도 지원할 수 있지 않을까 싶습니다.

Slide 523

Slide 523 text

3. 생산성 개선 이룬 것

Slide 524

Slide 524 text

3. 생산성 개선 이룬 것 그리고 전사 규칙 만들 때의 생산성도 상당히 좋아진 것 같아요.

Slide 525

Slide 525 text

• 중국어 전혀 모르는데 • 중국어 외래어 표기법 만드는 데 이틀 전사 규칙 제작 생산성 저는 중국어를 전혀 모르는데 중국어 외래어 표기법 자료만 보고

Slide 526

Slide 526 text

• 중국어 전혀 모르는데 • 중국어 외래어 표기법 만드는 데 이틀 전사 규칙 제작 생산성 규칙을 만드는 데엔 이틀 밖에 걸리지 않았습니다.

Slide 527

Slide 527 text

test: "郭廣昌" -> "궈광창" "劉鶴" -> "류허" "屠呦呦" -> "투유유" "許家印" -> "쉬자인" "王健林" -> "왕젠린" "廬志强" -> "루즈창" "馬化騰" -> "마화텅" "努爾白克力" -> "누얼바이커리" "金立群" -> "진리췬" "曹國偉" -> "차오궈웨이" "李河君" -> "리허쥔" "游客" -> "유커" "雷軍" -> "레이쥔" "李保樟" -> "리바오장" "古天樂" -> "구톈러" "鄧森悅" -> "덩썬웨" 이렇게 용례집에서 단어를 긁어서 테스트케이스에 대량으로 집어넣고

Slide 528

Slide 528 text

rewrite: "v" -> "yu" "{c|ch|r|s|sh|z|zh}i" -> "i," "{}ue" -> "yue" "{}uan" -> "yuan" "{}un" -> "yun" transcribe: # 단운 "yu" -> "ㅟ" # 제치류 "{}yang" -> "ㅏ-ㅇ" "{}yan" -> "ㅔ-ㄴ" "{}you" -> "ㅜ" "{}yai" -> "ㅏㅣ" "{}yao" -> "ㅏㅗ" "{}ya" -> "ㅏ" "{}yo" -> "ㅗ" "{}ye" -> "ㅔ" 오른쪽과 같은 외래어 표기법 표를 참고해서

Slide 529

Slide 529 text

rewrite: "v" -> "yu" "{c|ch|r|s|sh|z|zh}i" -> "i," "{}ue" -> "yue" "{}uan" -> "yuan" "{}un" -> "yun" transcribe: # 단운 "yu" -> "ㅟ" # 제치류 "{}yang" -> "ㅏ-ㅇ" "{}yan" -> "ㅔ-ㄴ" "{}you" -> "ㅜ" "{}yai" -> "ㅏㅣ" "{}yao" -> "ㅏㅗ" "{}ya" -> "ㅏ" "{}yo" -> "ㅗ" "{}ye" -> "ㅔ" 패턴 찾아 바꾸기 규칙만 몇 개 짜다 보니 금방 완성할 수 있었죠.

Slide 530

Slide 530 text

4. Go 학습 이룬 것

Slide 531

Slide 531 text

4. Go 학습 이룬 것 마지막으로 이번 한글라이즈 재제작을 통해서 이룬 가장 큰 성과는

Slide 532

Slide 532 text

4. Go 학습 이룬 것 Go를 많이 익힐 수 있었다는 것입니다.

Slide 533

Slide 533 text

•고루틴은 끝내주는데 •그런데 너무 기능이 적다. •고퍼도 귀엽지 않고 Go 첫인상 Go에 대한 제 첫인상은 이랬죠.

Slide 534

Slide 534 text

•고루틴은 끝내주는데 •그런데 너무 기능이 적다. •고퍼도 귀엽지 않고 Go 첫인상 고루틴은 끝내주지만 언어의 기능이 너무 빈약해 보였습니다.

Slide 535

Slide 535 text

•고루틴은 끝내주는데 •그런데 너무 기능이 적다. •고퍼도 귀엽지 않고 Go 첫인상 고퍼도 안 귀엽고요.

Slide 536

Slide 536 text

• 세밀하게 절제된 최소주의 •실수하지 않도록 도와주는 환경 Go 지금 인상 하지만 지금은, 빈약해 보였던 언어가

Slide 537

Slide 537 text

• 세밀하게 절제된 최소주의 •실수하지 않도록 도와주는 환경 Go 지금 인상 사실은 세밀하게 절제된 최소주의를 따르는 것이었고

Slide 538

Slide 538 text

• 세밀하게 절제된 최소주의 •실수하지 않도록 도와주는 환경 Go 지금 인상 언어의 복잡성을 극도로 낮춰서

Slide 539

Slide 539 text

• 세밀하게 절제된 최소주의 •실수하지 않도록 도와주는 환경 Go 지금 인상 대규모 프로젝트에서도 실수하기 어렵고

Slide 540

Slide 540 text

• 세밀하게 절제된 최소주의 •실수하지 않도록 도와주는 환경 Go 지금 인상 조금만 신경 써도 좋은 코드를 작성할 수 있게 해준다는 걸 깨닫게 됐습니다.

Slide 541

Slide 541 text

• 세밀하게 절제된 최소주의 •실수하지 않도록 도와주는 환경 • 고퍼는 여전히 귀엽지 않다. Go 지금 인상 그래도 고퍼는 여전히 귀여워 보이지 않지만요.

Slide 542

Slide 542 text

•패키징 •테스팅 •문서화 •정규표현식 •파서 • 플러그인 • 성능 최적화 Go에 자신감 이번 경험으로 Go의 여러가지 영역에 입문했고

Slide 543

Slide 543 text

•패키징 •테스팅 •문서화 •정규표현식 •파서 • 플러그인 • 성능 최적화 Go에 자신감 덕분에 Go 코딩에 자신감도 많이 붙었어요.

Slide 544

Slide 544 text

- [한글라이즈 재제작기] 이흥섭(넥슨 왓 스튜디오) 〈한글라이즈〉는 외국어 단어를 외래어 표기법에 따라 한글로 옮겨 적어주는 도구입니다. "Espresso"를 "에스프레소"로, "東京 "을 "도쿄"로 변환할 수 있죠. 본래 Python으로 구현했던 한글라 이즈를 Go로 재구현하면서 겪은 경험과 느낀점을 공유합니다. Go에 근자감 어떻게 보면 근자감일 수도 있는데 결국 이 발표까지 하게 됐습니다.

Slide 545

Slide 545 text

- [한글라이즈 재제작기] 이흥섭(넥슨 왓 스튜디오) 〈한글라이즈〉는 외국어 단어를 외래어 표기법에 따라 한글로 옮겨 적어주는 도구입니다. "Espresso"를 "에스프레소"로, "東京 "을 "도쿄"로 변환할 수 있죠. 본래 Python으로 구현했던 한글라 이즈를 Go로 재구현하면서 겪은 경험과 느낀점을 공유합니다. Go에 근자감 이번 발표를 준비하면서

Slide 546

Slide 546 text

- [한글라이즈 재제작기] 이흥섭(넥슨 왓 스튜디오) 〈한글라이즈〉는 외국어 단어를 외래어 표기법에 따라 한글로 옮겨 적어주는 도구입니다. "Espresso"를 "에스프레소"로, "東京 "을 "도쿄"로 변환할 수 있죠. 본래 Python으로 구현했던 한글라 이즈를 Go로 재구현하면서 겪은 경험과 느낀점을 공유합니다. Go에 근자감 명확하게 정리하지 않고 넘어갔던 부분도 명확하게 이해할 수 있었고

Slide 547

Slide 547 text

- [한글라이즈 재제작기] 이흥섭(넥슨 왓 스튜디오) 〈한글라이즈〉는 외국어 단어를 외래어 표기법에 따라 한글로 옮겨 적어주는 도구입니다. "Espresso"를 "에스프레소"로, "東京 "을 "도쿄"로 변환할 수 있죠. 본래 Python으로 구현했던 한글라 이즈를 Go로 재구현하면서 겪은 경험과 느낀점을 공유합니다. Go에 근자감 한글라이즈를 더 많이 발전시킬 수 있는 기회가 되기도 했습니다.

Slide 548

Slide 548 text

- [한글라이즈 재제작기] 이흥섭(넥슨 왓 스튜디오) 〈한글라이즈〉는 외국어 단어를 외래어 표기법에 따라 한글로 옮겨 적어주는 도구입니다. "Espresso"를 "에스프레소"로, "東京 "을 "도쿄"로 변환할 수 있죠. 본래 Python으로 구현했던 한글라 이즈를 Go로 재구현하면서 겪은 경험과 느낀점을 공유합니다. Go에 근자감 발표 준비하는 동안 한글라이즈 코딩도 평소보다 더 많이 했던 것 같아요.

Slide 549

Slide 549 text

I GO 요즘은 매일 일과후에 Go로 코딩하는 것을 취미로 삼고 있는데

Slide 550

Slide 550 text

I GO Go는 놀이처럼 느껴질 정도로 코딩하기 즐거운 언어였습니다.

Slide 551

Slide 551 text

I GO 이렇게 Go 프로그래머 분들을 많이 만날 수 있는 기회가 생겨서 설레고

Slide 552

Slide 552 text

I GO 여러분과 교류하며 더 많이 배우고 싶습니다.

Slide 553

Slide 553 text

I GO 좀 더 이야기 나누고 싶은 분은 [email protected]로 이메일 보내주세요.

Slide 554

Slide 554 text

감사합니다! 이 제작물은 아모레퍼시픽의 아리따 돋움, 그리고 서울남산체, 조선일보명조, 스포카한산스, Ubuntu Mono를 사용하여 디자인 되었습니다. 제가 준비한 발표는 여기까지입니다.

Slide 555

Slide 555 text

감사합니다! 이 제작물은 아모레퍼시픽의 아리따 돋움, 그리고 서울남산체, 조선일보명조, 스포카한산스, Ubuntu Mono를 사용하여 디자인 되었습니다. 끝까지 읽어주셔서 감사합니다.

Slide 556

Slide 556 text

김영호, 김찬웅, 김향아, 박종성 만든이 도와주신 분 이흥섭